mirror of
https://github.com/esiur/esiur-dotnet.git
synced 2025-05-06 19:42:58 +00:00
EntityCore
This commit is contained in:
parent
3205499747
commit
7a21f6a928
71
Esyur.Stores.EntityCore/EntityResource.cs
Normal file
71
Esyur.Stores.EntityCore/EntityResource.cs
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (c) 2020 Ahmed Kh. Zamil
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using Esyur.Core;
|
||||||
|
using Esyur.Resource;
|
||||||
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
|
namespace Esyur.Stores.EntityCore
|
||||||
|
{
|
||||||
|
public class EntityResource : IResource
|
||||||
|
{
|
||||||
|
public event DestroyedEvent OnDestroy;
|
||||||
|
public event PropertyChangedEventHandler PropertyChanged;
|
||||||
|
|
||||||
|
[NotMapped]
|
||||||
|
public Instance Instance { get; set; }
|
||||||
|
|
||||||
|
public EntityResource()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected virtual void Create()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public AsyncReply<bool> Trigger(ResourceTrigger trigger)
|
||||||
|
{
|
||||||
|
if (trigger == ResourceTrigger.Initialize)
|
||||||
|
Create();
|
||||||
|
|
||||||
|
return new AsyncReply<bool>(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Destroy()
|
||||||
|
{
|
||||||
|
//throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
153
Esyur.Stores.EntityCore/EntityStore.cs
Normal file
153
Esyur.Stores.EntityCore/EntityStore.cs
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (c) 2020 Ahmed Kh. Zamil
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
using Esyur.Core;
|
||||||
|
using Esyur.Data;
|
||||||
|
using Esyur.Resource;
|
||||||
|
using Esyur.Resource.Template;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using Microsoft.EntityFrameworkCore.Proxies;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
|
||||||
|
namespace Esyur.Stores.EntityCore
|
||||||
|
{
|
||||||
|
public class EntityStore : IStore
|
||||||
|
{
|
||||||
|
public Instance Instance { get; set; }
|
||||||
|
|
||||||
|
public event DestroyedEvent OnDestroy;
|
||||||
|
|
||||||
|
/*
|
||||||
|
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
||||||
|
{
|
||||||
|
var extension = optionsBuilder.Options.FindExtension<EsyurExtension>()
|
||||||
|
?? new EsyurExtension();
|
||||||
|
|
||||||
|
|
||||||
|
((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(extension);
|
||||||
|
//optionsBuilder.UseLazyLoadingProxies();
|
||||||
|
base.OnConfiguring(optionsBuilder);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
//modelBuilder.Entity<Series>().ToTable("Series");
|
||||||
|
//modelBuilder.Entity<Episode>().ToTable("Episodes").;
|
||||||
|
//modelBuilder.Ignore<Entit>
|
||||||
|
// modelBuilder.Entity<Series>(x=>x.Property(p=>p.Instance).HasConversion(v=>v.Managers.)
|
||||||
|
Console.WriteLine("OnModelCreating");
|
||||||
|
//modelBuilder.Entity()
|
||||||
|
|
||||||
|
|
||||||
|
base.OnModelCreating(modelBuilder);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
|
||||||
|
public AsyncReply<IResource> Get(string path)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async AsyncReply<bool> Put(IResource resource)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Link(IResource resource)
|
||||||
|
{
|
||||||
|
var p = resource.GetType().GetProperty("Id");
|
||||||
|
if (p != null)
|
||||||
|
return this.Instance.Name + "/" + resource.GetType().Name + "/" + p.GetValue(resource);
|
||||||
|
else
|
||||||
|
return this.Instance.Name + "/" + resource.GetType().Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Record(IResource resource, string propertyName, object value, ulong age, DateTime dateTime)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
//throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Modify(IResource resource, string propertyName, object value, ulong age, DateTime dateTime)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
//throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public new bool Remove(IResource resource)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public AsyncReply<bool> AddChild(IResource parent, IResource child)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public AsyncReply<bool> RemoveChild(IResource parent, IResource child)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public AsyncReply<bool> AddParent(IResource child, IResource parent)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public AsyncReply<bool> RemoveParent(IResource child, IResource parent)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public AsyncBag<T> Children<T>(IResource resource, string name) where T : IResource
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public AsyncBag<T> Parents<T>(IResource resource, string name) where T : IResource
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public AsyncReply<KeyList<PropertyTemplate, PropertyValue[]>> GetRecord(IResource resource, DateTime fromDate, DateTime toDate)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public AsyncReply<bool> Trigger(ResourceTrigger trigger)
|
||||||
|
{
|
||||||
|
return new AsyncReply<bool>(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Destroy()
|
||||||
|
{
|
||||||
|
//throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
23
Esyur.Stores.EntityCore/Esyur.Stores.EntityCore.csproj
Normal file
23
Esyur.Stores.EntityCore/Esyur.Stores.EntityCore.csproj
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>netstandard2.0</TargetFramework>
|
||||||
|
<AssemblyName>Esyur.Stores.EntityCore</AssemblyName>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Marten" Version="3.10.0" />
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.1" />
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Proxies" Version="3.1.1" />
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.1.1">
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="3.1.1.2" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\Esyur\Esyur.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
114
Esyur.Stores.EntityCore/EsyurExtensionOptions.cs
Normal file
114
Esyur.Stores.EntityCore/EsyurExtensionOptions.cs
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (c) 2020 Ahmed Kh. Zamil
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal;
|
||||||
|
using Microsoft.EntityFrameworkCore.Utilities;
|
||||||
|
using Microsoft.EntityFrameworkCore.Proxies.Internal;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace Esyur.Stores.EntityCore
|
||||||
|
{
|
||||||
|
public class EsyurExtensionOptions : IDbContextOptionsExtension
|
||||||
|
{
|
||||||
|
private DbContextOptionsExtensionInfo _info;
|
||||||
|
EntityStore _store;
|
||||||
|
|
||||||
|
public DbContextOptionsExtensionInfo Info => _info;
|
||||||
|
|
||||||
|
public EntityStore Store => _store;
|
||||||
|
|
||||||
|
public void ApplyServices(IServiceCollection services)
|
||||||
|
{
|
||||||
|
services.AddEntityFrameworkProxies();
|
||||||
|
|
||||||
|
new EntityFrameworkServicesBuilder(services)
|
||||||
|
.TryAdd<IConventionSetPlugin, EsyurPlugin>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Validate(IDbContextOptions options)
|
||||||
|
{
|
||||||
|
var internalServiceProvider = options.FindExtension<CoreOptionsExtension>()?.InternalServiceProvider;
|
||||||
|
if (internalServiceProvider != null)
|
||||||
|
{
|
||||||
|
var scope = internalServiceProvider.CreateScope();
|
||||||
|
var conventionPlugins = scope.ServiceProvider.GetService<IEnumerable<IConventionSetPlugin>>();
|
||||||
|
if (conventionPlugins?.Any(s => s is EsyurPlugin) == false)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public EsyurExtensionOptions(EntityStore store)
|
||||||
|
{
|
||||||
|
_info = new ExtensionInfo(this);
|
||||||
|
_store = store;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private sealed class ExtensionInfo : DbContextOptionsExtensionInfo
|
||||||
|
{
|
||||||
|
private string _logFragment;
|
||||||
|
|
||||||
|
public ExtensionInfo(IDbContextOptionsExtension extension)
|
||||||
|
: base(extension)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
private new EsyurExtensionOptions Extension
|
||||||
|
=> (EsyurExtensionOptions)base.Extension;
|
||||||
|
|
||||||
|
public override bool IsDatabaseProvider => false;
|
||||||
|
|
||||||
|
public override string LogFragment => "Esyur";
|
||||||
|
|
||||||
|
// => _logFragment ??= Extension.UseLazyLoadingProxies && Extension.UseChangeDetectionProxies
|
||||||
|
// ? "using lazy-loading and change detection proxies "
|
||||||
|
// : Extension.UseLazyLoadingProxies
|
||||||
|
// ? "using lazy-loading proxies "
|
||||||
|
//: Extension.UseChangeDetectionProxies
|
||||||
|
//? "using change detection proxies "
|
||||||
|
//: "";
|
||||||
|
|
||||||
|
public override long GetServiceProviderHashCode() => 2312;//541;//2922;// Extension.UseProxies ? : 0;
|
||||||
|
|
||||||
|
public override void PopulateDebugInfo(IDictionary<string, string> debugInfo)
|
||||||
|
{
|
||||||
|
//debugInfo["Proxies:" + nameof(ProxiesExtensions.UseLazyLoadingProxies)]
|
||||||
|
// = (Extension._useLazyLoadingProxies ? 541 : 0).ToString(CultureInfo.InvariantCulture);
|
||||||
|
|
||||||
|
//debugInfo["Proxies:" + nameof(ProxiesExtensions.UseChangeDetectionProxies)]
|
||||||
|
// = (Extension._useChangeDetectionProxies ? 541 : 0).ToString(CultureInfo.InvariantCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
98
Esyur.Stores.EntityCore/EsyurExtensions.cs
Normal file
98
Esyur.Stores.EntityCore/EsyurExtensions.cs
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (c) 2020 Ahmed Kh. Zamil
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
using Esyur.Resource;
|
||||||
|
using Esyur.Security.Permissions;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Esyur.Stores.EntityCore
|
||||||
|
{
|
||||||
|
public static class EsyurExtensions
|
||||||
|
{
|
||||||
|
public static T CreateResource<T>(this DbContext dbContext) where T:IResource
|
||||||
|
{
|
||||||
|
return dbContext.GetInfrastructure().CreateResource<T>();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static T CreateResource<T>(this IServiceProvider serviceProvider) where T:IResource
|
||||||
|
{
|
||||||
|
var options = serviceProvider.GetService<IDbContextOptions>().FindExtension<EsyurExtensionOptions>();
|
||||||
|
var manager = options.Store.Instance.Managers.Count > 0 ? options.Store.Instance.Managers.First() : null;
|
||||||
|
|
||||||
|
return Warehouse.New<T>("", options.Store, null, manager);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DbContextOptionsBuilder UseEsyur(this DbContextOptionsBuilder optionsBuilder,
|
||||||
|
string name = null,
|
||||||
|
IResource parent = null,
|
||||||
|
IPermissionsManager manager = null
|
||||||
|
|
||||||
|
)
|
||||||
|
{
|
||||||
|
var extension = optionsBuilder.Options.FindExtension<EsyurExtensionOptions>();
|
||||||
|
|
||||||
|
if (extension == null)
|
||||||
|
{
|
||||||
|
var store = Warehouse.New<EntityStore>(name, null, parent, manager);
|
||||||
|
extension = new EsyurExtensionOptions(store);
|
||||||
|
}
|
||||||
|
|
||||||
|
((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(extension);
|
||||||
|
|
||||||
|
return optionsBuilder;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DbContextOptionsBuilder<TContext> UseEsyur<TContext>(
|
||||||
|
this DbContextOptionsBuilder<TContext> optionsBuilder,
|
||||||
|
string name = null,
|
||||||
|
IResource parent = null,
|
||||||
|
IPermissionsManager manager = null)
|
||||||
|
where TContext : DbContext
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
var extension = optionsBuilder.Options.FindExtension<EsyurExtensionOptions>();
|
||||||
|
|
||||||
|
if (extension == null)
|
||||||
|
{
|
||||||
|
var store = Warehouse.New<EntityStore>(name, null, parent, manager);
|
||||||
|
extension = new EsyurExtensionOptions(store);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(extension);
|
||||||
|
|
||||||
|
return optionsBuilder;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
60
Esyur.Stores.EntityCore/EsyurPlugin.cs
Normal file
60
Esyur.Stores.EntityCore/EsyurPlugin.cs
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (c) 2020 Ahmed Kh. Zamil
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Metadata.Conventions;
|
||||||
|
using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Proxies.Internal;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Esyur.Stores.EntityCore
|
||||||
|
{
|
||||||
|
public class EsyurPlugin : IConventionSetPlugin
|
||||||
|
{
|
||||||
|
private readonly IDbContextOptions _options;
|
||||||
|
private readonly ProviderConventionSetBuilderDependencies _conventionSetBuilderDependencies;
|
||||||
|
|
||||||
|
public EsyurPlugin(
|
||||||
|
IDbContextOptions options,
|
||||||
|
ProviderConventionSetBuilderDependencies conventionSetBuilderDependencies)
|
||||||
|
{
|
||||||
|
_options = options;
|
||||||
|
_conventionSetBuilderDependencies = conventionSetBuilderDependencies;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public ConventionSet ModifyConventions(ConventionSet conventionSet)
|
||||||
|
{
|
||||||
|
var extension = _options.FindExtension<EsyurExtensionOptions>();
|
||||||
|
conventionSet.ModelFinalizedConventions.Add(new EsyurProxyRewrite(
|
||||||
|
extension,
|
||||||
|
_conventionSetBuilderDependencies));
|
||||||
|
return conventionSet;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
120
Esyur.Stores.EntityCore/EsyurProxyRewrite.cs
Normal file
120
Esyur.Stores.EntityCore/EsyurProxyRewrite.cs
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (c) 2020 Ahmed Kh. Zamil
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
using Esyur.Proxy;
|
||||||
|
using Esyur.Resource;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Internal;
|
||||||
|
using Microsoft.EntityFrameworkCore.Metadata;
|
||||||
|
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||||
|
using Microsoft.EntityFrameworkCore.Metadata.Conventions;
|
||||||
|
using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Metadata.Internal;
|
||||||
|
|
||||||
|
namespace Esyur.Stores.EntityCore
|
||||||
|
{
|
||||||
|
public class EsyurProxyRewrite : IModelFinalizedConvention
|
||||||
|
{
|
||||||
|
private static readonly MethodInfo _createInstance
|
||||||
|
= typeof(EsyurProxyRewrite).GetTypeInfo().GetDeclaredMethod(nameof(EsyurProxyRewrite.CreateInstance));
|
||||||
|
|
||||||
|
private readonly ConstructorBindingConvention _directBindingConvention;
|
||||||
|
|
||||||
|
public static object CreateInstance(
|
||||||
|
IDbContextOptions dbContextOptions,
|
||||||
|
IEntityType entityType,
|
||||||
|
ILazyLoader loader,
|
||||||
|
object[] constructorArguments)
|
||||||
|
{
|
||||||
|
var options = dbContextOptions.FindExtension<EsyurExtensionOptions>();
|
||||||
|
|
||||||
|
return CreateInstance2(
|
||||||
|
options,
|
||||||
|
entityType,
|
||||||
|
loader,
|
||||||
|
constructorArguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static object CreateInstance2(
|
||||||
|
EsyurExtensionOptions options,
|
||||||
|
IEntityType entityType,
|
||||||
|
ILazyLoader loader,
|
||||||
|
object[] constructorArguments)
|
||||||
|
{
|
||||||
|
var manager = options.Store.Instance.Managers.Count > 0 ? options.Store.Instance.Managers.First() : null;
|
||||||
|
return Warehouse.New(entityType.ClrType, "", options.Store, null, manager);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public EsyurProxyRewrite(EsyurExtensionOptions ext, ProviderConventionSetBuilderDependencies conventionSetBuilderDependencies)
|
||||||
|
{
|
||||||
|
_directBindingConvention = new ConstructorBindingConvention(conventionSetBuilderDependencies);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ProcessModelFinalized(IConventionModelBuilder modelBuilder, IConventionContext<IConventionModelBuilder> context)
|
||||||
|
{
|
||||||
|
foreach (var entityType in modelBuilder.Metadata.GetEntityTypes())
|
||||||
|
{
|
||||||
|
var proxyType = ResourceProxy.GetProxy(entityType.ClrType);
|
||||||
|
|
||||||
|
var ann = entityType.GetAnnotation(CoreAnnotationNames.ConstructorBinding);
|
||||||
|
|
||||||
|
var binding = (InstantiationBinding)entityType[CoreAnnotationNames.ConstructorBinding];
|
||||||
|
if (binding == null)
|
||||||
|
_directBindingConvention.ProcessModelFinalized(modelBuilder, context);
|
||||||
|
|
||||||
|
binding = (InstantiationBinding)entityType[CoreAnnotationNames.ConstructorBinding];
|
||||||
|
|
||||||
|
|
||||||
|
try
|
||||||
|
|
||||||
|
{
|
||||||
|
entityType.SetAnnotation(
|
||||||
|
CoreAnnotationNames.ConstructorBinding,
|
||||||
|
new FactoryMethodBinding(
|
||||||
|
_createInstance,
|
||||||
|
new List<ParameterBinding>
|
||||||
|
{
|
||||||
|
new DependencyInjectionParameterBinding(typeof(IDbContextOptions), typeof(IDbContextOptions)),
|
||||||
|
new EntityTypeParameterBinding(),
|
||||||
|
new DependencyInjectionParameterBinding(typeof(ILazyLoader), typeof(ILazyLoader)),
|
||||||
|
new ObjectArrayParameterBinding(binding.ParameterBindings)
|
||||||
|
},
|
||||||
|
proxyType));
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,28 @@
|
|||||||
using Esyur.Resource;
|
/*
|
||||||
|
|
||||||
|
Copyright (c) 2017 Ahmed Kh. Zamil
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
using Esyur.Resource;
|
||||||
using System;
|
using System;
|
||||||
using Esyur.Core;
|
using Esyur.Core;
|
||||||
using MongoDB.Driver.Core;
|
using MongoDB.Driver.Core;
|
||||||
@ -61,7 +85,7 @@ namespace Esyur.Stores.MongoDB
|
|||||||
|
|
||||||
public bool Record(IResource resource, string propertyName, object value, ulong age, DateTime date)
|
public bool Record(IResource resource, string propertyName, object value, ulong age, DateTime date)
|
||||||
{
|
{
|
||||||
var objectId = resource.Instance.Attributes["objectId"].ToString();
|
var objectId = resource.Instance.Variables["objectId"].ToString();
|
||||||
//var bsonObjectId = new BsonObjectId(new ObjectId(objectId));
|
//var bsonObjectId = new BsonObjectId(new ObjectId(objectId));
|
||||||
|
|
||||||
var record = this.database.GetCollection<BsonDocument>("record_" + objectId);
|
var record = this.database.GetCollection<BsonDocument>("record_" + objectId);
|
||||||
@ -88,7 +112,7 @@ namespace Esyur.Stores.MongoDB
|
|||||||
[ResourceFunction]
|
[ResourceFunction]
|
||||||
public bool Remove(IResource resource)
|
public bool Remove(IResource resource)
|
||||||
{
|
{
|
||||||
var objectId = resource.Instance.Attributes["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)));
|
||||||
|
|
||||||
this.database.DropCollection("record_" + objectId);
|
this.database.DropCollection("record_" + objectId);
|
||||||
@ -148,8 +172,8 @@ namespace Esyur.Stores.MongoDB
|
|||||||
|
|
||||||
// var bag = new AsyncBag<object>();
|
// var bag = new AsyncBag<object>();
|
||||||
|
|
||||||
resource.Instance.Attributes.Add("children", children.Select(x => x.AsString).ToArray());
|
resource.Instance.Variables.Add("children", children.Select(x => x.AsString).ToArray());
|
||||||
resource.Instance.Attributes.Add("parents", parents.Select(x => x.AsString).ToArray());
|
resource.Instance.Variables.Add("parents", parents.Select(x => x.AsString).ToArray());
|
||||||
|
|
||||||
// Apply store managers
|
// Apply store managers
|
||||||
foreach (var m in this.Instance.Managers)
|
foreach (var m in this.Instance.Managers)
|
||||||
@ -275,7 +299,7 @@ namespace Esyur.Stores.MongoDB
|
|||||||
|
|
||||||
public string Link(IResource resource)
|
public string Link(IResource resource)
|
||||||
{
|
{
|
||||||
return this.Instance.Name + "/id/" + (string)resource.Instance.Attributes["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)
|
||||||
@ -285,13 +309,12 @@ namespace Esyur.Stores.MongoDB
|
|||||||
if (resource == this)
|
if (resource == this)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
|
||||||
var attrs = resource.Instance.GetAttributes();
|
var attrs = resource.Instance.GetAttributes();
|
||||||
|
|
||||||
foreach (var kv in resources)
|
foreach (var kv in resources)
|
||||||
if (kv.Value.Target == resource)
|
if (kv.Value.Target == resource)
|
||||||
{
|
{
|
||||||
resource.Instance.Attributes.Add("objectId", kv.Key);
|
resource.Instance.Variables.Add("objectId", kv.Key);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -309,7 +332,7 @@ namespace Esyur.Stores.MongoDB
|
|||||||
};
|
};
|
||||||
|
|
||||||
resourcesCollection.InsertOne(document);
|
resourcesCollection.InsertOne(document);
|
||||||
resource.Instance.Attributes["objectId"] = document["_id"].ToString();
|
resource.Instance.Variables["objectId"] = document["_id"].ToString();
|
||||||
|
|
||||||
|
|
||||||
// now update the document
|
// now update the document
|
||||||
@ -321,8 +344,8 @@ namespace Esyur.Stores.MongoDB
|
|||||||
var template = resource.Instance.Template;
|
var template = resource.Instance.Template;
|
||||||
|
|
||||||
// setup attributes
|
// setup attributes
|
||||||
resource.Instance.Attributes["children"] = new string[0];
|
resource.Instance.Variables["children"] = new string[0];
|
||||||
resource.Instance.Attributes["parents"] = new string[] { this.Instance.Link };
|
resource.Instance.Variables["parents"] = new string[] { this.Instance.Link };
|
||||||
|
|
||||||
// copy old children (in case we are moving a resource from a store to another.
|
// copy old children (in case we are moving a resource from a store to another.
|
||||||
if (resource.Instance.Store != this)
|
if (resource.Instance.Store != this)
|
||||||
@ -376,7 +399,7 @@ namespace Esyur.Stores.MongoDB
|
|||||||
|
|
||||||
resources.Add(document["_id"].AsObjectId.ToString(), new WeakReference(resource));
|
resources.Add(document["_id"].AsObjectId.ToString(), new WeakReference(resource));
|
||||||
|
|
||||||
//resource.Instance.Attributes["objectId"] = document["_id"].ToString();
|
//resource.Instance.Variables["objectId"] = document["_id"].ToString();
|
||||||
|
|
||||||
ResourceAdded?.Invoke(resource);
|
ResourceAdded?.Invoke(resource);
|
||||||
|
|
||||||
@ -390,9 +413,6 @@ namespace Esyur.Stores.MongoDB
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public BsonDocument ComposeStructure(Structure value)
|
public BsonDocument ComposeStructure(Structure value)
|
||||||
{
|
{
|
||||||
var rt = new BsonDocument { { "type", 1 } };
|
var rt = new BsonDocument { { "type", 1 } };
|
||||||
@ -435,9 +455,9 @@ namespace Esyur.Stores.MongoDB
|
|||||||
{
|
{
|
||||||
rt.Add(new BsonDocument { { "type", 0 }, { "link", r.Instance.Link } });
|
rt.Add(new BsonDocument { { "type", 0 }, { "link", r.Instance.Link } });
|
||||||
|
|
||||||
//if (r.Instance.Attributes.ContainsKey("objectId"))
|
//if (r.Instance.Variables.ContainsKey("objectId"))
|
||||||
|
|
||||||
//rt.Add(new BsonObjectId(new ObjectId((string)r.Instance.Attributes["objectId"])));
|
//rt.Add(new BsonObjectId(new ObjectId((string)r.Instance.Variables["objectId"])));
|
||||||
}
|
}
|
||||||
|
|
||||||
return rt;
|
return rt;
|
||||||
@ -461,7 +481,7 @@ namespace Esyur.Stores.MongoDB
|
|||||||
|
|
||||||
return new BsonDocument { { "type", 0 }, { "link", (value as IResource).Instance.Link } };
|
return new BsonDocument { { "type", 0 }, { "link", (value as IResource).Instance.Link } };
|
||||||
|
|
||||||
//return new BsonObjectId(new ObjectId((string)(value as IResource).Instance.Attributes["objectId"]));
|
//return new BsonObjectId(new ObjectId((string)(value as IResource).Instance.Variables["objectId"]));
|
||||||
|
|
||||||
case DataType.Structure:
|
case DataType.Structure:
|
||||||
return ComposeStructure((Structure)value);
|
return ComposeStructure((Structure)value);
|
||||||
@ -490,15 +510,21 @@ namespace Esyur.Stores.MongoDB
|
|||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[ResourceAttribute]
|
||||||
|
public string Connection { get; set; }
|
||||||
|
[ResourceAttribute]
|
||||||
|
public string Collection { get; set; }
|
||||||
|
[ResourceAttribute]
|
||||||
|
public string Database { get; set; }
|
||||||
public AsyncReply<bool> Trigger(ResourceTrigger trigger)
|
public AsyncReply<bool> Trigger(ResourceTrigger trigger)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (trigger == ResourceTrigger.Initialize)
|
if (trigger == ResourceTrigger.Initialize)
|
||||||
{
|
{
|
||||||
|
|
||||||
var collectionName = Instance.Attributes["Collection"] as string ?? "resources";
|
var collectionName = Collection ?? "resources";
|
||||||
var dbName = Instance.Attributes["Database"] as string ?? "Esyur";
|
var dbName = Database ?? "Esyur";
|
||||||
client = new MongoClient(Instance.Attributes["Connection"] as string ?? "mongodb://localhost");
|
client = new MongoClient(Connection ?? "mongodb://localhost");
|
||||||
database = client.GetDatabase(dbName);
|
database = client.GetDatabase(dbName);
|
||||||
|
|
||||||
resourcesCollection = this.database.GetCollection<BsonDocument>(collectionName);
|
resourcesCollection = this.database.GetCollection<BsonDocument>(collectionName);
|
||||||
@ -568,7 +594,7 @@ namespace Esyur.Stores.MongoDB
|
|||||||
//foreach (IResource c in resource.Instance.Children)
|
//foreach (IResource c in resource.Instance.Children)
|
||||||
// children.Add(c.Instance.Link);
|
// children.Add(c.Instance.Link);
|
||||||
|
|
||||||
var plist = resource.Instance.Attributes["parents"] as string[];
|
var plist = resource.Instance.Variables["parents"] as string[];
|
||||||
|
|
||||||
foreach (var link in plist)// Parents)
|
foreach (var link in plist)// Parents)
|
||||||
parents.Add(link);
|
parents.Add(link);
|
||||||
@ -605,7 +631,7 @@ namespace Esyur.Stores.MongoDB
|
|||||||
{ "attributes", attrsDoc },
|
{ "attributes", attrsDoc },
|
||||||
{ "classname", type.FullName + "," + type.GetTypeInfo().Assembly.GetName().Name },
|
{ "classname", type.FullName + "," + type.GetTypeInfo().Assembly.GetName().Name },
|
||||||
{ "name", resource.Instance.Name },
|
{ "name", resource.Instance.Name },
|
||||||
{ "_id", new BsonObjectId(new ObjectId(resource.Instance.Attributes["objectId"].ToString())) },
|
{ "_id", new BsonObjectId(new ObjectId(resource.Instance.Variables["objectId"].ToString())) },
|
||||||
{"values", values }
|
{"values", values }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -627,7 +653,7 @@ namespace Esyur.Stores.MongoDB
|
|||||||
|
|
||||||
public AsyncReply<PropertyValue[]> GetPropertyRecordByAge(IResource resource, string propertyName, ulong fromAge, ulong toAge)
|
public AsyncReply<PropertyValue[]> GetPropertyRecordByAge(IResource resource, string propertyName, ulong fromAge, ulong toAge)
|
||||||
{
|
{
|
||||||
var objectId = resource.Instance.Attributes["objectId"].ToString();
|
var objectId = resource.Instance.Variables["objectId"].ToString();
|
||||||
|
|
||||||
var record = this.database.GetCollection<BsonDocument>("record_" + objectId);
|
var record = this.database.GetCollection<BsonDocument>("record_" + objectId);
|
||||||
var builder = Builders<BsonDocument>.Filter;
|
var builder = Builders<BsonDocument>.Filter;
|
||||||
@ -663,7 +689,7 @@ namespace Esyur.Stores.MongoDB
|
|||||||
|
|
||||||
public AsyncReply<PropertyValue[]> GetPropertyRecordByDate(IResource resource, string propertyName, DateTime fromDate, DateTime toDate)
|
public AsyncReply<PropertyValue[]> GetPropertyRecordByDate(IResource resource, string propertyName, DateTime fromDate, DateTime toDate)
|
||||||
{
|
{
|
||||||
var objectId = resource.Instance.Attributes["objectId"].ToString();
|
var objectId = resource.Instance.Variables["objectId"].ToString();
|
||||||
|
|
||||||
var record = this.database.GetCollection<BsonDocument>("record_" + objectId);
|
var record = this.database.GetCollection<BsonDocument>("record_" + objectId);
|
||||||
var builder = Builders<BsonDocument>.Filter;
|
var builder = Builders<BsonDocument>.Filter;
|
||||||
@ -755,7 +781,7 @@ namespace Esyur.Stores.MongoDB
|
|||||||
if (resource == this)
|
if (resource == this)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
var objectId = resource.Instance.Attributes["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)));
|
||||||
var update = Builders<BsonDocument>.Update
|
var update = Builders<BsonDocument>.Update
|
||||||
@ -802,7 +828,7 @@ namespace Esyur.Stores.MongoDB
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var children = (string[])resource.Instance.Attributes["children"];
|
var children = (string[])resource.Instance.Variables["children"];
|
||||||
|
|
||||||
if (children == null)
|
if (children == null)
|
||||||
{
|
{
|
||||||
@ -833,7 +859,7 @@ namespace Esyur.Stores.MongoDB
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var parents = (string[])resource.Instance.Attributes["parents"];
|
var parents = (string[])resource.Instance.Variables["parents"];
|
||||||
|
|
||||||
if (parents == null)
|
if (parents == null)
|
||||||
{
|
{
|
||||||
@ -862,8 +888,8 @@ namespace Esyur.Stores.MongoDB
|
|||||||
|
|
||||||
public AsyncReply<bool> AddChild(IResource resource, IResource child)
|
public AsyncReply<bool> AddChild(IResource resource, IResource child)
|
||||||
{
|
{
|
||||||
var list = (string[])resource.Instance.Attributes["children"];
|
var list = (string[])resource.Instance.Variables["children"];
|
||||||
resource.Instance.Attributes["children"] = list.Concat(new string[] { child.Instance.Link }).ToArray();
|
resource.Instance.Variables["children"] = list.Concat(new string[] { child.Instance.Link }).ToArray();
|
||||||
|
|
||||||
SaveResource(resource);
|
SaveResource(resource);
|
||||||
|
|
||||||
@ -877,8 +903,8 @@ namespace Esyur.Stores.MongoDB
|
|||||||
|
|
||||||
public AsyncReply<bool> AddParent(IResource resource, IResource parent)
|
public AsyncReply<bool> AddParent(IResource resource, IResource parent)
|
||||||
{
|
{
|
||||||
var list = (string[])resource.Instance.Attributes["parents"];
|
var list = (string[])resource.Instance.Variables["parents"];
|
||||||
resource.Instance.Attributes["parents"] = list.Concat(new string[] { parent.Instance.Link }).ToArray();
|
resource.Instance.Variables["parents"] = list.Concat(new string[] { parent.Instance.Link }).ToArray();
|
||||||
|
|
||||||
SaveResource(resource);
|
SaveResource(resource);
|
||||||
|
|
||||||
|
@ -1,4 +1,28 @@
|
|||||||
using Esyur.Core;
|
/*
|
||||||
|
|
||||||
|
Copyright (c) 2020 Ahmed Kh. Zamil
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
using Esyur.Core;
|
||||||
using Esyur.Data;
|
using Esyur.Data;
|
||||||
using Esyur.Proxy;
|
using Esyur.Proxy;
|
||||||
using Esyur.Resource;
|
using Esyur.Resource;
|
||||||
|
@ -1,23 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<TargetFramework>netstandard2.0</TargetFramework>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<Compile Remove="MySqlStore.cs" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<None Include="MySqlStore.cs" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="MySql.Data" Version="8.0.17" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\Esyur\Esyur.csproj" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
@ -1,718 +0,0 @@
|
|||||||
using Esyur.Resource;
|
|
||||||
using System;
|
|
||||||
using Esyur.Core;
|
|
||||||
using Esyur.Data;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Esyur.Resource.Template;
|
|
||||||
using System.Linq;
|
|
||||||
using Esyur.Security.Permissions;
|
|
||||||
using Esyur.Proxy;
|
|
||||||
using MySql.Data.MySqlClient;
|
|
||||||
|
|
||||||
namespace Esyur.Stores.MySql
|
|
||||||
{
|
|
||||||
public class MySqlStore : IStore
|
|
||||||
{
|
|
||||||
public Instance Instance { get; set; }
|
|
||||||
|
|
||||||
public event DestroyedEvent OnDestroy;
|
|
||||||
|
|
||||||
string connectionString;
|
|
||||||
|
|
||||||
|
|
||||||
Dictionary<string, IResource> resources = new Dictionary<string, IResource>();
|
|
||||||
|
|
||||||
|
|
||||||
public int Count
|
|
||||||
{
|
|
||||||
get { return resources.Count; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Destroy()
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public bool Record(IResource resource, string propertyName, object value, ulong age, DateTime date)
|
|
||||||
{
|
|
||||||
var objectId = resource.Instance.Attributes["objectId"].ToString();
|
|
||||||
//var bsonObjectId = new BsonObjectId(new ObjectId(objectId));
|
|
||||||
|
|
||||||
var record = this.database.GetCollection<BsonDocument>("record_" + objectId);
|
|
||||||
|
|
||||||
record.InsertOne(new BsonDocument()
|
|
||||||
{
|
|
||||||
{"property", propertyName}, {"age", BsonValue.Create(age) }, {"date", date}, {"value", Compose(value) }
|
|
||||||
});
|
|
||||||
|
|
||||||
//var col = this.database.GetCollection<BsonDocument>(collectionName);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var filter = Builders<BsonDocument>.Filter.Eq("_id", new BsonObjectId(new ObjectId(objectId)));
|
|
||||||
var update = Builders<BsonDocument>.Update
|
|
||||||
.Set("values." + propertyName, new BsonDocument { { "age", BsonValue.Create(age) },
|
|
||||||
{ "modification", date },
|
|
||||||
{ "value", Compose(value) } });
|
|
||||||
resourcesCollection.UpdateOne(filter, update);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Remove(IResource resource)
|
|
||||||
{
|
|
||||||
var objectId = resource.Instance.Attributes["objectId"].ToString();
|
|
||||||
var filter = Builders<BsonDocument>.Filter.Eq("_id", new BsonObjectId(new ObjectId(objectId)));
|
|
||||||
|
|
||||||
this.database.DropCollection("record_" + objectId);
|
|
||||||
resourcesCollection.DeleteOne(filter);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
AsyncReply<IResource> Fetch(string id)
|
|
||||||
{
|
|
||||||
|
|
||||||
MySqlHelper.
|
|
||||||
|
|
||||||
var filter = Builders<BsonDocument>.Filter.Eq("_id", new BsonObjectId(new ObjectId(id)));
|
|
||||||
var list = resourcesCollection.Find(filter).ToList();
|
|
||||||
if (list.Count == 0)
|
|
||||||
return new AsyncReply<IResource>(null);
|
|
||||||
var document = list[0];
|
|
||||||
|
|
||||||
var type = Type.GetType(document["classname"].AsString);
|
|
||||||
|
|
||||||
if (type == null)
|
|
||||||
return new AsyncReply<IResource>(null);
|
|
||||||
|
|
||||||
IResource resource = (IResource)Activator.CreateInstance(ResourceProxy.GetProxy(type));
|
|
||||||
resources.Add(document["_id"].AsObjectId.ToString(), resource);
|
|
||||||
|
|
||||||
Warehouse.Put(resource, document["name"].AsString, this);
|
|
||||||
|
|
||||||
|
|
||||||
var parents = document["parents"].AsBsonArray;
|
|
||||||
var children = document["children"].AsBsonArray;
|
|
||||||
//var managers = document["managers"].AsBsonArray;
|
|
||||||
|
|
||||||
var attributes = Parse(document["attributes"]).Then(x => {
|
|
||||||
resource.Instance.SetAttributes(x as Structure);
|
|
||||||
});
|
|
||||||
|
|
||||||
var bag = new AsyncBag<object>();
|
|
||||||
|
|
||||||
foreach (var p in parents)
|
|
||||||
{
|
|
||||||
var ap = Warehouse.Get(p.AsString);
|
|
||||||
bag.Add(ap);
|
|
||||||
ap.Then((x) =>
|
|
||||||
{
|
|
||||||
if (!resource.Instance.Parents.Contains(x))
|
|
||||||
resource.Instance.Parents.Add(x);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var c in children)
|
|
||||||
{
|
|
||||||
|
|
||||||
var ac = Warehouse.Get(c.AsString);
|
|
||||||
bag.Add(ac);
|
|
||||||
ac.Then((x) =>
|
|
||||||
{
|
|
||||||
if (!resource.Instance.Children.Contains(x))
|
|
||||||
resource.Instance.Children.Add(x);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply store managers
|
|
||||||
foreach (var m in this.Instance.Managers)
|
|
||||||
resource.Instance.Managers.Add(m);
|
|
||||||
|
|
||||||
/*
|
|
||||||
// load managers
|
|
||||||
foreach(var m in managers)
|
|
||||||
{
|
|
||||||
IPermissionsManager pm = (IPermissionsManager)Activator.CreateInstance(Type.GetType(m["classname"].AsString));
|
|
||||||
var sr = Parse(m["settings"]);
|
|
||||||
bag.Add(sr);
|
|
||||||
sr.Then((x) =>
|
|
||||||
{
|
|
||||||
pm.Initialize((Structure)x, resource);
|
|
||||||
resource.Instance.Managers.Add(pm);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Load values
|
|
||||||
var values = document["values"].AsBsonDocument;
|
|
||||||
|
|
||||||
|
|
||||||
foreach (var v in values)
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
var valueInfo = v.Value as BsonDocument;
|
|
||||||
|
|
||||||
var av = Parse(valueInfo["value"]);
|
|
||||||
bag.Add(av);
|
|
||||||
av.Then((x) =>
|
|
||||||
{
|
|
||||||
resource.Instance.LoadProperty(v.Name, (ulong)valueInfo["age"].AsInt64, valueInfo["modification"].ToUniversalTime(), x);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
bag.Seal();
|
|
||||||
|
|
||||||
var rt = new AsyncReply<IResource>();
|
|
||||||
|
|
||||||
bag.Then((x) =>
|
|
||||||
{
|
|
||||||
rt.Trigger(resource);
|
|
||||||
});
|
|
||||||
|
|
||||||
return rt;
|
|
||||||
}
|
|
||||||
|
|
||||||
IAsyncReply<object> Parse(BsonValue value)
|
|
||||||
{
|
|
||||||
if (value.BsonType == BsonType.Document)
|
|
||||||
{
|
|
||||||
var doc = value.AsBsonDocument;
|
|
||||||
if (doc["type"] == 0)
|
|
||||||
{
|
|
||||||
return Warehouse.Get(doc["link"].AsString);
|
|
||||||
} // structure
|
|
||||||
else if (doc["type"] == 1)
|
|
||||||
{
|
|
||||||
var bag = new AsyncBag<object>();
|
|
||||||
var rt = new AsyncReply<Structure>();
|
|
||||||
|
|
||||||
var bs = (BsonDocument)doc["values"].AsBsonDocument;
|
|
||||||
var s = new Structure();
|
|
||||||
|
|
||||||
foreach (var v in bs)
|
|
||||||
bag.Add(Parse(v.Value));
|
|
||||||
|
|
||||||
bag.Seal();
|
|
||||||
bag.Then((x) =>
|
|
||||||
{
|
|
||||||
for (var i = 0; i < x.Length; i++)
|
|
||||||
s[bs.GetElement(i).Name] = x[i];
|
|
||||||
|
|
||||||
rt.Trigger(s);
|
|
||||||
});
|
|
||||||
|
|
||||||
return rt;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return new AsyncReply<object>(null);
|
|
||||||
}
|
|
||||||
else if (value.BsonType == BsonType.Array)
|
|
||||||
{
|
|
||||||
var array = value.AsBsonArray;
|
|
||||||
var bag = new AsyncBag<object>();
|
|
||||||
|
|
||||||
foreach (var v in array)
|
|
||||||
bag.Add(Parse(v));
|
|
||||||
|
|
||||||
bag.Seal();
|
|
||||||
|
|
||||||
return bag;
|
|
||||||
}
|
|
||||||
else if (value.BsonType == BsonType.DateTime)
|
|
||||||
{
|
|
||||||
return new AsyncReply<object>(value.ToUniversalTime());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
|
|
||||||
return new AsyncReply<object>(value.RawValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public AsyncReply<IResource> Get(string path)
|
|
||||||
{
|
|
||||||
var p = path.Split('/');
|
|
||||||
if (p.Length == 2)
|
|
||||||
if (p[0] == "id")
|
|
||||||
{
|
|
||||||
// load from Id
|
|
||||||
|
|
||||||
if (resources.ContainsKey(p[1]))
|
|
||||||
return new AsyncReply<IResource>(resources[p[1]]);
|
|
||||||
else
|
|
||||||
return Fetch(p[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new AsyncReply<IResource>(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Link(IResource resource)
|
|
||||||
{
|
|
||||||
return this.Instance.Name + "/id/" + (string)resource.Instance.Attributes["objectId"];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
string MakeTable(Type type)
|
|
||||||
{
|
|
||||||
var props = type.GetTypeInfo().GetProperties();
|
|
||||||
|
|
||||||
|
|
||||||
foreach(var p in props)
|
|
||||||
{
|
|
||||||
var rp = p.GetCustomAttribute<ResourceProperty>();
|
|
||||||
if (rp == null)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Put(IResource resource)
|
|
||||||
{
|
|
||||||
|
|
||||||
var attrs = resource.Instance.GetAttributes();
|
|
||||||
|
|
||||||
foreach (var kv in resources)
|
|
||||||
if (kv.Value == resource)
|
|
||||||
{
|
|
||||||
resource.Instance.Attributes.Add("objectId", kv.Key);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
var type = ResourceProxy.GetBaseType(resource);
|
|
||||||
|
|
||||||
// insert the document
|
|
||||||
var document = new BsonDocument
|
|
||||||
{
|
|
||||||
{ "classname", type.FullName + "," + type.GetTypeInfo().Assembly.GetName().Name },
|
|
||||||
{ "name", resource.Instance.Name },
|
|
||||||
};
|
|
||||||
|
|
||||||
resourcesCollection.InsertOne(document);
|
|
||||||
resource.Instance.Attributes["objectId"] = document["_id"].ToString();
|
|
||||||
|
|
||||||
|
|
||||||
// now update the document
|
|
||||||
// * insert first to get the object id, update values, attributes, children and parents after in case the same resource has a property references self
|
|
||||||
|
|
||||||
var parents = new BsonArray();
|
|
||||||
var children = new BsonArray();
|
|
||||||
|
|
||||||
var template = resource.Instance.Template;
|
|
||||||
|
|
||||||
foreach (IResource c in resource.Instance.Children)
|
|
||||||
children.Add(c.Instance.Link);
|
|
||||||
|
|
||||||
foreach (IResource p in resource.Instance.Parents)
|
|
||||||
parents.Add(p.Instance.Link);
|
|
||||||
|
|
||||||
|
|
||||||
var attrsDoc = ComposeStructure(attrs);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var values = new BsonDocument();
|
|
||||||
|
|
||||||
foreach (var pt in template.Properties)
|
|
||||||
{
|
|
||||||
var rt = pt.Info.GetValue(resource, null);
|
|
||||||
|
|
||||||
values.Add(pt.Name,
|
|
||||||
new BsonDocument { { "age", BsonValue.Create(resource.Instance.GetAge(pt.Index)) },
|
|
||||||
{ "modification", resource.Instance.GetModificationDate(pt.Index) },
|
|
||||||
{ "value", Compose(rt) } });
|
|
||||||
}
|
|
||||||
|
|
||||||
// var filter = Builders<BsonDocument>.Filter.Eq("_id", document["_id"]);
|
|
||||||
// var update = Builders<BsonDocument>.Update
|
|
||||||
// .Set("values", values);
|
|
||||||
// col.UpdateOne(filter, update);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
var document = new BsonDocument
|
|
||||||
{
|
|
||||||
{ "parents", parents },
|
|
||||||
{ "children", children },
|
|
||||||
{ "attributes", attrsDoc },
|
|
||||||
{ "classname", resource.GetType().FullName + "," + resource.GetType().GetTypeInfo().Assembly.GetName().Name },
|
|
||||||
{ "name", resource.Instance.Name },
|
|
||||||
{ "values", values }
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
||||||
var filter = Builders<BsonDocument>.Filter.Eq("_id", document["_id"]);
|
|
||||||
var update = Builders<BsonDocument>.Update
|
|
||||||
.Set("values", values).Set("parents", parents).Set("children", children).Set("attributes", attrsDoc);
|
|
||||||
resourcesCollection.UpdateOne(filter, update);
|
|
||||||
|
|
||||||
|
|
||||||
//resource.Instance.Attributes["objectId"] = document["_id"].ToString();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public BsonDocument ComposeStructure(Structure value)
|
|
||||||
{
|
|
||||||
var rt = new BsonDocument { { "type", 1 } };
|
|
||||||
|
|
||||||
var values = new BsonDocument();
|
|
||||||
foreach (var i in value)
|
|
||||||
values.Add(i.Key, Compose(i.Value));
|
|
||||||
|
|
||||||
rt.Add("values", values);
|
|
||||||
return rt;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BsonArray ComposeVarArray(object[] array)
|
|
||||||
{
|
|
||||||
var rt = new BsonArray();
|
|
||||||
|
|
||||||
for (var i = 0; i < array.Length; i++)
|
|
||||||
rt.Add(Compose(array[i]));
|
|
||||||
|
|
||||||
return rt;
|
|
||||||
}
|
|
||||||
|
|
||||||
BsonArray ComposeStructureArray(Structure[] structures)
|
|
||||||
{
|
|
||||||
var rt = new BsonArray();
|
|
||||||
|
|
||||||
if (structures == null || structures?.Length == 0)
|
|
||||||
return rt;
|
|
||||||
|
|
||||||
foreach (var s in structures)
|
|
||||||
rt.Add(ComposeStructure(s));
|
|
||||||
|
|
||||||
return rt;
|
|
||||||
}
|
|
||||||
|
|
||||||
BsonArray ComposeResourceArray(IResource[] array)
|
|
||||||
{
|
|
||||||
var rt = new BsonArray();
|
|
||||||
foreach (var r in array)
|
|
||||||
{
|
|
||||||
rt.Add(new BsonDocument { { "type", 0 }, { "link", r.Instance.Link } });
|
|
||||||
|
|
||||||
//if (r.Instance.Attributes.ContainsKey("objectId"))
|
|
||||||
|
|
||||||
//rt.Add(new BsonObjectId(new ObjectId((string)r.Instance.Attributes["objectId"])));
|
|
||||||
}
|
|
||||||
|
|
||||||
return rt;
|
|
||||||
}
|
|
||||||
|
|
||||||
private BsonValue Compose(object value)
|
|
||||||
{
|
|
||||||
var type = Codec.GetDataType(value, null);
|
|
||||||
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
case DataType.Void:
|
|
||||||
// nothing to do;
|
|
||||||
return BsonNull.Value;
|
|
||||||
|
|
||||||
case DataType.String:
|
|
||||||
return new BsonString((string)value);
|
|
||||||
|
|
||||||
case DataType.Resource:
|
|
||||||
case DataType.DistributedResource:
|
|
||||||
|
|
||||||
return new BsonDocument { { "type", 0 }, { "link", (value as IResource).Instance.Link } };
|
|
||||||
|
|
||||||
//return new BsonObjectId(new ObjectId((string)(value as IResource).Instance.Attributes["objectId"]));
|
|
||||||
|
|
||||||
case DataType.Structure:
|
|
||||||
return ComposeStructure((Structure)value);
|
|
||||||
|
|
||||||
case DataType.VarArray:
|
|
||||||
return ComposeVarArray((object[])value);
|
|
||||||
|
|
||||||
case DataType.ResourceArray:
|
|
||||||
if (value is IResource[])
|
|
||||||
return ComposeResourceArray((IResource[])value);
|
|
||||||
else
|
|
||||||
return ComposeResourceArray((IResource[])DC.CastConvert(value, typeof(IResource[])));
|
|
||||||
|
|
||||||
|
|
||||||
case DataType.StructureArray:
|
|
||||||
return ComposeStructureArray((Structure[])value);
|
|
||||||
|
|
||||||
|
|
||||||
default:
|
|
||||||
return BsonValue.Create(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public AsyncReply<IResource> Retrieve(uint iid)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public AsyncReply<bool> Trigger(ResourceTrigger trigger)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (trigger == ResourceTrigger.Initialize)
|
|
||||||
{
|
|
||||||
|
|
||||||
var collectionName = Instance.Attributes["Collection"] as string ?? "resources";
|
|
||||||
var dbName = Instance.Attributes["Database"] as string ?? "Esyur";
|
|
||||||
client = new MongoClient(Instance.Attributes["Connection"] as string ?? "mongodb://localhost");
|
|
||||||
database = client.GetDatabase(dbName);
|
|
||||||
|
|
||||||
resourcesCollection = this.database.GetCollection<BsonDocument>(collectionName);
|
|
||||||
|
|
||||||
// return new AsyncReply<bool>(true);
|
|
||||||
|
|
||||||
var filter = new BsonDocument();
|
|
||||||
|
|
||||||
var list = resourcesCollection.Find(filter).ToList();
|
|
||||||
|
|
||||||
|
|
||||||
// if (list.Count == 0)
|
|
||||||
// return new AsyncBag<IResource>(new IResource[0]);
|
|
||||||
|
|
||||||
var bag = new AsyncBag<IResource>();
|
|
||||||
|
|
||||||
for (var i = 0; i < list.Count; i++)
|
|
||||||
{
|
|
||||||
//Console.WriteLine("Loading {0}/{1}", i, list.Count);
|
|
||||||
bag.Add(Get("id/" + list[i]["_id"].AsObjectId.ToString()));
|
|
||||||
}
|
|
||||||
|
|
||||||
bag.Seal();
|
|
||||||
|
|
||||||
var rt = new AsyncReply<bool>();
|
|
||||||
|
|
||||||
bag.Then((x) => { rt.Trigger(true); });
|
|
||||||
|
|
||||||
return rt;
|
|
||||||
}
|
|
||||||
else if (trigger == ResourceTrigger.Terminate)
|
|
||||||
{
|
|
||||||
// save all resources
|
|
||||||
foreach (var resource in resources.Values)
|
|
||||||
SaveResource(resource);
|
|
||||||
|
|
||||||
return new AsyncReply<bool>(true);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return new AsyncReply<bool>(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void SaveResource(IResource resource)
|
|
||||||
{
|
|
||||||
var attrs = resource.Instance.GetAttributes();
|
|
||||||
|
|
||||||
var parents = new BsonArray();
|
|
||||||
var children = new BsonArray();
|
|
||||||
var template = resource.Instance.Template;
|
|
||||||
|
|
||||||
foreach (IResource c in resource.Instance.Children)
|
|
||||||
children.Add(c.Instance.Link);
|
|
||||||
|
|
||||||
foreach (IResource p in resource.Instance.Parents)
|
|
||||||
parents.Add(p.Instance.Link);
|
|
||||||
|
|
||||||
|
|
||||||
var values = new BsonDocument();
|
|
||||||
|
|
||||||
foreach (var pt in template.Properties)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
#if NETSTANDARD1_5
|
|
||||||
var pi = resource.GetType().GetTypeInfo().GetProperty(pt.Name);
|
|
||||||
#else
|
|
||||||
var pi = resource.GetType().GetProperty(pt.Name);
|
|
||||||
#endif
|
|
||||||
*/
|
|
||||||
var rt = pt.Info.GetValue(resource, null);
|
|
||||||
|
|
||||||
values.Add(pt.Name,
|
|
||||||
new BsonDocument { { "age", BsonValue.Create(resource.Instance.GetAge(pt.Index)) },
|
|
||||||
{ "modification", resource.Instance.GetModificationDate(pt.Index) },
|
|
||||||
{ "value", Compose(rt) } });
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
var attrsDoc = ComposeStructure(attrs);
|
|
||||||
|
|
||||||
var type = ResourceProxy.GetBaseType(resource);
|
|
||||||
|
|
||||||
var document = new BsonDocument
|
|
||||||
{
|
|
||||||
{ "parents", parents },
|
|
||||||
{ "children", children },
|
|
||||||
{"attributes", attrsDoc },
|
|
||||||
{ "classname", type.FullName + "," + type.GetTypeInfo().Assembly.GetName().Name },
|
|
||||||
{ "name", resource.Instance.Name },
|
|
||||||
{ "_id", new BsonObjectId(new ObjectId(resource.Instance.Attributes["objectId"].ToString())) },
|
|
||||||
{"values", values }
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var filter = Builders<BsonDocument>.Filter.Eq("_id", document["_id"]);
|
|
||||||
|
|
||||||
/*
|
|
||||||
var update = Builders<BsonDocument>.Update
|
|
||||||
.Set("values", values);
|
|
||||||
|
|
||||||
var update = Builders<BsonDocument>.Update.Set("values", values).Set("parents", parents;
|
|
||||||
col.UpdateOne(filter, update);
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
resourcesCollection.ReplaceOne(filter, document);
|
|
||||||
}
|
|
||||||
|
|
||||||
public AsyncReply<PropertyValue[]> GetPropertyRecordByAge(IResource resource, string propertyName, ulong fromAge, ulong toAge)
|
|
||||||
{
|
|
||||||
var objectId = resource.Instance.Attributes["objectId"].ToString();
|
|
||||||
|
|
||||||
var record = this.database.GetCollection<BsonDocument>("record_" + objectId);
|
|
||||||
var builder = Builders<BsonDocument>.Filter;
|
|
||||||
|
|
||||||
var filter = builder.Gte("age", fromAge) & builder.Lte("age", toAge) & builder.Eq("property", propertyName);
|
|
||||||
|
|
||||||
var reply = new AsyncReply<PropertyValue[]>();
|
|
||||||
|
|
||||||
record.FindAsync(filter).ContinueWith((x) =>
|
|
||||||
{
|
|
||||||
var values = ((Task<IAsyncCursor<BsonDocument>>)x).Result.ToList();
|
|
||||||
|
|
||||||
var bag = new AsyncBag<object>();
|
|
||||||
|
|
||||||
foreach (var v in values)
|
|
||||||
bag.Add(Parse(v["value"]));
|
|
||||||
|
|
||||||
bag.Seal();
|
|
||||||
|
|
||||||
bag.Then((results) =>
|
|
||||||
{
|
|
||||||
var list = new List<PropertyValue>();
|
|
||||||
for (var i = 0; i < results.Length; i++)
|
|
||||||
list.Add(new PropertyValue(results[i], (ulong)values[i]["age"].AsInt64, values[i]["date"].ToUniversalTime()));
|
|
||||||
|
|
||||||
reply.Trigger(list.ToArray());
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
return reply;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AsyncReply<PropertyValue[]> GetPropertyRecordByDate(IResource resource, string propertyName, DateTime fromDate, DateTime toDate)
|
|
||||||
{
|
|
||||||
var objectId = resource.Instance.Attributes["objectId"].ToString();
|
|
||||||
|
|
||||||
var record = this.database.GetCollection<BsonDocument>("record_" + objectId);
|
|
||||||
var builder = Builders<BsonDocument>.Filter;
|
|
||||||
|
|
||||||
var filter = builder.Gte("date", fromDate) & builder.Lte("date", toDate) & builder.Eq("property", propertyName);
|
|
||||||
|
|
||||||
var reply = new AsyncReply<PropertyValue[]>();
|
|
||||||
|
|
||||||
record.FindAsync(filter).ContinueWith((x) =>
|
|
||||||
{
|
|
||||||
var values = ((Task<IAsyncCursor<BsonDocument>>)x).Result.ToList();
|
|
||||||
|
|
||||||
var bag = new AsyncBag<object>();
|
|
||||||
|
|
||||||
foreach (var v in values)
|
|
||||||
bag.Add(Parse(v["value"]));
|
|
||||||
|
|
||||||
bag.Seal();
|
|
||||||
|
|
||||||
bag.Then((results) =>
|
|
||||||
{
|
|
||||||
var list = new List<PropertyValue>();
|
|
||||||
for (var i = 0; i < results.Length; i++)
|
|
||||||
list.Add(new PropertyValue(results[i], (ulong)values[i]["age"].AsInt64, values[i]["date"].ToUniversalTime()));
|
|
||||||
|
|
||||||
reply.Trigger(list.ToArray());
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
return reply;
|
|
||||||
}
|
|
||||||
|
|
||||||
AsyncReply<KeyList<PropertyTemplate, PropertyValue[]>> GetRecordByAge(IResource resource, ulong fromAge, ulong toAge)
|
|
||||||
{
|
|
||||||
var properties = resource.Instance.Template.Properties.Where(x => x.Storage == StorageMode.Recordable).ToList();
|
|
||||||
|
|
||||||
var reply = new AsyncReply<KeyList<PropertyTemplate, PropertyValue[]>>();
|
|
||||||
|
|
||||||
AsyncBag<PropertyValue[]> bag = new AsyncBag<PropertyValue[]>();
|
|
||||||
|
|
||||||
foreach (var p in properties)
|
|
||||||
bag.Add(GetPropertyRecordByAge(resource, p.Name, fromAge, toAge));
|
|
||||||
|
|
||||||
bag.Seal();
|
|
||||||
|
|
||||||
bag.Then(x =>
|
|
||||||
{
|
|
||||||
var list = new KeyList<PropertyTemplate, PropertyValue[]>();
|
|
||||||
|
|
||||||
for (var i = 0; i < x.Length; i++)
|
|
||||||
list.Add(properties[i], x[i]);
|
|
||||||
|
|
||||||
reply.Trigger(list);
|
|
||||||
});
|
|
||||||
|
|
||||||
return reply;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AsyncReply<KeyList<PropertyTemplate, PropertyValue[]>> GetRecord(IResource resource, DateTime fromDate, DateTime toDate)
|
|
||||||
{
|
|
||||||
var properties = resource.Instance.Template.Properties.Where(x => x.Storage == StorageMode.Recordable).ToList();
|
|
||||||
|
|
||||||
var reply = new AsyncReply<KeyList<PropertyTemplate, PropertyValue[]>>();
|
|
||||||
|
|
||||||
AsyncBag<PropertyValue[]> bag = new AsyncBag<PropertyValue[]>();
|
|
||||||
|
|
||||||
foreach (var p in properties)
|
|
||||||
bag.Add(GetPropertyRecordByDate(resource, p.Name, fromDate, toDate));
|
|
||||||
|
|
||||||
bag.Seal();
|
|
||||||
|
|
||||||
bag.Then(x =>
|
|
||||||
{
|
|
||||||
var list = new KeyList<PropertyTemplate, PropertyValue[]>();
|
|
||||||
|
|
||||||
for (var i = 0; i < x.Length; i++)
|
|
||||||
list.Add(properties[i], x[i]);
|
|
||||||
|
|
||||||
reply.Trigger(list);
|
|
||||||
});
|
|
||||||
|
|
||||||
return reply;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Modify(IResource resource, string propertyName, object value, ulong age, DateTime dateTime)
|
|
||||||
{
|
|
||||||
|
|
||||||
var sql = $"UPDATE `{resource.Instance.Template.ClassName}` SET `{propertyName}` = @value, `{propertyName}_age` = @age, `{propertyName}_date` = @date WHERE `_id` = @id";
|
|
||||||
|
|
||||||
MySqlHelper.ExecuteNonQuery(connectionString, sql,
|
|
||||||
new MySqlParameter("@value", value),
|
|
||||||
new MySqlParameter("@age", age),
|
|
||||||
new MySqlParameter("@date", dateTime),
|
|
||||||
new MySqlParameter("@id", resource.Instance.Attributes["objectId"]));
|
|
||||||
|
|
||||||
return true;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
10
Esyur.sln
10
Esyur.sln
@ -6,7 +6,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Esyur", "Esyur\Esyur.csproj
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Esyur.Stores.MongoDB", "Esyur.Stores.MongoDB\Esyur.Stores.MongoDB.csproj", "{4C90D4B3-8EA2-48AE-A2F9-2B722FCEF9C4}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Esyur.Stores.MongoDB", "Esyur.Stores.MongoDB\Esyur.Stores.MongoDB.csproj", "{4C90D4B3-8EA2-48AE-A2F9-2B722FCEF9C4}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Esyur.Stores.MySql", "Esyur.Stores.MySql\Esyur.Stores.MySql.csproj", "{7BD6148A-3335-411C-9189-3803B1824264}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Esyur.Stores.EntityCore", "Esyur.Stores.EntityCore\Esyur.Stores.EntityCore.csproj", "{53DE5A30-CFA9-4DE7-A840-77CFF519D31B}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
@ -22,10 +22,10 @@ Global
|
|||||||
{4C90D4B3-8EA2-48AE-A2F9-2B722FCEF9C4}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{4C90D4B3-8EA2-48AE-A2F9-2B722FCEF9C4}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{4C90D4B3-8EA2-48AE-A2F9-2B722FCEF9C4}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{4C90D4B3-8EA2-48AE-A2F9-2B722FCEF9C4}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{4C90D4B3-8EA2-48AE-A2F9-2B722FCEF9C4}.Release|Any CPU.Build.0 = Release|Any CPU
|
{4C90D4B3-8EA2-48AE-A2F9-2B722FCEF9C4}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{7BD6148A-3335-411C-9189-3803B1824264}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{53DE5A30-CFA9-4DE7-A840-77CFF519D31B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{7BD6148A-3335-411C-9189-3803B1824264}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{53DE5A30-CFA9-4DE7-A840-77CFF519D31B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{7BD6148A-3335-411C-9189-3803B1824264}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{53DE5A30-CFA9-4DE7-A840-77CFF519D31B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{7BD6148A-3335-411C-9189-3803B1824264}.Release|Any CPU.Build.0 = Release|Any CPU
|
{53DE5A30-CFA9-4DE7-A840-77CFF519D31B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
@ -35,6 +35,7 @@ using System.Linq;
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using Esyur.Resource.Template;
|
using Esyur.Resource.Template;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Collections;
|
||||||
|
|
||||||
namespace Esyur.Data
|
namespace Esyur.Data
|
||||||
{
|
{
|
||||||
@ -1172,6 +1173,8 @@ namespace Esyur.Data
|
|||||||
value = (value as IUserType).Get();
|
value = (value as IUserType).Get();
|
||||||
|
|
||||||
|
|
||||||
|
// value = (List<>)value.ToArray();
|
||||||
|
|
||||||
if (value is Func<DistributedConnection, object>)
|
if (value is Func<DistributedConnection, object>)
|
||||||
//if (connection != null)
|
//if (connection != null)
|
||||||
value = (value as Func<DistributedConnection, object>)(connection);
|
value = (value as Func<DistributedConnection, object>)(connection);
|
||||||
@ -1189,7 +1192,21 @@ namespace Esyur.Data
|
|||||||
|
|
||||||
var t = value.GetType();
|
var t = value.GetType();
|
||||||
|
|
||||||
|
// Convert ICollection<T> to Array<T>
|
||||||
|
if (!t.IsArray && typeof(ICollection).IsAssignableFrom(t))
|
||||||
|
{
|
||||||
|
var col = t.GetInterfaces().Where(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(ICollection<>));
|
||||||
|
if (col.Count() == 0)
|
||||||
|
return (DataType.Void, null);
|
||||||
|
|
||||||
|
var elementType = col.First().GetGenericArguments()[0];
|
||||||
|
|
||||||
|
value = new ArrayList((ICollection)value).ToArray(elementType);
|
||||||
|
t = value.GetType();
|
||||||
|
}
|
||||||
|
|
||||||
var isArray = t.IsArray;
|
var isArray = t.IsArray;
|
||||||
|
|
||||||
if (isArray)
|
if (isArray)
|
||||||
t = t.GetElementType();
|
t = t.GetElementType();
|
||||||
|
|
||||||
|
@ -260,7 +260,7 @@ namespace Esyur.Net.HTTP
|
|||||||
if (resource.Execute(sender))
|
if (resource.Execute(sender))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
sender.Response.Number = HTTPResponsePacket.ResponseCode.HTTP_SERVERERROR;
|
||||||
sender.Send("Bad Request");
|
sender.Send("Bad Request");
|
||||||
sender.Close();
|
sender.Close();
|
||||||
}
|
}
|
||||||
|
@ -800,6 +800,15 @@ namespace Esyur.Net.IIP
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[ResourceAttribute]
|
||||||
|
public string Username { get; set; }
|
||||||
|
|
||||||
|
[ResourceAttribute]
|
||||||
|
public string Password { get; set; }
|
||||||
|
|
||||||
|
[ResourceAttribute]
|
||||||
|
public string Domain { get; set; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Resource interface
|
/// Resource interface
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -809,8 +818,8 @@ namespace Esyur.Net.IIP
|
|||||||
{
|
{
|
||||||
if (trigger == ResourceTrigger.Open)
|
if (trigger == ResourceTrigger.Open)
|
||||||
{
|
{
|
||||||
if (Instance.Attributes.ContainsKey("username")
|
if (Username != null // Instance.Attributes.ContainsKey("username")
|
||||||
&& Instance.Attributes.ContainsKey("password"))
|
&& Password != null)/// Instance.Attributes.ContainsKey("password"))
|
||||||
{
|
{
|
||||||
// assign domain from hostname if not provided
|
// assign domain from hostname if not provided
|
||||||
|
|
||||||
@ -818,16 +827,16 @@ namespace Esyur.Net.IIP
|
|||||||
|
|
||||||
var address = host[0];
|
var address = host[0];
|
||||||
var port = ushort.Parse(host[1]);
|
var port = ushort.Parse(host[1]);
|
||||||
var username = Instance.Attributes["username"].ToString();
|
var username = Username;// Instance.Attributes["username"].ToString();
|
||||||
|
|
||||||
var domain = Instance.Attributes.ContainsKey("domain") ? Instance.Attributes["domain"].ToString() : address;
|
var domain = Domain != null ? Domain : address;// Instance.Attributes.ContainsKey("domain") ? Instance.Attributes["domain"].ToString() : address;
|
||||||
|
|
||||||
session = new Session(new ClientAuthentication()
|
session = new Session(new ClientAuthentication()
|
||||||
, new HostAuthentication());
|
, new HostAuthentication());
|
||||||
|
|
||||||
session.LocalAuthentication.Domain = domain;
|
session.LocalAuthentication.Domain = domain;
|
||||||
session.LocalAuthentication.Username = username;
|
session.LocalAuthentication.Username = username;
|
||||||
localPassword = DC.ToBytes(Instance.Attributes["password"].ToString());
|
localPassword = DC.ToBytes(Password);// Instance.Attributes["password"].ToString());
|
||||||
|
|
||||||
openReply = new AsyncReply<bool>();
|
openReply = new AsyncReply<bool>();
|
||||||
var sock = new TCPSocket();
|
var sock = new TCPSocket();
|
||||||
|
@ -413,7 +413,7 @@ namespace Esyur.Net.IIP
|
|||||||
{
|
{
|
||||||
Fetch(resourceId).Then(resource =>
|
Fetch(resourceId).Then(resource =>
|
||||||
{
|
{
|
||||||
resource.Instance.Attributes["name"] = name.GetString(0, (uint)name.Length);
|
resource.Instance.Variables["name"] = name.GetString(0, (uint)name.Length);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -451,7 +451,8 @@ namespace Esyur.Net.IIP
|
|||||||
r.Instance.ResourceDestroyed -= Instance_ResourceDestroyed;
|
r.Instance.ResourceDestroyed -= Instance_ResourceDestroyed;
|
||||||
// r.Instance.Children.OnAdd -= Children_OnAdd;
|
// r.Instance.Children.OnAdd -= Children_OnAdd;
|
||||||
// r.Instance.Children.OnRemoved -= Children_OnRemoved;
|
// r.Instance.Children.OnRemoved -= Children_OnRemoved;
|
||||||
r.Instance.Attributes.OnModified -= Attributes_OnModified;
|
|
||||||
|
//r.Instance.Attributes.OnModified -= Attributes_OnModified;
|
||||||
|
|
||||||
// subscribe
|
// subscribe
|
||||||
r.Instance.ResourceEventOccurred += Instance_EventOccurred;
|
r.Instance.ResourceEventOccurred += Instance_EventOccurred;
|
||||||
@ -459,7 +460,8 @@ namespace Esyur.Net.IIP
|
|||||||
r.Instance.ResourceDestroyed += Instance_ResourceDestroyed;
|
r.Instance.ResourceDestroyed += Instance_ResourceDestroyed;
|
||||||
//r.Instance.Children.OnAdd += Children_OnAdd;
|
//r.Instance.Children.OnAdd += Children_OnAdd;
|
||||||
//r.Instance.Children.OnRemoved += Children_OnRemoved;
|
//r.Instance.Children.OnRemoved += Children_OnRemoved;
|
||||||
r.Instance.Attributes.OnModified += Attributes_OnModified;
|
|
||||||
|
//r.Instance.Attributes.OnModified += Attributes_OnModified;
|
||||||
|
|
||||||
// add it to attached resources so GC won't remove it from memory
|
// add it to attached resources so GC won't remove it from memory
|
||||||
attachedResources.Add(r);
|
attachedResources.Add(r);
|
||||||
@ -564,7 +566,8 @@ namespace Esyur.Net.IIP
|
|||||||
r.Instance.ResourceDestroyed -= Instance_ResourceDestroyed;
|
r.Instance.ResourceDestroyed -= Instance_ResourceDestroyed;
|
||||||
//r.Instance.Children.OnAdd -= Children_OnAdd;
|
//r.Instance.Children.OnAdd -= Children_OnAdd;
|
||||||
//r.Instance.Children.OnRemoved -= Children_OnRemoved;
|
//r.Instance.Children.OnRemoved -= Children_OnRemoved;
|
||||||
r.Instance.Attributes.OnModified -= Attributes_OnModified;
|
|
||||||
|
//r.Instance.Attributes.OnModified -= Attributes_OnModified;
|
||||||
|
|
||||||
// subscribe
|
// subscribe
|
||||||
r.Instance.ResourceEventOccurred += Instance_EventOccurred;
|
r.Instance.ResourceEventOccurred += Instance_EventOccurred;
|
||||||
@ -572,7 +575,8 @@ namespace Esyur.Net.IIP
|
|||||||
r.Instance.ResourceDestroyed += Instance_ResourceDestroyed;
|
r.Instance.ResourceDestroyed += Instance_ResourceDestroyed;
|
||||||
//r.Instance.Children.OnAdd += Children_OnAdd;
|
//r.Instance.Children.OnAdd += Children_OnAdd;
|
||||||
//r.Instance.Children.OnRemoved += Children_OnRemoved;
|
//r.Instance.Children.OnRemoved += Children_OnRemoved;
|
||||||
r.Instance.Attributes.OnModified += Attributes_OnModified;
|
|
||||||
|
//r.Instance.Attributes.OnModified += Attributes_OnModified;
|
||||||
|
|
||||||
// reply ok
|
// reply ok
|
||||||
SendReply(IIPPacket.IIPPacketAction.ReattachResource, callback)
|
SendReply(IIPPacket.IIPPacketAction.ReattachResource, callback)
|
||||||
|
@ -406,8 +406,6 @@ namespace Esyur.Net.Sockets
|
|||||||
Console.WriteLine("Level 2 {0}", ex2);
|
Console.WriteLine("Level 2 {0}", ex2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Global.Log("TCPSocket", LogType.Error, ex.ToString());
|
Global.Log("TCPSocket", LogType.Error, ex.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,8 +48,8 @@ namespace Esyur.Proxy
|
|||||||
#if NETSTANDARD
|
#if NETSTANDARD
|
||||||
var typeInfo = type.GetTypeInfo();
|
var typeInfo = type.GetTypeInfo();
|
||||||
|
|
||||||
if (typeInfo.IsSealed)
|
if (typeInfo.IsSealed || typeInfo.IsAbstract)
|
||||||
throw new Exception("Sealed class can't be proxied.");
|
throw new Exception("Sealed/Abastract classes can't be proxied.");
|
||||||
|
|
||||||
var props = from p in typeInfo.GetProperties()
|
var props = from p in typeInfo.GetProperties()
|
||||||
where p.CanWrite && p.GetSetMethod().IsVirtual &&
|
where p.CanWrite && p.GetSetMethod().IsVirtual &&
|
||||||
|
@ -28,12 +28,13 @@ using System.Linq;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using Esyur.Data;
|
using Esyur.Data;
|
||||||
using Esyur.Core;
|
using Esyur.Core;
|
||||||
|
using System.ComponentModel;
|
||||||
|
|
||||||
namespace Esyur.Resource
|
namespace Esyur.Resource
|
||||||
{
|
{
|
||||||
public delegate bool QueryFilter<T>(T value);
|
public delegate bool QueryFilter<T>(T value);
|
||||||
|
|
||||||
public interface IResource : IDestructible
|
public interface IResource : IDestructible///, INotifyPropertyChanged
|
||||||
{
|
{
|
||||||
|
|
||||||
AsyncReply<bool> Trigger(ResourceTrigger trigger);
|
AsyncReply<bool> Trigger(ResourceTrigger trigger);
|
||||||
|
@ -30,6 +30,8 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Esyur.Security.Permissions;
|
||||||
|
using Esyur.Security.Authority;
|
||||||
|
|
||||||
namespace Esyur.Resource
|
namespace Esyur.Resource
|
||||||
{
|
{
|
||||||
@ -43,6 +45,13 @@ namespace Esyur.Resource
|
|||||||
bool Modify(IResource resource, string propertyName, object value, ulong age, DateTime dateTime);
|
bool Modify(IResource resource, string propertyName, object value, ulong age, DateTime dateTime);
|
||||||
bool Remove(IResource resource);
|
bool Remove(IResource resource);
|
||||||
|
|
||||||
|
//bool RemoveAttributes(IResource resource, string[] attributes = null);
|
||||||
|
|
||||||
|
//Structure GetAttributes(IResource resource, string[] attributes = null);
|
||||||
|
|
||||||
|
//bool SetAttributes(IResource resource, Structure attributes, bool clearAttributes = false);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AsyncReply<bool> AddChild(IResource parent, IResource child);
|
AsyncReply<bool> AddChild(IResource parent, IResource child);
|
||||||
AsyncReply<bool> RemoveChild(IResource parent, IResource child);
|
AsyncReply<bool> RemoveChild(IResource parent, IResource child);
|
||||||
|
@ -20,22 +20,14 @@ namespace Esyur.Resource
|
|||||||
{
|
{
|
||||||
string name;
|
string name;
|
||||||
|
|
||||||
//IQueryable<IResource> children;//
|
|
||||||
//AutoList<IResource, Instance> children;// = new AutoList<IResource, Instance>();
|
|
||||||
WeakReference<IResource> resource;
|
WeakReference<IResource> resource;
|
||||||
IStore store;
|
IStore store;
|
||||||
//AutoList<IResource, Instance> parents;// = new AutoList<IResource>();
|
|
||||||
//bool inherit;
|
|
||||||
ResourceTemplate template;
|
ResourceTemplate template;
|
||||||
|
AutoList<IPermissionsManager, Instance> managers;
|
||||||
AutoList<IPermissionsManager, Instance> managers;// = new AutoList<IPermissionManager, Instance>();
|
|
||||||
|
|
||||||
|
|
||||||
public delegate void ResourceModifiedEvent(IResource resource, string propertyName, object newValue);
|
public delegate void ResourceModifiedEvent(IResource resource, string propertyName, object newValue);
|
||||||
//public delegate void ResourceEventOccurredEvent(IResource resource, string eventName, string[] users, DistributedConnection[] connections, object[] args);
|
|
||||||
|
|
||||||
public delegate void ResourceEventOccurredEvent(IResource resource, object issuer, Session[] receivers, string eventName, object[] args);
|
public delegate void ResourceEventOccurredEvent(IResource resource, object issuer, Session[] receivers, string eventName, object[] args);
|
||||||
|
|
||||||
public delegate void ResourceDestroyedEvent(IResource resource);
|
public delegate void ResourceDestroyedEvent(IResource resource);
|
||||||
|
|
||||||
public event ResourceModifiedEvent ResourceModified;
|
public event ResourceModifiedEvent ResourceModified;
|
||||||
@ -44,7 +36,7 @@ namespace Esyur.Resource
|
|||||||
|
|
||||||
bool loading = false;
|
bool loading = false;
|
||||||
|
|
||||||
KeyList<string, object> attributes;
|
//KeyList<string, object> attributes;
|
||||||
|
|
||||||
List<ulong> ages = new List<ulong>();
|
List<ulong> ages = new List<ulong>();
|
||||||
List<DateTime> modificationDates = new List<DateTime>();
|
List<DateTime> modificationDates = new List<DateTime>();
|
||||||
@ -53,17 +45,18 @@ namespace Esyur.Resource
|
|||||||
|
|
||||||
uint id;
|
uint id;
|
||||||
|
|
||||||
|
public KeyList<string, object> Variables { get; } = new KeyList<string, object>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Instance attributes are custom properties associated with the instance, a place to store information by IStore.
|
/// Instance attributes are custom properties associated with the instance, a place to store information by IStore.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public KeyList<string, object> Attributes
|
//public KeyList<string, object> Attributes
|
||||||
{
|
//{
|
||||||
get
|
// get
|
||||||
{
|
// {
|
||||||
return attributes;
|
// return attributes;
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
@ -72,6 +65,19 @@ namespace Esyur.Resource
|
|||||||
|
|
||||||
public bool RemoveAttributes(string[] attributes = null)
|
public bool RemoveAttributes(string[] attributes = null)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/*
|
||||||
|
IResource res;
|
||||||
|
|
||||||
|
if (!resource.TryGetTarget(out res))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return store.RemoveAttributes(res, attributes);
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
if (attributes == null)
|
if (attributes == null)
|
||||||
this.attributes.Clear();
|
this.attributes.Clear();
|
||||||
else
|
else
|
||||||
@ -81,10 +87,31 @@ namespace Esyur.Resource
|
|||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
public Structure GetAttributes(string[] attributes = null)
|
public Structure GetAttributes(string[] attributes = null)
|
||||||
{
|
{
|
||||||
|
// @TODO
|
||||||
|
Structure rt = new Structure();
|
||||||
|
|
||||||
|
if (attributes != null)
|
||||||
|
{
|
||||||
|
for (var i = 0; i < attributes.Length; i++)
|
||||||
|
{
|
||||||
|
var at = template.GetAttributeTemplate(attributes[i]);
|
||||||
|
if (at != null)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rt;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
var st = new Structure();
|
var st = new Structure();
|
||||||
|
|
||||||
if (attributes == null)
|
if (attributes == null)
|
||||||
@ -132,10 +159,31 @@ namespace Esyur.Resource
|
|||||||
}
|
}
|
||||||
|
|
||||||
return st;
|
return st;
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool SetAttributes(Structure attributes, bool clearAttributes = false)
|
public bool SetAttributes(Structure attributes, bool clearAttributes = false)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// @ TODO
|
||||||
|
IResource res;
|
||||||
|
|
||||||
|
if (resource.TryGetTarget(out res))
|
||||||
|
{
|
||||||
|
foreach (var kv in attributes)
|
||||||
|
{
|
||||||
|
var at = template.GetAttributeTemplate(kv.Key);
|
||||||
|
|
||||||
|
if (at != null)
|
||||||
|
if (at.Info.CanWrite)
|
||||||
|
at.Info.SetValue(res, kv.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -183,6 +231,7 @@ namespace Esyur.Resource
|
|||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -758,12 +807,15 @@ namespace Esyur.Resource
|
|||||||
IResource res;
|
IResource res;
|
||||||
if (this.resource.TryGetTarget(out res))
|
if (this.resource.TryGetTarget(out res))
|
||||||
{
|
{
|
||||||
|
//return store.Applicable(res, session, action, member, inquirer);
|
||||||
|
|
||||||
foreach (IPermissionsManager manager in managers)
|
foreach (IPermissionsManager manager in managers)
|
||||||
{
|
{
|
||||||
var r = manager.Applicable(res, session, action, member, inquirer);
|
var r = manager.Applicable(res, session, action, member, inquirer);
|
||||||
if (r != Ruling.DontCare)
|
if (r != Ruling.DontCare)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Ruling.DontCare;
|
return Ruling.DontCare;
|
||||||
@ -790,7 +842,7 @@ namespace Esyur.Resource
|
|||||||
this.name = name;
|
this.name = name;
|
||||||
this.instanceAge = age;
|
this.instanceAge = age;
|
||||||
|
|
||||||
this.attributes = new KeyList<string, object>(this);
|
//this.attributes = new KeyList<string, object>(this);
|
||||||
//children = new AutoList<IResource, Instance>(this);
|
//children = new AutoList<IResource, Instance>(this);
|
||||||
//parents = new AutoList<IResource, Instance>(this);
|
//parents = new AutoList<IResource, Instance>(this);
|
||||||
managers = new AutoList<IPermissionsManager, Instance>(this);
|
managers = new AutoList<IPermissionsManager, Instance>(this);
|
||||||
|
42
Esyur/Resource/ResourceAttribute.cs
Normal file
42
Esyur/Resource/ResourceAttribute.cs
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (c) 2020 Ahmed Kh. Zamil
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Esyur.Resource
|
||||||
|
{
|
||||||
|
|
||||||
|
[AttributeUsage(AttributeTargets.Property)]
|
||||||
|
public class ResourceAttribute : System.Attribute
|
||||||
|
{
|
||||||
|
|
||||||
|
public ResourceAttribute()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
26
Esyur/Resource/Template/AttributeTemplate.cs
Normal file
26
Esyur/Resource/Template/AttributeTemplate.cs
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
using Esyur.Data;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Esyur.Resource.Template
|
||||||
|
{
|
||||||
|
public class AttributeTemplate : MemberTemplate
|
||||||
|
{
|
||||||
|
public PropertyInfo Info
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public AttributeTemplate(ResourceTemplate template, byte index, string name)
|
||||||
|
: base(template, MemberType.Attribute, index, name)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -14,6 +14,7 @@ namespace Esyur.Resource.Template
|
|||||||
Function = 0,
|
Function = 0,
|
||||||
Property = 1,
|
Property = 1,
|
||||||
Event = 2,
|
Event = 2,
|
||||||
|
Attribute = 3
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte Index => index;
|
public byte Index => index;
|
||||||
|
@ -19,6 +19,7 @@ namespace Esyur.Resource.Template
|
|||||||
List<FunctionTemplate> functions = new List<FunctionTemplate>();
|
List<FunctionTemplate> functions = new List<FunctionTemplate>();
|
||||||
List<EventTemplate> events = new List<EventTemplate>();
|
List<EventTemplate> events = new List<EventTemplate>();
|
||||||
List<PropertyTemplate> properties = new List<PropertyTemplate>();
|
List<PropertyTemplate> properties = new List<PropertyTemplate>();
|
||||||
|
List<AttributeTemplate> attributes = new List<AttributeTemplate>();
|
||||||
int version;
|
int version;
|
||||||
//bool isReady;
|
//bool isReady;
|
||||||
|
|
||||||
@ -88,6 +89,14 @@ namespace Esyur.Resource.Template
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public AttributeTemplate GetAttributeTemplate(string attributeName)
|
||||||
|
{
|
||||||
|
foreach (var i in attributes)
|
||||||
|
if (i.Name == attributeName)
|
||||||
|
return i;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public Guid ClassId
|
public Guid ClassId
|
||||||
{
|
{
|
||||||
get { return classId; }
|
get { return classId; }
|
||||||
@ -156,21 +165,31 @@ namespace Esyur.Resource.Template
|
|||||||
|
|
||||||
foreach (var pi in propsInfo)
|
foreach (var pi in propsInfo)
|
||||||
{
|
{
|
||||||
var ps = (ResourceProperty[])pi.GetCustomAttributes(typeof(ResourceProperty), true);
|
var rp = pi.GetCustomAttribute<ResourceProperty>(true);
|
||||||
if (ps.Length > 0)
|
|
||||||
|
if (rp != null)
|
||||||
{
|
{
|
||||||
var pt = new PropertyTemplate(this, i++, pi.Name, ps[0].ReadExpansion, ps[0].WriteExpansion, ps[0].Storage);
|
var pt = new PropertyTemplate(this, i++, pi.Name, rp.ReadExpansion, rp.WriteExpansion, rp.Storage);
|
||||||
pt.Info = pi;
|
pt.Info = pi;
|
||||||
pt.Serilize = ps[0].Serialize;
|
pt.Serilize = rp.Serialize;
|
||||||
properties.Add(pt);
|
properties.Add(pt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var ra = pi.GetCustomAttribute<ResourceAttribute>(true);
|
||||||
|
|
||||||
|
if (ra != null)
|
||||||
|
{
|
||||||
|
var at = new AttributeTemplate(this, i++, pi.Name);
|
||||||
|
at.Info = pi;
|
||||||
|
attributes.Add(at);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
|
|
||||||
foreach (var ei in eventsInfo)
|
foreach (var ei in eventsInfo)
|
||||||
{
|
{
|
||||||
var es = (ResourceEvent[])ei.GetCustomAttributes(typeof(ResourceEvent), true);
|
var es = ei.GetCustomAttributes<ResourceEvent>(true).ToArray();
|
||||||
if (es.Length > 0)
|
if (es.Length > 0)
|
||||||
{
|
{
|
||||||
var et = new EventTemplate(this, i++, ei.Name, es[0].Expansion);
|
var et = new EventTemplate(this, i++, ei.Name, es[0].Expansion);
|
||||||
@ -181,7 +200,7 @@ namespace Esyur.Resource.Template
|
|||||||
i = 0;
|
i = 0;
|
||||||
foreach (MethodInfo mi in methodsInfo)
|
foreach (MethodInfo mi in methodsInfo)
|
||||||
{
|
{
|
||||||
var fs = (ResourceFunction[])mi.GetCustomAttributes(typeof(ResourceFunction), true);
|
var fs = mi.GetCustomAttributes<ResourceFunction>(true).ToArray();
|
||||||
if (fs.Length > 0)
|
if (fs.Length > 0)
|
||||||
{
|
{
|
||||||
var ft = new FunctionTemplate(this, i++, mi.Name, mi.ReturnType == typeof(void), fs[0].Expansion);
|
var ft = new FunctionTemplate(this, i++, mi.Name, mi.ReturnType == typeof(void), fs[0].Expansion);
|
||||||
|
@ -501,10 +501,9 @@ namespace Esyur.Resource
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static T New<T>(string name, IStore store = null, IResource parent = null, IPermissionsManager manager = null, Structure attributes = null, Structure arguments = null, Structure properties = null)
|
public static IResource New(Type type, 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<T>();
|
type = ResourceProxy.GetProxy(type);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -544,7 +543,7 @@ namespace Esyur.Resource
|
|||||||
{
|
{
|
||||||
foreach (var p in properties)
|
foreach (var p in properties)
|
||||||
{
|
{
|
||||||
var pi = typeof(T).GetProperty(p.Key, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.DeclaredOnly);
|
var pi = type.GetProperty(p.Key, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.DeclaredOnly);
|
||||||
if (pi != null)
|
if (pi != null)
|
||||||
pi.SetValue(res, p.Value);
|
pi.SetValue(res, p.Value);
|
||||||
}
|
}
|
||||||
@ -553,7 +552,14 @@ namespace Esyur.Resource
|
|||||||
if (store != null || parent != null || res is IStore)
|
if (store != null || parent != null || res is IStore)
|
||||||
Put(res, name, store, parent, null, 0, manager, attributes);
|
Put(res, name, store, parent, null, 0, manager, attributes);
|
||||||
|
|
||||||
return (T)res;
|
return res;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static T New<T>(string name, IStore store = null, IResource parent = null, IPermissionsManager manager = null, Structure attributes = null, Structure arguments = null, Structure properties = null)
|
||||||
|
where T : IResource
|
||||||
|
{
|
||||||
|
return (T)New(typeof(T), name, store, parent, manager, attributes, arguments, properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -45,8 +45,8 @@ namespace Esyur.Stores
|
|||||||
{
|
{
|
||||||
|
|
||||||
resources.Add(resource.Instance.Id, resource);// new WeakReference<IResource>(resource));
|
resources.Add(resource.Instance.Id, resource);// new WeakReference<IResource>(resource));
|
||||||
resource.Instance.Attributes["children"] = new AutoList<IResource, Instance>(resource.Instance);
|
resource.Instance.Variables["children"] = new AutoList<IResource, Instance>(resource.Instance);
|
||||||
resource.Instance.Attributes["parents"] = new AutoList<IResource, Instance>(resource.Instance);
|
resource.Instance.Variables["parents"] = new AutoList<IResource, Instance>(resource.Instance);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -94,7 +94,7 @@ namespace Esyur.Stores
|
|||||||
{
|
{
|
||||||
if (parent.Instance.Store == this)
|
if (parent.Instance.Store == this)
|
||||||
{
|
{
|
||||||
(parent.Instance.Attributes["children"] as AutoList<IResource, Instance>).Add(child);
|
(parent.Instance.Variables["children"] as AutoList<IResource, Instance>).Add(child);
|
||||||
return new AsyncReply<bool>(true);
|
return new AsyncReply<bool>(true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -111,7 +111,7 @@ namespace Esyur.Stores
|
|||||||
|
|
||||||
if (resource.Instance.Store == this)
|
if (resource.Instance.Store == this)
|
||||||
{
|
{
|
||||||
(resource.Instance.Attributes["parents"] as AutoList<IResource, Instance>).Add(parent);
|
(resource.Instance.Variables["parents"] as AutoList<IResource, Instance>).Add(parent);
|
||||||
return new AsyncReply<bool>(true);
|
return new AsyncReply<bool>(true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -125,7 +125,7 @@ namespace Esyur.Stores
|
|||||||
|
|
||||||
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.Attributes["children"] as AutoList<IResource, Instance>);
|
var children = (resource.Instance.Variables["children"] as AutoList<IResource, Instance>);
|
||||||
|
|
||||||
if (name == null)
|
if (name == null)
|
||||||
return new AsyncBag<T>(children.Where(x=>x is T).Select(x=>(T)x).ToArray());
|
return new AsyncBag<T>(children.Where(x=>x is T).Select(x=>(T)x).ToArray());
|
||||||
@ -136,7 +136,7 @@ namespace Esyur.Stores
|
|||||||
|
|
||||||
public AsyncBag<T> Parents<T>(IResource resource, string name) where T : IResource
|
public AsyncBag<T> Parents<T>(IResource resource, string name) where T : IResource
|
||||||
{
|
{
|
||||||
var parents = (resource.Instance.Attributes["parents"] as AutoList<IResource, Instance>);
|
var parents = (resource.Instance.Variables["parents"] as AutoList<IResource, Instance>);
|
||||||
|
|
||||||
if (name == null)
|
if (name == null)
|
||||||
return new AsyncBag<T>(parents.Where(x => x is T).Select(x => (T)x).ToArray());
|
return new AsyncBag<T>(parents.Where(x => x is T).Select(x => (T)x).ToArray());
|
||||||
|
Loading…
x
Reference in New Issue
Block a user