From e64d96bd0d14c9566dee01a23c669fccae2aca43 Mon Sep 17 00:00:00 2001 From: ahmed Date: Sun, 24 Aug 2025 14:51:18 +0300 Subject: [PATCH] Put --- Esiur.Stores.EntityCore/EsiurProxyRewrite.cs | 2 +- Esiur/Net/IIP/DistributedConnection.cs | 2 +- Esiur/Net/Packets/IIPPacket.cs | 20 ++- Esiur/Resource/Warehouse.cs | 140 +++++++++++++------ Esiur/Stores/MemoryStore.cs | 14 +- 5 files changed, 113 insertions(+), 65 deletions(-) diff --git a/Esiur.Stores.EntityCore/EsiurProxyRewrite.cs b/Esiur.Stores.EntityCore/EsiurProxyRewrite.cs index 568fc6f..ca72c26 100644 --- a/Esiur.Stores.EntityCore/EsiurProxyRewrite.cs +++ b/Esiur.Stores.EntityCore/EsiurProxyRewrite.cs @@ -69,7 +69,7 @@ public class EsiurProxyRewrite : IModelFinalizingConvention if (Codec.ImplementsInterface(entityType.ClrType, typeof(IResource))) { // check if the object exists - var obj = options.Warehouse.CreateInstance(entityType.ClrType) as IResource; + var obj = options.Warehouse.Create(entityType.ClrType) as IResource; options.Store.TypesByType[entityType.ClrType].PrimaryKey.SetValue(obj, id); options.Warehouse.Put(id.ToString(), obj, options.Store, null, 0, manager).Wait(); return obj; diff --git a/Esiur/Net/IIP/DistributedConnection.cs b/Esiur/Net/IIP/DistributedConnection.cs index 0c50ada..aa94dad 100644 --- a/Esiur/Net/IIP/DistributedConnection.cs +++ b/Esiur/Net/IIP/DistributedConnection.cs @@ -430,7 +430,7 @@ public partial class DistributedConnection : NetworkConnection, IStore if (packet.DataType == null) return offset; - + Console.WriteLine("Incoming: " + packet); if (packet.Method == IIPPacketMethod.Notification) { var dt = packet.DataType.Value; diff --git a/Esiur/Net/Packets/IIPPacket.cs b/Esiur/Net/Packets/IIPPacket.cs index 4959a93..90df85c 100644 --- a/Esiur/Net/Packets/IIPPacket.cs +++ b/Esiur/Net/Packets/IIPPacket.cs @@ -55,6 +55,18 @@ class IIPPacket : Packet return base.Compose(); } + public override string ToString() + { + return Method switch + { + IIPPacketMethod.Notification => $"{Method} {Notification}", + IIPPacketMethod.Request => $"{Method} {Request}", + IIPPacketMethod.Reply => $"{Method} {Reply}", + IIPPacketMethod.Extension => $"{Method} {Extension}", + _ => $"{Method}" + }; + } + bool NotEnough(uint offset, uint ends, uint needed) { if (offset + needed > ends) @@ -80,11 +92,11 @@ class IIPPacket : Packet if (Method == IIPPacketMethod.Notification) { - Notification = (IIPPacketNotification)(data[offset++] & 0x3f); + Notification = (IIPPacketNotification)(data[offset++] & 0x1f); } else if (Method == IIPPacketMethod.Request) { - Request = (IIPPacketRequest)(data[offset++] & 0x3f); + Request = (IIPPacketRequest)(data[offset++] & 0x1f); if (NotEnough(offset, ends, 4)) return -dataLengthNeeded; @@ -94,7 +106,7 @@ class IIPPacket : Packet } else if (Method == IIPPacketMethod.Reply) { - Reply = (IIPPacketReply)(data[offset++] & 0x3f); + Reply = (IIPPacketReply)(data[offset++] & 0x1f); if (NotEnough(offset, ends, 4)) return -dataLengthNeeded; @@ -104,7 +116,7 @@ class IIPPacket : Packet } else if (Method == IIPPacketMethod.Extension) { - Extension = (byte)(data[offset++] & 0x3f); + Extension = (byte)(data[offset++] & 0x1f); } if (hasDTU) diff --git a/Esiur/Resource/Warehouse.cs b/Esiur/Resource/Warehouse.cs index c55f08f..bfde8cf 100644 --- a/Esiur/Resource/Warehouse.cs +++ b/Esiur/Resource/Warehouse.cs @@ -361,39 +361,6 @@ public class Warehouse if (store == null) throw new Exception("Resource store is not set."); - //if (store == null) - //{ - // // assign parent's store as a store - // if (parent != null) - // { - // // assign parent as a store - // if (parent is IStore) - // { - // store = (IStore)parent; - // List> list; - // if (stores.TryGetValue(store, out list)) - // lock (((ICollection)list).SyncRoot) - // list.Add(resourceReference); - // //stores[store].Add(resourceReference); - // } - // else - // { - // store = parent.Instance.Store; - - // List> list; - // if (stores.TryGetValue(store, out list)) - // lock (((ICollection)list).SyncRoot) - // list.Add(resourceReference); - // } - // } - // // assign self as a store (root store) - // else if (resource is IStore) - // { - // store = (IStore)resource; - // } - // else - // throw new Exception("Can't find a store for the resource."); - //} resource.Instance = new Instance(this, resourceCounter++, instanceName, resource, store, customTemplate, age); @@ -464,34 +431,115 @@ public class Warehouse if (resource.Instance != null) throw new Exception("Resource has a store."); + if (string.IsNullOrEmpty(path)) + throw new ArgumentNullException("Invalid path."); + var location = path.TrimStart('/').Split('/'); IResource parent = null; + IStore store = null; var instanceName = location.Last(); - if (location.Length <= 1 && !(resource is IStore)) - throw new Exception("Can't find the store."); - else if (location.Length == 1) - return await Put(path, resource, null, customTemplate, age, manager, attributes); - else + if (location.Length == 1) { - // get parent - parent = await Get(string.Join("/", location.Take(location.Length - 1))); + if (!(resource is IStore)) + throw new Exception("Resource is not a store, root level path is not allowed."); - if (parent == null) - throw new Exception("Can't find parent"); - return await Put(instanceName, resource, parent.Instance.Store, customTemplate, age, manager, attributes); } + + if (location.Length == 1 && + + + if (location.Length == 1) + return await Put(path, resource, null, customTemplate, age, manager, attributes); + else + { + // get parent + parent = await Get(string.Join("/", location.Take(location.Length - 1))); + + if (parent == null) + throw new Exception("Can't find parent"); + + return await Put(instanceName, resource, parent.Instance.Store, customTemplate, age, manager, attributes); + } + + + + var resourceReference = new WeakReference(resource); + + + if (resource is IStore && store == null) + store = (IStore)resource; + + if (store == null) + throw new Exception("Resource store is not set."); + + + resource.Instance = new Instance(this, resourceCounter++, instanceName, resource, store, customTemplate, age); + + if (attributes != null) + if (attributes is Map attrs) + resource.Instance.SetAttributes(attrs); + else + resource.Instance.SetAttributes(Map.FromObject(attributes)); + + if (manager != null) + resource.Instance.Managers.Add(manager); + + //if (store == parent) + // parent = null; + + + try + { + if (resource is IStore) + stores.TryAdd(resource as IStore, new List>()); + + + if (!await store.Put(resource)) + throw new Exception("Store failed to put the resource"); + //return default(T); + + + //if (parent != null) + //{ + // await parent.Instance.Store.AddChild(parent, resource); + // await store.AddParent(resource, parent); + //} + + var t = resource.GetType(); + Global.Counters["T-" + t.Namespace + "." + t.Name]++; + + resources.TryAdd(resource.Instance.Id, resourceReference); + + if (warehouseIsOpen) + { + await resource.Trigger(ResourceTrigger.Initialize); + if (resource is IStore) + await resource.Trigger(ResourceTrigger.Open); + } + + if (resource is IStore) + StoreConnected?.Invoke(resource as IStore); + } + catch (Exception ex) + { + Remove(resource); + throw ex; + } + + return resource; + } - public T CreateInstance(object properties = null) + public T Create(object properties = null) { - return (T)CreateInstance(typeof(T), properties); + return (T)Create(typeof(T), properties); } - public IResource CreateInstance(Type type, object properties = null) + public IResource Create(Type type, object properties = null) { type = ResourceProxy.GetProxy(type); diff --git a/Esiur/Stores/MemoryStore.cs b/Esiur/Stores/MemoryStore.cs index 2b47478..9c1c772 100644 --- a/Esiur/Stores/MemoryStore.cs +++ b/Esiur/Stores/MemoryStore.cs @@ -65,19 +65,7 @@ public class MemoryStore : IStore return new AsyncReply(true); } - //public AsyncReply Retrieve(uint iid) - //{ - // if (resources.ContainsKey(iid)) - // { - // if (resources.ContainsKey(iid))// .TryGetTarget(out r)) - // return new AsyncReply(resources[iid]); - // else - // return new AsyncReply(null); - // } - // else - // return new AsyncReply(null); - //} - + public AsyncReply Trigger(ResourceTrigger trigger) { return new AsyncReply(true);