2
0
mirror of https://github.com/esiur/esiur-dotnet.git synced 2025-09-13 12:43:17 +00:00
This commit is contained in:
2025-08-24 22:10:35 +03:00
parent 490f3eeebd
commit 3ea7adaebc
13 changed files with 106 additions and 123 deletions

View File

@@ -103,7 +103,7 @@ public class EntityStore : IStore
} }
} }
public AsyncReply<bool> Put(IResource resource) public AsyncReply<bool> Put(IResource resource, string path)
{ {
if (resource == this) if (resource == this)
return new AsyncReply<bool>(true); return new AsyncReply<bool>(true);

View File

@@ -131,7 +131,7 @@ public static class EsiurExtensions
var id = store.TypesByType[typeof(T)].PrimaryKey.GetValue(resource); var id = store.TypesByType[typeof(T)].PrimaryKey.GetValue(resource);
await options.Warehouse.Put(id.ToString(), res, store, null, 0, manager); await options.Warehouse.Put($"{store.Instance.Name}/{typeof(T).Name}/{id}", res, null, 0, manager);
return (T)res; return (T)res;
} }

View File

@@ -71,7 +71,7 @@ public class EsiurProxyRewrite : IModelFinalizingConvention
// check if the object exists // check if the object exists
var obj = options.Warehouse.Create(entityType.ClrType) as IResource; var obj = options.Warehouse.Create(entityType.ClrType) as IResource;
options.Store.TypesByType[entityType.ClrType].PrimaryKey.SetValue(obj, id); options.Store.TypesByType[entityType.ClrType].PrimaryKey.SetValue(obj, id);
options.Warehouse.Put(id.ToString(), obj, options.Store, null, 0, manager).Wait(); options.Warehouse.Put($"{options.Store.Instance.Name}/{entityType.ClrType.Name}/{id}", obj, null, 0, manager).Wait();
return obj; return obj;
} }
else else

View File

