mirror of
https://github.com/esiur/esiur-dotnet.git
synced 2025-09-13 20:43:19 +00:00
update
This commit is contained in:
@@ -127,7 +127,7 @@ public class EntityStore : IStore
|
|||||||
public IResource GetById(Type type, object id)
|
public IResource GetById(Type type, object id)
|
||||||
{
|
{
|
||||||
if (!initialized)
|
if (!initialized)
|
||||||
throw new Exception("Store not initalized. Make sure the Warehouse is open.");
|
throw new Exception("Store is not initialized. Make sure the Warehouse is open.");
|
||||||
|
|
||||||
lock (DBLock)
|
lock (DBLock)
|
||||||
{
|
{
|
||||||
|
@@ -35,6 +35,7 @@ using Microsoft.EntityFrameworkCore.Metadata;
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using Esiur.Proxy;
|
using Esiur.Proxy;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Esiur.Resource;
|
||||||
|
|
||||||
namespace Esiur.Stores.EntityCore;
|
namespace Esiur.Stores.EntityCore;
|
||||||
|
|
||||||
@@ -50,13 +51,15 @@ public class EsiurExtensionOptions : IDbContextOptionsExtension
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
private DbContextOptionsExtensionInfo _info;
|
DbContextOptionsExtensionInfo _info;
|
||||||
EntityStore _store;
|
EntityStore _store;
|
||||||
|
Warehouse _warehouse;
|
||||||
|
|
||||||
public DbContextOptionsExtensionInfo Info => _info;
|
public DbContextOptionsExtensionInfo Info => _info;
|
||||||
|
|
||||||
public EntityStore Store => _store;
|
public EntityStore Store => _store;
|
||||||
|
|
||||||
|
public Warehouse Warehouse => _warehouse;
|
||||||
|
|
||||||
public void ApplyServices(IServiceCollection services)
|
public void ApplyServices(IServiceCollection services)
|
||||||
{
|
{
|
||||||
@@ -84,6 +87,7 @@ public class EsiurExtensionOptions : IDbContextOptionsExtension
|
|||||||
{
|
{
|
||||||
_info = new ExtensionInfo(this);
|
_info = new ExtensionInfo(this);
|
||||||
_store = store;
|
_store = store;
|
||||||
|
_warehouse = store.Instance.Warehouse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -57,7 +57,8 @@ public static class EsiurExtensions
|
|||||||
|
|
||||||
public static async AsyncReply<T> AddResourceAsync<T>(this DbSet<T> dbSet, T resource) where T : class, IResource
|
public static async AsyncReply<T> AddResourceAsync<T>(this DbSet<T> dbSet, T resource) where T : class, IResource
|
||||||
{
|
{
|
||||||
var store = dbSet.GetInfrastructure().GetService<IDbContextOptions>().FindExtension<EsiurExtensionOptions>().Store;
|
var options = dbSet.GetInfrastructure().GetService<IDbContextOptions>().FindExtension<EsiurExtensionOptions>();
|
||||||
|
var store = options.Store;
|
||||||
|
|
||||||
if (store == null)
|
if (store == null)
|
||||||
throw new Exception("Store not set, please call 'UseEsiur' on your DbContextOptionsBuilder.");
|
throw new Exception("Store not set, please call 'UseEsiur' on your DbContextOptionsBuilder.");
|
||||||
@@ -89,7 +90,6 @@ public static class EsiurExtensions
|
|||||||
|
|
||||||
foreach (var p in ps)
|
foreach (var p in ps)
|
||||||
{
|
{
|
||||||
|
|
||||||
var mi = resType.GetMember(p.Key, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance)
|
var mi = resType.GetMember(p.Key, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance)
|
||||||
.FirstOrDefault();
|
.FirstOrDefault();
|
||||||
|
|
||||||
@@ -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 Warehouse.Put(id.ToString(), res, store, null, null, 0, manager);
|
await options.Warehouse.Put(id.ToString(), res, store, null, 0, manager);
|
||||||
|
|
||||||
return (T)res;
|
return (T)res;
|
||||||
}
|
}
|
||||||
|
@@ -69,11 +69,10 @@ public class EsiurProxyRewrite : IModelFinalizingConvention
|
|||||||
if (Codec.ImplementsInterface(entityType.ClrType, typeof(IResource)))
|
if (Codec.ImplementsInterface(entityType.ClrType, typeof(IResource)))
|
||||||
{
|
{
|
||||||
// check if the object exists
|
// check if the object exists
|
||||||
var obj = Warehouse.New(entityType.ClrType).Wait() as IResource;
|
var obj = options.Warehouse.CreateInstance(entityType.ClrType) as IResource;
|
||||||
options.Store.TypesByType[entityType.ClrType].PrimaryKey.SetValue(obj, id);
|
options.Store.TypesByType[entityType.ClrType].PrimaryKey.SetValue(obj, id);
|
||||||
Warehouse.Put(id.ToString(), obj, options.Store, null, null, 0, manager).Wait();
|
options.Warehouse.Put(id.ToString(), obj, options.Store, null, 0, manager).Wait();
|
||||||
return obj;
|
return obj;
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@@ -110,7 +110,7 @@ public class MongoDBStore : IStore
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public bool Remove(IResource resource)
|
public AsyncReply<bool> Remove(IResource resource)
|
||||||
{
|
{
|
||||||
var objectId = resource.Instance.Variables["objectId"].ToString();
|
var objectId = resource.Instance.Variables["objectId"].ToString();
|
||||||
var filter = Builders<BsonDocument>.Filter.Eq("_id", new BsonObjectId(new ObjectId(objectId)));
|
var filter = Builders<BsonDocument>.Filter.Eq("_id", new BsonObjectId(new ObjectId(objectId)));
|
||||||
@@ -125,7 +125,7 @@ public class MongoDBStore : IStore
|
|||||||
|
|
||||||
Instance.Modified("Count");
|
Instance.Modified("Count");
|
||||||
|
|
||||||
return true;
|
return new AsyncReply<bool>(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
async AsyncReply<T> Fetch<T>(string id) where T : IResource
|
async AsyncReply<T> Fetch<T>(string id) where T : IResource
|
||||||
@@ -159,7 +159,7 @@ public class MongoDBStore : IStore
|
|||||||
resources.Add(id, new WeakReference(resource));
|
resources.Add(id, new WeakReference(resource));
|
||||||
|
|
||||||
//@TODO this causes store.put to be invoked, need fix
|
//@TODO this causes store.put to be invoked, need fix
|
||||||
await Warehouse.Put(document["name"].AsString, resource, this);
|
await Instance.Warehouse.Put(document["name"].AsString, resource);
|
||||||
|
|
||||||
|
|
||||||
var parents = document["parents"].AsBsonArray;
|
var parents = document["parents"].AsBsonArray;
|
||||||
@@ -887,22 +887,51 @@ public class MongoDBStore : IStore
|
|||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
AsyncReply<bool> IStore.Remove(IResource resource)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public AsyncReply<bool> Remove(string path)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public AsyncReply<bool> Move(IResource resource, string newPath)
|
public AsyncReply<bool> Move(IResource resource, string newPath)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public AsyncReply<T> Parent<T>(IResource resource, string name) where T : IResource
|
|
||||||
|
public AsyncBag<T> Parents<T>(IResource resource, string name) where T : IResource
|
||||||
|
{
|
||||||
|
|
||||||
|
if (resource == this)
|
||||||
|
{
|
||||||
|
return new AsyncBag<T>(null);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var parents = (string[])resource.Instance.Variables["parents"];
|
||||||
|
|
||||||
|
if (parents == null)
|
||||||
|
{
|
||||||
|
return new AsyncBag<T>(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
var rt = new AsyncBag<T>();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
foreach (var parent in parents)
|
||||||
|
{
|
||||||
|
var r = Instance.Warehouse.Get<T>(parent);
|
||||||
|
if (r is AsyncReply<T>)
|
||||||
|
rt.Add(r);// (AsyncReply<T>)r);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
rt.Seal();
|
||||||
|
|
||||||
|
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public AsyncReply<bool> Remove(string path)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
@@ -38,7 +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 = await Warehouse.New<T>(name, this, null, null, null, properties);
|
var resource = Instance.Warehouse.CreateInstance<T>(properties);
|
||||||
|
await Instance.Warehouse.Put(name, resource, this, null, 0);
|
||||||
resource.Instance.Managers.AddRange(this.Instance.Managers.ToArray());
|
resource.Instance.Managers.AddRange(this.Instance.Managers.ToArray());
|
||||||
return resource;
|
return resource;
|
||||||
}
|
}
|
||||||
|
@@ -782,15 +782,15 @@ public class Instance
|
|||||||
return new AsyncBag<T>(null);
|
return new AsyncBag<T>(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public AsyncReply<T> Parent<T>(string name = null) where T : IResource
|
public AsyncBag<T> Parents<T>(string name = null) where T : IResource
|
||||||
{
|
{
|
||||||
IResource res;
|
IResource res;
|
||||||
if (this.resource.TryGetTarget(out res))
|
if (this.resource.TryGetTarget(out res))
|
||||||
{
|
{
|
||||||
return store.Parent<T>(res, name);
|
return store.Parents<T>(res, name);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return new AsyncReply<T>(default(T));
|
return new AsyncBag<T>(default(T[]));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -340,62 +340,54 @@ 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 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 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 location = path.TrimStart('/').Split('/');
|
|
||||||
|
|
||||||
IResource parent = null;
|
|
||||||
IStore store = null;
|
|
||||||
var instanceName = location.Last();
|
|
||||||
|
|
||||||
if (location.Length > 1)
|
|
||||||
{
|
|
||||||
parent = await Get<IResource>(string.Join("/", path.Take(path.Length - 1)));
|
|
||||||
|
|
||||||
if (parent == null)
|
|
||||||
throw new Exception("Can't find parent");
|
|
||||||
|
|
||||||
store = parent.Instance.Store;
|
|
||||||
}
|
|
||||||
|
|
||||||
var resourceReference = new WeakReference<IResource>(resource);
|
var resourceReference = new WeakReference<IResource>(resource);
|
||||||
|
|
||||||
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<WeakReference<IResource>> list;
|
|
||||||
if (stores.TryGetValue(store, out list))
|
|
||||||
lock (((ICollection)list).SyncRoot)
|
|
||||||
list.Add(resourceReference);
|
|
||||||
//stores[store].Add(resourceReference);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
store = parent.Instance.Store;
|
|
||||||
|
|
||||||
List<WeakReference<IResource>> list;
|
if (resource is IStore && store == null)
|
||||||
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;
|
store = (IStore)resource;
|
||||||
}
|
|
||||||
else
|
if (store == null)
|
||||||
throw new Exception("Can't find a store for the resource.");
|
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<WeakReference<IResource>> list;
|
||||||
|
// if (stores.TryGetValue(store, out list))
|
||||||
|
// lock (((ICollection)list).SyncRoot)
|
||||||
|
// list.Add(resourceReference);
|
||||||
|
// //stores[store].Add(resourceReference);
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// store = parent.Instance.Store;
|
||||||
|
|
||||||
|
// List<WeakReference<IResource>> 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);
|
resource.Instance = new Instance(this, resourceCounter++, instanceName, resource, store, customTemplate, age);
|
||||||
|
|
||||||
@@ -408,8 +400,8 @@ public class Warehouse
|
|||||||
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
|
||||||
@@ -451,11 +443,50 @@ public class Warehouse
|
|||||||
}
|
}
|
||||||
|
|
||||||
return resource;
|
return resource;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async AsyncReply<IResource> New(Type type, string path, IPermissionsManager manager = null, object attributes = null, object properties = null)
|
/// <summary>
|
||||||
|
/// Put a resource in the warehouse.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">Resource name.</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="parent">Parent resource. if not presented the store becomes the parent for the resource.</param>
|
||||||
|
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)
|
||||||
|
throw new Exception("Resource has a store.");
|
||||||
|
|
||||||
|
var location = path.TrimStart('/').Split('/');
|
||||||
|
|
||||||
|
IResource parent = 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<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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public T CreateInstance<T>(object properties = null)
|
||||||
|
{
|
||||||
|
return (T)CreateInstance(typeof(T), properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IResource CreateInstance(Type type, object properties = null)
|
||||||
|
{
|
||||||
type = ResourceProxy.GetProxy(type);
|
type = ResourceProxy.GetProxy(type);
|
||||||
|
|
||||||
var res = Activator.CreateInstance(type) as IResource;
|
var res = Activator.CreateInstance(type) as IResource;
|
||||||
@@ -509,6 +540,12 @@ public class Warehouse
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async AsyncReply<IResource> New(Type type, string path, IPermissionsManager manager = null, object attributes = null, object properties = null)
|
||||||
|
{
|
||||||
|
var res = CreateInstance(type, properties);
|
||||||
return await Put(path, res, null, 0, manager, attributes);
|
return await Put(path, res, null, 0, manager, attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user