@@ -303,7 +303,7 @@ public class MongoDBStore : IStore
return this.Instance.Name + "/id/" + (string)resource.Instance.Variables["objectId"]; return this.Instance.Name + "/id/" + (string)resource.Instance.Variables["objectId"];
} }
public async AsyncReply<bool> Put(IResource resource) public async AsyncReply<bool> Put(IResource resource, string path)
{ {
try try
{ {

View File

@@ -38,8 +38,8 @@ namespace Esiur.Stores.MongoDB
[Export] [Export]
public async AsyncReply<T> New(string name = null, object properties = null) public async AsyncReply<T> New(string name = null, object properties = null)
{ {
var resource = Instance.Warehouse.CreateInstance<T>(properties); var resource = Instance.Warehouse.Create<T>(properties);
await Instance.Warehouse.Put(name, resource, this, null, 0); await Instance.Warehouse.Put(this.Instance.Name + "/" + name, resource);
resource.Instance.Managers.AddRange(this.Instance.Managers.ToArray()); resource.Instance.Managers.AddRange(this.Instance.Managers.ToArray());
return resource; return resource;
} }

View File

@@ -1570,14 +1570,13 @@ public partial class DistributedConnection : NetworkConnection, IStore
return true; return true;
} }
// AsyncReply<bool> connect({ISocket socket, String hostname, int port, String username, DC password, String domain})
/// <summary> /// <summary>
/// Store interface. /// Store interface.
/// </summary> /// </summary>
/// <param name="resource">Resource.</param> /// <param name="resource">Resource.</param>
/// <returns></returns> /// <returns></returns>
public AsyncReply<bool> Put(IResource resource) public AsyncReply<bool> Put(IResource resource, string path)
{ {
if (Codec.IsLocalResource(resource, this)) if (Codec.IsLocalResource(resource, this))
neededResources.Add((resource as DistributedResource).DistributedResourceInstanceId, (DistributedResource)resource); neededResources.Add((resource as DistributedResource).DistributedResourceInstanceId, (DistributedResource)resource);

View File

@@ -272,7 +272,7 @@ partial class DistributedConnection
return; return;
} }
var (_, parsed) = Codec.ParseAsync(data, 0, this, null); var (_, parsed) = Codec.ParseAsync(data, 0, this, null, dataType);
if (parsed is AsyncReply reply) if (parsed is AsyncReply reply)
{ {
reply.Then(result => reply.Then(result =>
@@ -2054,7 +2054,7 @@ partial class DistributedConnection
dataType.ContentLength, Instance.Warehouse); dataType.ContentLength, Instance.Warehouse);
var peerTime = (DateTime)args[0]; var peerTime = (DateTime)args[0];
var interval = (uint)args[0]; var interval = (uint)args[1];
uint jitter = 0; uint jitter = 0;

View File

@@ -37,7 +37,7 @@ namespace Esiur.Resource;
public interface IStore : IResource public interface IStore : IResource
{ {
AsyncReply<IResource> Get(string path); AsyncReply<IResource> Get(string path);
AsyncReply<bool> Put(IResource resource); AsyncReply<bool> Put(IResource resource, string path);
string Link(IResource resource); string Link(IResource resource);
bool Record(IResource resource, string propertyName, object value, ulong? age, DateTime? dateTime); bool Record(IResource resource, string propertyName, object value, ulong? age, DateTime? dateTime);
bool Modify(IResource resource, string propertyName, object value, ulong? age, DateTime? dateTime); bool Modify(IResource resource, string propertyName, object value, ulong? age, DateTime? dateTime);

View File

@@ -764,7 +764,7 @@ public class Instance
if (res == res.Instance.store) if (res == res.Instance.store)
return name; // root store return name; // root store
else else
return store.Link(res); return store.Instance.name + "/" + store.Link(res);
} }
else else
return null; return null;

View File

@@ -31,7 +31,7 @@ public abstract class Store<T> : IStore where T : IResource
public abstract bool Modify(IResource resource, string propertyName, object value, ulong? age, DateTime? dateTime); public abstract bool Modify(IResource resource, string propertyName, object value, ulong? age, DateTime? dateTime);
public abstract AsyncReply<bool> Put(IResource resource); public abstract AsyncReply<bool> Put(IResource resource, string path);
public abstract bool Record(IResource resource, string propertyName, object value, ulong? age, DateTime? dateTime); public abstract bool Record(IResource resource, string propertyName, object value, ulong? age, DateTime? dateTime);

View File

@@ -346,78 +346,78 @@ public class Warehouse
/// <param name="resource">Resource instance.</param> /// <param name="resource">Resource instance.</param>
/// <param name="store">IStore that manages the resource. Can be null if the resource is a store.</param> /// <param name="store">IStore that manages the resource. Can be null if the resource is a store.</param>
/// <param name="parent">Parent resource. if not presented the store becomes the parent for the resource.</param> /// <param name="parent">Parent resource. if not presented the store becomes the parent for the resource.</param>
public async AsyncReply<T> Put<T>(string instanceName, T resource, IStore store, TypeTemplate customTemplate = null, ulong age = 0, IPermissionsManager manager = null, object attributes = null) where T : IResource //public async AsyncReply<T> Put<T>(string instanceName, T resource, IStore store, TypeTemplate customTemplate = null, ulong age = 0, IPermissionsManager manager = null, object attributes = null) where T : IResource
{ //{
if (resource.Instance != null) // if (resource.Instance != null)
throw new Exception("Resource has a store."); // throw new Exception("Resource has a store.");
var resourceReference = new WeakReference<IResource>(resource); // var resourceReference = new WeakReference<IResource>(resource);
if (resource is IStore && store == null) // if (resource is IStore && store == null)
store = (IStore)resource; // store = (IStore)resource;
if (store == null) // if (store == null)
throw new Exception("Resource store is not set."); // throw new Exception("Resource store is not set.");
resource.Instance = new Instance(this, resourceCounter++, instanceName, resource, store, customTemplate, age); // resource.Instance = new Instance(this, resourceCounter++, instanceName, resource, store, customTemplate, age);
if (attributes != null) // if (attributes != null)
if (attributes is Map<string, object> attrs) // if (attributes is Map<string, object> attrs)
resource.Instance.SetAttributes(attrs); // resource.Instance.SetAttributes(attrs);
else // else
resource.Instance.SetAttributes(Map<string, object>.FromObject(attributes)); // resource.Instance.SetAttributes(Map<string, object>.FromObject(attributes));
if (manager != null) // if (manager != null)
resource.Instance.Managers.Add(manager); // resource.Instance.Managers.Add(manager);
//if (store == parent) // //if (store == parent)
// parent = null; // // parent = null;
try // try
{ // {
if (resource is IStore) // if (resource is IStore)
stores.TryAdd(resource as IStore, new List<WeakReference<IResource>>()); // stores.TryAdd(resource as IStore, new List<WeakReference<IResource>>());
if (!await store.Put(resource)) // if (!await store.Put(resource))
throw new Exception("Store failed to put the resource"); // throw new Exception("Store failed to put the resource");
//return default(T); // //return default(T);
//if (parent != null) // //if (parent != null)
//{ // //{
// await parent.Instance.Store.AddChild(parent, resource); // // await parent.Instance.Store.AddChild(parent, resource);
// await store.AddParent(resource, parent); // // await store.AddParent(resource, parent);
//} // //}
var t = resource.GetType(); // var t = resource.GetType();
Global.Counters["T-" + t.Namespace + "." + t.Name]++; // Global.Counters["T-" + t.Namespace + "." + t.Name]++;
resources.TryAdd(resource.Instance.Id, resourceReference); // resources.TryAdd(resource.Instance.Id, resourceReference);
if (warehouseIsOpen) // if (warehouseIsOpen)
{ // {
await resource.Trigger(ResourceTrigger.Initialize); // await resource.Trigger(ResourceTrigger.Initialize);
if (resource is IStore) // if (resource is IStore)
await resource.Trigger(ResourceTrigger.Open); // await resource.Trigger(ResourceTrigger.Open);
} // }
if (resource is IStore) // if (resource is IStore)
StoreConnected?.Invoke(resource as IStore); // StoreConnected?.Invoke(resource as IStore);
} // }
catch (Exception ex) // catch (Exception ex)
{ // {
Remove(resource); // Remove(resource);
throw ex; // throw ex;
} // }
return resource; // return resource;
} //}
/// <summary> /// <summary>
/// Put a resource in the warehouse. /// Put a resource in the warehouse.
@@ -429,7 +429,7 @@ public class Warehouse
public async AsyncReply<T> Put<T>(string path, T resource, TypeTemplate customTemplate = null, ulong age = 0, IPermissionsManager manager = null, object attributes = null) where T : IResource public async AsyncReply<T> Put<T>(string path, T resource, TypeTemplate customTemplate = null, ulong age = 0, IPermissionsManager manager = null, object attributes = null) where T : IResource
{ {
if (resource.Instance != null) if (resource.Instance != null)
throw new Exception("Resource has a store."); throw new Exception("Resource already initialized.");
if (string.IsNullOrEmpty(path)) if (string.IsNullOrEmpty(path))
throw new ArgumentNullException("Invalid path."); throw new ArgumentNullException("Invalid path.");
@@ -437,6 +437,7 @@ public class Warehouse
var location = path.TrimStart('/').Split('/'); var location = path.TrimStart('/').Split('/');
IStore store = null; IStore store = null;
//IResource parent = null;
var instanceName = location.Last(); var instanceName = location.Last();
@@ -447,73 +448,46 @@ public class Warehouse
store = (IStore)resource; store = (IStore)resource;
} }
else
{
if (location.Length == 1 && // get parent
var parent = await Get<IResource>(string.Join("/", location.Take(location.Length - 1)));
if (parent == null)
throw new Exception("Can't find parent");
if (location.Length == 1) store = parent.Instance.Store;// GetStore(location[0]);
return await Put<T>(path, resource, null, customTemplate, age, manager, attributes);
else
{
// get parent
parent = await Get<IResource>(string.Join("/", location.Take(location.Length - 1)));
if (parent == null)
throw new Exception("Can't find parent");
return await Put<T>(instanceName, resource, parent.Instance.Store, customTemplate, age, manager, attributes);
}
//if (store == null)
// throw new Exception("Store not found.");
}
var resourceReference = new WeakReference<IResource>(resource); var resourceReference = new WeakReference<IResource>(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); resource.Instance = new Instance(this, resourceCounter++, instanceName, resource, store, customTemplate, age);
if (attributes != null) if (attributes != null)
if (attributes is Map<string, object> attrs) if (attributes is Map<string, object> attrs)
resource.Instance.SetAttributes(attrs); resource.Instance.SetAttributes(attrs);
else else
resource.Instance.SetAttributes(Map<string, object>.FromObject(attributes)); resource.Instance.SetAttributes(Map<string, object>.FromObject(attributes));
//if (manager != null)
// resource.Instance.Managers.Add(manager);
//if (store == parent)
// parent = null;
try try
{ {
if (resource is IStore) if (resource is IStore)
stores.TryAdd(resource as IStore, new List<WeakReference<IResource>>()); stores.TryAdd(resource as IStore, new List<WeakReference<IResource>>());
else if ((IResource)resource != store)
{
if (!await store.Put(resource)) if (!await store.Put(resource, string.Join("/", location.Skip(1).ToArray())))
throw new Exception("Store failed to put the 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(); var t = resource.GetType();
Global.Counters["T-" + t.Namespace + "." + t.Name]++; Global.Counters["T-" + t.Namespace + "." + t.Name]++;
resources.TryAdd(resource.Instance.Id, resourceReference); resources.TryAdd(resource.Instance.Id, resourceReference);
if (warehouseIsOpen) if (warehouseIsOpen)
{ {
await resource.Trigger(ResourceTrigger.Initialize); await resource.Trigger(ResourceTrigger.Initialize);
@@ -523,6 +497,7 @@ public class Warehouse
if (resource is IStore) if (resource is IStore)
StoreConnected?.Invoke(resource as IStore); StoreConnected?.Invoke(resource as IStore);
} }
catch (Exception ex) catch (Exception ex)
{ {
@@ -599,7 +574,7 @@ public class Warehouse
public async AsyncReply<IResource> New(Type type, string path, IPermissionsManager manager = null, object attributes = null, object properties = null) public async AsyncReply<IResource> New(Type type, string path, IPermissionsManager manager = null, object attributes = null, object properties = null)
{ {
var res = CreateInstance(type, properties); var res = Create(type, properties);
return await Put(path, res, null, 0, manager, attributes); return await Put(path, res, null, 0, manager, attributes);
} }

View File

@@ -15,7 +15,7 @@ public class MemoryStore : IStore
public Instance Instance { get; set; } public Instance Instance { get; set; }
public event DestroyedEvent OnDestroy; public event DestroyedEvent OnDestroy;
KeyList<uint, IResource> resources = new KeyList<uint, IResource>(); KeyList<uint, IResource> resources = new KeyList<uint, IResource>();
@@ -27,8 +27,9 @@ public class MemoryStore : IStore
public string Link(IResource resource) public string Link(IResource resource)
{ {
if (resource.Instance.Store == this) if (resource.Instance.Store == this)
return this.Instance.Name + "/$" + resource.Instance.Id; return (string)resource.Instance.Variables["link"];
// return this.Instance.Name + "/$" + resource.Instance.Id;
return null; return null;
} }
@@ -48,24 +49,25 @@ public class MemoryStore : IStore
else else
{ {
foreach (var r in resources) foreach (var r in resources)
if (r.Value.Instance.Name == path) if (Link(r.Value) == path)//.Value.Instance.Name == path)
return new AsyncReply<IResource>(r.Value); return new AsyncReply<IResource>(r.Value);
} }
return new AsyncReply<IResource>(null); return new AsyncReply<IResource>(null);
} }
public AsyncReply<bool> Put(IResource resource) public AsyncReply<bool> Put(IResource resource, string path)
{ {
resources.Add(resource.Instance.Id, resource);// new WeakReference<IResource>(resource)); resources.Add(resource.Instance.Id, resource);
resource.Instance.Variables["children"] = new AutoList<IResource, Instance>(resource.Instance); resource.Instance.Variables["children"] = new AutoList<IResource, Instance>(resource.Instance);
resource.Instance.Variables["parents"] = new AutoList<IResource, Instance>(resource.Instance); resource.Instance.Variables["parents"] = new AutoList<IResource, Instance>(resource.Instance);
resource.Instance.Variables["link"] = path;
return new AsyncReply<bool>(true); return new AsyncReply<bool>(true);
} }
public AsyncReply<bool> Trigger(ResourceTrigger trigger) public AsyncReply<bool> Trigger(ResourceTrigger trigger)
{ {
return new AsyncReply<bool>(true); return new AsyncReply<bool>(true);
@@ -102,7 +104,7 @@ public class MemoryStore : IStore
// else // else
// return new AsyncReply<bool>(false); // return new AsyncReply<bool>(false);
//} //}
//public AsyncReply<bool> AddParent(IResource resource, IResource parent) //public AsyncReply<bool> AddParent(IResource resource, IResource parent)
//{ //{
@@ -123,12 +125,19 @@ public class MemoryStore : IStore
public AsyncBag<T> Children<T>(IResource resource, string name) where T : IResource public AsyncBag<T> Children<T>(IResource resource, string name) where T : IResource
{ {
var children = (resource.Instance.Variables["children"] as AutoList<IResource, Instance>);
if (name == null) var rt = new AsyncBag<T>();
return new AsyncBag<T>(children.Where(x => x is T).Select(x => (T)x).ToArray());
else var location = Link(resource) + "/";
return new AsyncBag<T>(children.Where(x => x is T && x.Instance.Name == name).Select(x => (T)x).ToArray());
return new AsyncBag<T>(resources.Where(r => r.Value is T && Link(r.Value).StartsWith(location)).Select(r => (T)r.Value).ToArray());
//var children = (resource.Instance.Variables["children"] as AutoList<IResource, Instance>);
//if (name == null)
// return new AsyncBag<T>(children.Where(x => x is T).Select(x => (T)x).ToArray());
//else
// return new AsyncBag<T>(children.Where(x => x is T && x.Instance.Name == name).Select(x => (T)x).ToArray());
} }

View File

@@ -40,7 +40,7 @@ public class TemporaryStore : IStore
return new AsyncReply<IResource>(null); return new AsyncReply<IResource>(null);
} }
public AsyncReply<bool> Put(IResource resource) public AsyncReply<bool> Put(IResource resource, string path)
{ {
resources.Add(resource.Instance.Id, new WeakReference(resource)); resources.Add(resource.Instance.Id, new WeakReference(resource));
return new AsyncReply<bool>(true); return new AsyncReply<bool>(true);