From 87bbd0e94ce208dc9473feb14e06a0c4197c7eac Mon Sep 17 00:00:00 2001 From: Tobias Klika Date: Wed, 7 Dec 2022 15:20:53 +0100 Subject: [PATCH] move raven impl to package --- zero.Raven/Extensions/ValidatorExtensions.cs | 68 +++++++++++++++++++ .../Flavors/ConfigureFlavorJsonOptions.cs | 2 +- .../Flavors/FlavorConfig.cs | 2 +- .../Flavors/FlavorOptions.cs | 2 +- .../Flavors/FlavorProvider.cs | 2 +- .../Flavors/FlavorProviderOptions.cs | 2 +- .../Flavors/JsonFlavorVariantConverter.cs | 2 +- .../JsonFlavorVariantConverterFactory.cs | 2 +- .../GenerateIdAttribute.cs | 2 +- .../Persistence => zero.Raven}/IdGenerator.cs | 2 +- .../Indexes/ZeroIndex.cs | 2 +- .../Indexes/ZeroIndexExtensions.cs | 2 +- .../Indexes/ZeroTreeHierachyIndex.cs | 2 +- .../Interceptors/Interceptor.cs | 2 +- .../Interceptors/InterceptorInstruction.cs | 9 ++- .../Interceptors/InterceptorParameters.cs | 2 +- .../Interceptors/InterceptorResult.cs | 2 +- .../Interceptors/InterceptorRunType.cs | 2 +- .../Interceptors/Interceptors.cs | 13 ++-- .../Operations/RavenOperations.Delete.cs | 2 +- .../Operations/RavenOperations.Empty.cs | 2 +- .../Operations/RavenOperations.Read.cs | 2 +- .../Operations/RavenOperations.Tree.cs | 2 +- .../Operations/RavenOperations.Write.cs | 5 +- .../Operations/RavenOperations.cs | 7 +- .../Operations/RavenOperationsExtensions.cs | 2 +- .../Operations/StoreContext.cs | 6 +- .../RavenCollectionAttribute.cs | 2 +- .../RavenConstants.cs | 2 +- .../RavenIndexExtensions.cs | 2 +- .../RavenOptions.cs | 2 +- .../RavenQueryableExtensions.cs | 2 +- {zero/Persistence => zero.Raven}/Safenames.cs | 2 +- .../Tokens/Rfc6238AuthenticationService.cs | 2 +- .../Tokens/Token.cs | 2 +- .../Tokens/ZeroTokenProvider.cs | 2 +- zero.Raven/Usings.cs | 19 ++++++ zero.Raven/ZeroBuilderExtensions.cs | 12 ++++ .../ZeroDocumentConventionsBuilder.cs | 5 +- .../ZeroDocumentSession.cs | 2 +- zero.Raven/ZeroDocumentSessionExtensions.cs | 16 +++++ .../ZeroDocumentStore.cs | 2 +- .../ZeroPersistenceModule.cs | 13 ++-- {zero/Persistence => zero.Raven}/ZeroStore.cs | 2 +- zero.Raven/zero.Raven.csproj | 22 ++++++ zero.sln | 6 ++ zero/Communication/ZeroCommunicationModule.cs | 1 - zero/Configuration/ZeroOptions.cs | 8 --- zero/Context/ZeroContext.cs | 12 +--- zero/Localization/FileLocalizer.cs | 48 +++++++++++++ zero/Localization/LocalizationOptions.cs | 6 ++ zero/Localization/Localizer.cs | 14 +--- zero/Localization/Models/Translation.cs | 15 ++-- zero/Localization/ZeroLocalizationModule.cs | 7 +- zero/Models/ISupportsDbConventions.cs | 6 ++ zero/Persistence/ISupportsDbConventions.cs | 6 -- .../ZeroDocumentSessionExtensions.cs | 14 ---- zero/Usings.cs | 2 +- zero/Validation/ValidatorExtensions.cs | 60 ---------------- zero/ZeroBuilder.cs | 18 ++++- 60 files changed, 304 insertions(+), 180 deletions(-) create mode 100644 zero.Raven/Extensions/ValidatorExtensions.cs rename {zero/Persistence => zero.Raven}/Flavors/ConfigureFlavorJsonOptions.cs (94%) rename {zero/Persistence => zero.Raven}/Flavors/FlavorConfig.cs (96%) rename {zero/Persistence => zero.Raven}/Flavors/FlavorOptions.cs (99%) rename {zero/Persistence => zero.Raven}/Flavors/FlavorProvider.cs (96%) rename {zero/Persistence => zero.Raven}/Flavors/FlavorProviderOptions.cs (98%) rename {zero/Persistence => zero.Raven}/Flavors/JsonFlavorVariantConverter.cs (97%) rename {zero/Persistence => zero.Raven}/Flavors/JsonFlavorVariantConverterFactory.cs (96%) rename {zero/Persistence => zero.Raven}/GenerateIdAttribute.cs (92%) rename {zero/Persistence => zero.Raven}/IdGenerator.cs (98%) rename {zero/Persistence => zero.Raven}/Indexes/ZeroIndex.cs (99%) rename {zero/Persistence => zero.Raven}/Indexes/ZeroIndexExtensions.cs (93%) rename {zero/Persistence => zero.Raven}/Indexes/ZeroTreeHierachyIndex.cs (96%) rename {zero/Communication => zero.Raven}/Interceptors/Interceptor.cs (99%) rename {zero/Communication => zero.Raven}/Interceptors/InterceptorInstruction.cs (93%) rename {zero/Communication => zero.Raven}/Interceptors/InterceptorParameters.cs (97%) rename {zero/Communication => zero.Raven}/Interceptors/InterceptorResult.cs (94%) rename {zero/Communication => zero.Raven}/Interceptors/InterceptorRunType.cs (69%) rename {zero/Communication => zero.Raven}/Interceptors/Interceptors.cs (67%) rename {zero/Persistence => zero.Raven}/Operations/RavenOperations.Delete.cs (95%) rename {zero/Persistence => zero.Raven}/Operations/RavenOperations.Empty.cs (93%) rename {zero/Persistence => zero.Raven}/Operations/RavenOperations.Read.cs (99%) rename {zero/Persistence => zero.Raven}/Operations/RavenOperations.Tree.cs (99%) rename {zero/Persistence => zero.Raven}/Operations/RavenOperations.Write.cs (93%) rename {zero/Persistence => zero.Raven}/Operations/RavenOperations.cs (98%) rename {zero/Persistence => zero.Raven}/Operations/RavenOperationsExtensions.cs (98%) rename {zero/Persistence => zero.Raven}/Operations/StoreContext.cs (72%) rename {zero/Persistence => zero.Raven}/RavenCollectionAttribute.cs (92%) rename {zero/Persistence => zero.Raven}/RavenConstants.cs (85%) rename {zero/Persistence => zero.Raven}/RavenIndexExtensions.cs (91%) rename {zero/Persistence => zero.Raven}/RavenOptions.cs (98%) rename {zero/Persistence => zero.Raven}/RavenQueryableExtensions.cs (99%) rename {zero/Persistence => zero.Raven}/Safenames.cs (99%) rename {zero/Persistence => zero.Raven}/Tokens/Rfc6238AuthenticationService.cs (99%) rename {zero/Persistence => zero.Raven}/Tokens/Token.cs (89%) rename {zero/Persistence => zero.Raven}/Tokens/ZeroTokenProvider.cs (99%) create mode 100644 zero.Raven/Usings.cs create mode 100644 zero.Raven/ZeroBuilderExtensions.cs rename {zero/Persistence => zero.Raven}/ZeroDocumentConventionsBuilder.cs (97%) rename {zero/Persistence => zero.Raven}/ZeroDocumentSession.cs (96%) create mode 100644 zero.Raven/ZeroDocumentSessionExtensions.cs rename {zero/Persistence => zero.Raven}/ZeroDocumentStore.cs (99%) rename {zero/Persistence => zero.Raven}/ZeroPersistenceModule.cs (85%) rename {zero/Persistence => zero.Raven}/ZeroStore.cs (98%) create mode 100644 zero.Raven/zero.Raven.csproj create mode 100644 zero/Localization/FileLocalizer.cs create mode 100644 zero/Localization/LocalizationOptions.cs create mode 100644 zero/Models/ISupportsDbConventions.cs delete mode 100644 zero/Persistence/ISupportsDbConventions.cs delete mode 100644 zero/Persistence/ZeroDocumentSessionExtensions.cs diff --git a/zero.Raven/Extensions/ValidatorExtensions.cs b/zero.Raven/Extensions/ValidatorExtensions.cs new file mode 100644 index 00000000..edfdff7f --- /dev/null +++ b/zero.Raven/Extensions/ValidatorExtensions.cs @@ -0,0 +1,68 @@ +using FluentValidation; +using Raven.Client.Documents; +using System.Globalization; +using zero.Extensions; +using zero.Models; +using zero.Raven; + +namespace zero.Raven; + +public static class ValidatorExtensions +{ + /// + /// Check if this value is unique within a collection + /// + public static IRuleBuilderOptions Unique(this IRuleBuilder ruleBuilder, IZeroStore store) where T : ZeroEntity + { + return ruleBuilder.MustAsync(async (entity, value, context, cancellation) => + { + bool any = await store.Session().Advanced.AsyncDocumentQuery() + .WhereNotEquals(nameof(ZeroIdEntity.Id), entity.Id) + .WhereEquals(context.PropertyName.ToPascalCaseId(), value) + .AnyAsync(cancellation); + + return !any; + }).WithMessage("@errors.forms.not_unique"); + } + + + /// + /// Check if this value is at least set once to the expected value within a collection + /// + public static IRuleBuilderOptions ExpectAnyUnique(this IRuleBuilder ruleBuilder, IZeroStore store, TProperty expectedValue) where T : ZeroEntity + { + return ruleBuilder.MustAsync(async (entity, value, context, cancellation) => + { + return await store.Session().Advanced.AsyncDocumentQuery() + .WhereNotEquals(nameof(ZeroIdEntity.Id), entity.Id) + .WhereEquals(context.PropertyName.ToPascalCaseId(), expectedValue) + .AnyAsync(cancellation); + }).WithMessage("@errors.forms.not_unique_alone"); + } + + + /// + /// Check if this reference exists and is an entity which can be referenced (appId = shared for shareable entities or appId = current) + /// + public static IRuleBuilderOptions Exists(this IRuleBuilder ruleBuilder, IZeroStore store) where T : ZeroEntity + { + return ruleBuilder.Exists(store); + } + + + /// + /// Check if this reference exists and is an entity which can be referenced (appId = shared for shareable entities or appId = current) + /// + public static IRuleBuilderOptions Exists(this IRuleBuilder ruleBuilder, IZeroStore store) where T : ZeroEntity where TReference : ZeroEntity + { + return ruleBuilder.MustAsync(async (entity, id, context, cancellation) => + { + if (id.IsNullOrWhiteSpace()) + { + return true; + } + + return await store.Session().Query().AnyAsync(x => x.Id == id); + }).WithMessage("@errors.forms.reference_notfound"); + } +} diff --git a/zero/Persistence/Flavors/ConfigureFlavorJsonOptions.cs b/zero.Raven/Flavors/ConfigureFlavorJsonOptions.cs similarity index 94% rename from zero/Persistence/Flavors/ConfigureFlavorJsonOptions.cs rename to zero.Raven/Flavors/ConfigureFlavorJsonOptions.cs index 3dc8eaf3..d964bd75 100644 --- a/zero/Persistence/Flavors/ConfigureFlavorJsonOptions.cs +++ b/zero.Raven/Flavors/ConfigureFlavorJsonOptions.cs @@ -1,7 +1,7 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Options; -namespace zero.Persistence; +namespace zero.Raven; public class ConfigureFlavorJsonOptions : IConfigureOptions diff --git a/zero/Persistence/Flavors/FlavorConfig.cs b/zero.Raven/Flavors/FlavorConfig.cs similarity index 96% rename from zero/Persistence/Flavors/FlavorConfig.cs rename to zero.Raven/Flavors/FlavorConfig.cs index abfc4def..c606fe99 100644 --- a/zero/Persistence/Flavors/FlavorConfig.cs +++ b/zero.Raven/Flavors/FlavorConfig.cs @@ -1,6 +1,6 @@ using System.Text.Json.Serialization; -namespace zero.Persistence; +namespace zero.Raven; /// /// A flavor config holds information about a flavor implementation diff --git a/zero/Persistence/Flavors/FlavorOptions.cs b/zero.Raven/Flavors/FlavorOptions.cs similarity index 99% rename from zero/Persistence/Flavors/FlavorOptions.cs rename to zero.Raven/Flavors/FlavorOptions.cs index 00dd7794..d97c55f5 100644 --- a/zero/Persistence/Flavors/FlavorOptions.cs +++ b/zero.Raven/Flavors/FlavorOptions.cs @@ -1,6 +1,6 @@ using System.Collections.Concurrent; -namespace zero.Persistence; +namespace zero.Raven; public class FlavorOptions { diff --git a/zero/Persistence/Flavors/FlavorProvider.cs b/zero.Raven/Flavors/FlavorProvider.cs similarity index 96% rename from zero/Persistence/Flavors/FlavorProvider.cs rename to zero.Raven/Flavors/FlavorProvider.cs index 4acb07ee..30567b04 100644 --- a/zero/Persistence/Flavors/FlavorProvider.cs +++ b/zero.Raven/Flavors/FlavorProvider.cs @@ -1,6 +1,6 @@ using System.Text.Json.Serialization; -namespace zero.Persistence; +namespace zero.Raven; /// /// A flavor provider is attached to an entity (which has ISupportsFlavors) and contains all flavors diff --git a/zero/Persistence/Flavors/FlavorProviderOptions.cs b/zero.Raven/Flavors/FlavorProviderOptions.cs similarity index 98% rename from zero/Persistence/Flavors/FlavorProviderOptions.cs rename to zero.Raven/Flavors/FlavorProviderOptions.cs index 24f75fa7..71e03559 100644 --- a/zero/Persistence/Flavors/FlavorProviderOptions.cs +++ b/zero.Raven/Flavors/FlavorProviderOptions.cs @@ -1,4 +1,4 @@ -namespace zero.Persistence; +namespace zero.Raven; public class FlavorProviderOptions where TEntity : class, ISupportsFlavors, new() { diff --git a/zero/Persistence/Flavors/JsonFlavorVariantConverter.cs b/zero.Raven/Flavors/JsonFlavorVariantConverter.cs similarity index 97% rename from zero/Persistence/Flavors/JsonFlavorVariantConverter.cs rename to zero.Raven/Flavors/JsonFlavorVariantConverter.cs index 6ba16c4d..1e278898 100644 --- a/zero/Persistence/Flavors/JsonFlavorVariantConverter.cs +++ b/zero.Raven/Flavors/JsonFlavorVariantConverter.cs @@ -1,7 +1,7 @@ using System.Text.Json; using System.Text.Json.Serialization; -namespace zero.Persistence; +namespace zero.Raven; internal class JsonFlavorVariantConverter : JsonDiscriminatorConverter where T : class, ISupportsFlavors, new() { diff --git a/zero/Persistence/Flavors/JsonFlavorVariantConverterFactory.cs b/zero.Raven/Flavors/JsonFlavorVariantConverterFactory.cs similarity index 96% rename from zero/Persistence/Flavors/JsonFlavorVariantConverterFactory.cs rename to zero.Raven/Flavors/JsonFlavorVariantConverterFactory.cs index 1d33d703..a466bac8 100644 --- a/zero/Persistence/Flavors/JsonFlavorVariantConverterFactory.cs +++ b/zero.Raven/Flavors/JsonFlavorVariantConverterFactory.cs @@ -1,7 +1,7 @@ using System.Text.Json; using System.Text.Json.Serialization; -namespace zero.Persistence; +namespace zero.Raven; public class JsonFlavorVariantConverterFactory : JsonConverterFactory { diff --git a/zero/Persistence/GenerateIdAttribute.cs b/zero.Raven/GenerateIdAttribute.cs similarity index 92% rename from zero/Persistence/GenerateIdAttribute.cs rename to zero.Raven/GenerateIdAttribute.cs index 8318aa43..f26ce683 100644 --- a/zero/Persistence/GenerateIdAttribute.cs +++ b/zero.Raven/GenerateIdAttribute.cs @@ -1,4 +1,4 @@ -namespace zero.Persistence; +namespace zero.Raven; /// /// Automatically generate ID with the specified length and insert it into this property on entity save diff --git a/zero/Persistence/IdGenerator.cs b/zero.Raven/IdGenerator.cs similarity index 98% rename from zero/Persistence/IdGenerator.cs rename to zero.Raven/IdGenerator.cs index 63483b0c..4011fd62 100644 --- a/zero/Persistence/IdGenerator.cs +++ b/zero.Raven/IdGenerator.cs @@ -1,6 +1,6 @@ using System.Text.Json; -namespace zero.Persistence; +namespace zero.Raven; public class IdGenerator { diff --git a/zero/Persistence/Indexes/ZeroIndex.cs b/zero.Raven/Indexes/ZeroIndex.cs similarity index 99% rename from zero/Persistence/Indexes/ZeroIndex.cs rename to zero.Raven/Indexes/ZeroIndex.cs index b86cee27..0c13387e 100644 --- a/zero/Persistence/Indexes/ZeroIndex.cs +++ b/zero.Raven/Indexes/ZeroIndex.cs @@ -4,7 +4,7 @@ using Raven.Client.Documents.Indexes.Spatial; using Raven.Client.Documents.Operations.Attachments; using System.Linq.Expressions; -namespace zero.Persistence; +namespace zero.Raven; public abstract class ZeroJavascriptIndex : AbstractJavaScriptIndexCreationTask, IZeroIndexDefinition diff --git a/zero/Persistence/Indexes/ZeroIndexExtensions.cs b/zero.Raven/Indexes/ZeroIndexExtensions.cs similarity index 93% rename from zero/Persistence/Indexes/ZeroIndexExtensions.cs rename to zero.Raven/Indexes/ZeroIndexExtensions.cs index 41ead020..0555592c 100644 --- a/zero/Persistence/Indexes/ZeroIndexExtensions.cs +++ b/zero.Raven/Indexes/ZeroIndexExtensions.cs @@ -1,4 +1,4 @@ -namespace zero.Persistence; +namespace zero.Raven; public static class ZeroIndexExtensions { diff --git a/zero/Persistence/Indexes/ZeroTreeHierachyIndex.cs b/zero.Raven/Indexes/ZeroTreeHierachyIndex.cs similarity index 96% rename from zero/Persistence/Indexes/ZeroTreeHierachyIndex.cs rename to zero.Raven/Indexes/ZeroTreeHierachyIndex.cs index f1f2d6b6..255ea19e 100644 --- a/zero/Persistence/Indexes/ZeroTreeHierachyIndex.cs +++ b/zero.Raven/Indexes/ZeroTreeHierachyIndex.cs @@ -1,7 +1,7 @@ using Raven.Client.Documents; using Raven.Client.Documents.Indexes; -namespace zero.Persistence; +namespace zero.Raven; public class ZeroTreeHierarchyIndexResult : ZeroIdEntity, ISupportsDbConventions { diff --git a/zero/Communication/Interceptors/Interceptor.cs b/zero.Raven/Interceptors/Interceptor.cs similarity index 99% rename from zero/Communication/Interceptors/Interceptor.cs rename to zero.Raven/Interceptors/Interceptor.cs index f47498c3..abdf6b95 100644 --- a/zero/Communication/Interceptors/Interceptor.cs +++ b/zero.Raven/Interceptors/Interceptor.cs @@ -1,4 +1,4 @@ -namespace zero.Communication; +namespace zero.Raven; public abstract partial class Interceptor : Interceptor, IInterceptor where T : ZeroIdEntity diff --git a/zero/Communication/Interceptors/InterceptorInstruction.cs b/zero.Raven/Interceptors/InterceptorInstruction.cs similarity index 93% rename from zero/Communication/Interceptors/InterceptorInstruction.cs rename to zero.Raven/Interceptors/InterceptorInstruction.cs index 30f510f4..4d9a521e 100644 --- a/zero/Communication/Interceptors/InterceptorInstruction.cs +++ b/zero.Raven/Interceptors/InterceptorInstruction.cs @@ -1,6 +1,6 @@ using Microsoft.Extensions.Logging; -namespace zero.Communication; +namespace zero.Raven; public class InterceptorInstruction where T : ZeroIdEntity, new() { @@ -17,6 +17,8 @@ public class InterceptorInstruction where T : ZeroIdEntity, new() public Result Result { get; private set; } protected IZeroContext Context { get; private set; } + + protected IZeroStore Store { get; private set; } protected Lazy> Interceptors { get; private set; } @@ -29,9 +31,10 @@ public class InterceptorInstruction where T : ZeroIdEntity, new() protected Func InterceptorFilter { get; private set; } = x => true; - internal InterceptorInstruction(IInterceptors interceptors, IZeroContext context, Lazy> registrations, ILogger logger, InterceptorRunType runtype, T model, T previousModel = null) + internal InterceptorInstruction(IInterceptors interceptors, IZeroStore store, IZeroContext context, Lazy> registrations, ILogger logger, InterceptorRunType runtype, T model, T previousModel = null) { InterceptorHandler = interceptors; + Store = store; Context = context; Guid = Guid.NewGuid(); Logger = logger; @@ -65,7 +68,7 @@ public class InterceptorInstruction where T : ZeroIdEntity, new() InterceptorParameters parameters = new() { Context = Context, - Store = Context.Store, + Store = Store, Properties = new(), Interceptors = InterceptorHandler, Operations = operations, diff --git a/zero/Communication/Interceptors/InterceptorParameters.cs b/zero.Raven/Interceptors/InterceptorParameters.cs similarity index 97% rename from zero/Communication/Interceptors/InterceptorParameters.cs rename to zero.Raven/Interceptors/InterceptorParameters.cs index 461e557f..4b16384d 100644 --- a/zero/Communication/Interceptors/InterceptorParameters.cs +++ b/zero.Raven/Interceptors/InterceptorParameters.cs @@ -1,4 +1,4 @@ -namespace zero.Communication; +namespace zero.Raven; public class InterceptorParameters { diff --git a/zero/Communication/Interceptors/InterceptorResult.cs b/zero.Raven/Interceptors/InterceptorResult.cs similarity index 94% rename from zero/Communication/Interceptors/InterceptorResult.cs rename to zero.Raven/Interceptors/InterceptorResult.cs index 735ae3ba..b6a4a1ba 100644 --- a/zero/Communication/Interceptors/InterceptorResult.cs +++ b/zero.Raven/Interceptors/InterceptorResult.cs @@ -1,4 +1,4 @@ -namespace zero.Communication; +namespace zero.Raven; public class InterceptorResult { diff --git a/zero/Communication/Interceptors/InterceptorRunType.cs b/zero.Raven/Interceptors/InterceptorRunType.cs similarity index 69% rename from zero/Communication/Interceptors/InterceptorRunType.cs rename to zero.Raven/Interceptors/InterceptorRunType.cs index 82be301e..292a35ad 100644 --- a/zero/Communication/Interceptors/InterceptorRunType.cs +++ b/zero.Raven/Interceptors/InterceptorRunType.cs @@ -1,4 +1,4 @@ -namespace zero.Communication; +namespace zero.Raven; public enum InterceptorRunType { diff --git a/zero/Communication/Interceptors/Interceptors.cs b/zero.Raven/Interceptors/Interceptors.cs similarity index 67% rename from zero/Communication/Interceptors/Interceptors.cs rename to zero.Raven/Interceptors/Interceptors.cs index 297f1676..51606ed3 100644 --- a/zero/Communication/Interceptors/Interceptors.cs +++ b/zero.Raven/Interceptors/Interceptors.cs @@ -1,32 +1,35 @@ using Microsoft.Extensions.Logging; -namespace zero.Communication; +namespace zero.Raven; public class Interceptors : IInterceptors { protected IZeroContext Context { get; set; } + + protected IZeroStore Store { get; set; } protected Lazy> Registrations { get; set; } protected ILogger Logger { get; set; } - public Interceptors(IZeroContext context, Lazy> registrations, ILogger logger) + public Interceptors(IZeroContext context, IZeroStore store, Lazy> registrations, ILogger logger) { Context = context; + Store = store; Registrations = registrations; Logger = logger; } /// - public InterceptorInstruction ForCreate(T model) where T : ZeroIdEntity, new() => new(this, Context, Registrations, Logger, InterceptorRunType.Create, model); + public InterceptorInstruction ForCreate(T model) where T : ZeroIdEntity, new() => new(this, Store, Context, Registrations, Logger, InterceptorRunType.Create, model); /// - public InterceptorInstruction ForUpdate(T model, T previousModel = null) where T : ZeroIdEntity, new() => new(this, Context, Registrations, Logger, InterceptorRunType.Update, model, previousModel); + public InterceptorInstruction ForUpdate(T model, T previousModel = null) where T : ZeroIdEntity, new() => new(this, Store, Context, Registrations, Logger, InterceptorRunType.Update, model, previousModel); /// - public InterceptorInstruction ForDelete(T model) where T : ZeroIdEntity, new() => new(this, Context, Registrations, Logger, InterceptorRunType.Delete, model); + public InterceptorInstruction ForDelete(T model) where T : ZeroIdEntity, new() => new(this, Store, Context, Registrations, Logger, InterceptorRunType.Delete, model); } diff --git a/zero/Persistence/Operations/RavenOperations.Delete.cs b/zero.Raven/Operations/RavenOperations.Delete.cs similarity index 95% rename from zero/Persistence/Operations/RavenOperations.Delete.cs rename to zero.Raven/Operations/RavenOperations.Delete.cs index dcf7a67a..5bd164e4 100644 --- a/zero/Persistence/Operations/RavenOperations.Delete.cs +++ b/zero.Raven/Operations/RavenOperations.Delete.cs @@ -1,4 +1,4 @@ -namespace zero.Persistence; +namespace zero.Raven; public partial class RavenOperations : IRavenOperations { diff --git a/zero/Persistence/Operations/RavenOperations.Empty.cs b/zero.Raven/Operations/RavenOperations.Empty.cs similarity index 93% rename from zero/Persistence/Operations/RavenOperations.Empty.cs rename to zero.Raven/Operations/RavenOperations.Empty.cs index c06250d5..177d2489 100644 --- a/zero/Persistence/Operations/RavenOperations.Empty.cs +++ b/zero.Raven/Operations/RavenOperations.Empty.cs @@ -1,4 +1,4 @@ -namespace zero.Persistence; +namespace zero.Raven; public partial class RavenOperations : IRavenOperations { diff --git a/zero/Persistence/Operations/RavenOperations.Read.cs b/zero.Raven/Operations/RavenOperations.Read.cs similarity index 99% rename from zero/Persistence/Operations/RavenOperations.Read.cs rename to zero.Raven/Operations/RavenOperations.Read.cs index 33b1074d..d3f6419a 100644 --- a/zero/Persistence/Operations/RavenOperations.Read.cs +++ b/zero.Raven/Operations/RavenOperations.Read.cs @@ -3,7 +3,7 @@ using Raven.Client.Documents.Indexes; using Raven.Client.Documents.Linq; using Raven.Client.Documents.Session; -namespace zero.Persistence; +namespace zero.Raven; public partial class RavenOperations : IRavenOperations { diff --git a/zero/Persistence/Operations/RavenOperations.Tree.cs b/zero.Raven/Operations/RavenOperations.Tree.cs similarity index 99% rename from zero/Persistence/Operations/RavenOperations.Tree.cs rename to zero.Raven/Operations/RavenOperations.Tree.cs index 6f39bc74..e04b1c27 100644 --- a/zero/Persistence/Operations/RavenOperations.Tree.cs +++ b/zero.Raven/Operations/RavenOperations.Tree.cs @@ -3,7 +3,7 @@ using Raven.Client.Documents.Indexes; using Raven.Client.Documents.Linq; using Raven.Client.Documents.Session; -namespace zero.Persistence; +namespace zero.Raven; public partial class RavenOperations : IRavenOperations { diff --git a/zero/Persistence/Operations/RavenOperations.Write.cs b/zero.Raven/Operations/RavenOperations.Write.cs similarity index 93% rename from zero/Persistence/Operations/RavenOperations.Write.cs rename to zero.Raven/Operations/RavenOperations.Write.cs index 2b57f46a..fb6d7066 100644 --- a/zero/Persistence/Operations/RavenOperations.Write.cs +++ b/zero.Raven/Operations/RavenOperations.Write.cs @@ -1,6 +1,7 @@ using FluentValidation.Results; +using Rv = Raven.Client; -namespace zero.Persistence; +namespace zero.Raven; public partial class RavenOperations : IRavenOperations { @@ -24,7 +25,7 @@ public partial class RavenOperations : IRavenOperations // check if the Id for a model already exists if (!model.Id.IsNullOrEmpty()) { - using (IZeroDocumentSession session = Context.Store.Session(options: new Raven.Client.Documents.Session.SessionOptions() { Database = Context.Store.ResolvedDatabase, NoCaching = true })) + using (IZeroDocumentSession session = Store.Session(options: new Rv.Documents.Session.SessionOptions() { Database = Store.ResolvedDatabase, NoCaching = true })) { previousModel = await session.LoadAsync(model.Id); } diff --git a/zero/Persistence/Operations/RavenOperations.cs b/zero.Raven/Operations/RavenOperations.cs similarity index 98% rename from zero/Persistence/Operations/RavenOperations.cs rename to zero.Raven/Operations/RavenOperations.cs index 7de7dd86..ed4287d7 100644 --- a/zero/Persistence/Operations/RavenOperations.cs +++ b/zero.Raven/Operations/RavenOperations.cs @@ -4,12 +4,12 @@ using Raven.Client.Documents.Indexes; using Raven.Client.Documents.Linq; using System.Security.Claims; -namespace zero.Persistence; +namespace zero.Raven; public partial class RavenOperations : IRavenOperations { /// - public IZeroDocumentSession Session => Context.Store.Session(); + public IZeroDocumentSession Session => Store.Session(); protected record OperationOptions(bool IncludeInactive); @@ -20,12 +20,15 @@ public partial class RavenOperations : IRavenOperations protected FlavorOptions Flavors { get; private set; } protected IServiceProvider Services { get; private set; } + + protected IZeroStore Store { get; private set; } protected StoreInterceptorBlocker InterceptorBlocker { get; private set; } public RavenOperations(StoreContext context) { + Store = context.Store; Context = context.Context; Interceptors = context.Interceptors; Services = context.Services; diff --git a/zero/Persistence/Operations/RavenOperationsExtensions.cs b/zero.Raven/Operations/RavenOperationsExtensions.cs similarity index 98% rename from zero/Persistence/Operations/RavenOperationsExtensions.cs rename to zero.Raven/Operations/RavenOperationsExtensions.cs index dec4f435..5841cb3a 100644 --- a/zero/Persistence/Operations/RavenOperationsExtensions.cs +++ b/zero.Raven/Operations/RavenOperationsExtensions.cs @@ -1,6 +1,6 @@ using Raven.Client.Documents.Linq; -namespace zero.Persistence; +namespace zero.Raven; public static class RavenOperationsExtensions { diff --git a/zero/Persistence/Operations/StoreContext.cs b/zero.Raven/Operations/StoreContext.cs similarity index 72% rename from zero/Persistence/Operations/StoreContext.cs rename to zero.Raven/Operations/StoreContext.cs index 95c44939..f36e257e 100644 --- a/zero/Persistence/Operations/StoreContext.cs +++ b/zero.Raven/Operations/StoreContext.cs @@ -1,4 +1,4 @@ -namespace zero.Persistence; +namespace zero.Raven; public class StoreContext { @@ -15,9 +15,9 @@ public class StoreContext public IMessageAggregator Messages { get; private set; } - public StoreContext(IZeroContext context, IInterceptors interceptors, IServiceProvider serviceProvider, IMessageAggregator messages) + public StoreContext(IZeroContext context, IZeroStore store, IInterceptors interceptors, IServiceProvider serviceProvider, IMessageAggregator messages) { - Store = context.Store; + Store = store; Options = context.Options; Context = context; Interceptors = interceptors; diff --git a/zero/Persistence/RavenCollectionAttribute.cs b/zero.Raven/RavenCollectionAttribute.cs similarity index 92% rename from zero/Persistence/RavenCollectionAttribute.cs rename to zero.Raven/RavenCollectionAttribute.cs index d45d9701..c3749e06 100644 --- a/zero/Persistence/RavenCollectionAttribute.cs +++ b/zero.Raven/RavenCollectionAttribute.cs @@ -1,4 +1,4 @@ -namespace zero.Persistence; +namespace zero.Raven; /// /// This attribute will allow the usage of custom collection names for Raven collections diff --git a/zero/Persistence/RavenConstants.cs b/zero.Raven/RavenConstants.cs similarity index 85% rename from zero/Persistence/RavenConstants.cs rename to zero.Raven/RavenConstants.cs index 698754c2..b0e061c6 100644 --- a/zero/Persistence/RavenConstants.cs +++ b/zero.Raven/RavenConstants.cs @@ -1,4 +1,4 @@ -namespace zero.Persistence; +namespace zero.Raven; public static partial class RavenConstants { diff --git a/zero/Persistence/RavenIndexExtensions.cs b/zero.Raven/RavenIndexExtensions.cs similarity index 91% rename from zero/Persistence/RavenIndexExtensions.cs rename to zero.Raven/RavenIndexExtensions.cs index 016894fc..1447451b 100644 --- a/zero/Persistence/RavenIndexExtensions.cs +++ b/zero.Raven/RavenIndexExtensions.cs @@ -1,6 +1,6 @@ using Raven.Client.Documents.Indexes; -namespace zero.Persistence; +namespace zero.Raven; public static class RavenIndexExtensions { diff --git a/zero/Persistence/RavenOptions.cs b/zero.Raven/RavenOptions.cs similarity index 98% rename from zero/Persistence/RavenOptions.cs rename to zero.Raven/RavenOptions.cs index eb9ed12b..35991042 100644 --- a/zero/Persistence/RavenOptions.cs +++ b/zero.Raven/RavenOptions.cs @@ -1,7 +1,7 @@ using Raven.Client.Documents; using System.Linq.Expressions; -namespace zero.Persistence; +namespace zero.Raven; public class RavenOptions { diff --git a/zero/Persistence/RavenQueryableExtensions.cs b/zero.Raven/RavenQueryableExtensions.cs similarity index 99% rename from zero/Persistence/RavenQueryableExtensions.cs rename to zero.Raven/RavenQueryableExtensions.cs index 332154e4..7a776e52 100644 --- a/zero/Persistence/RavenQueryableExtensions.cs +++ b/zero.Raven/RavenQueryableExtensions.cs @@ -4,7 +4,7 @@ using Raven.Client.Documents.Queries; using Raven.Client.Documents.Session; using System.Linq.Expressions; -namespace zero.Persistence; +namespace zero.Raven; public static class RavenQueryableExtensions { diff --git a/zero/Persistence/Safenames.cs b/zero.Raven/Safenames.cs similarity index 99% rename from zero/Persistence/Safenames.cs rename to zero.Raven/Safenames.cs index 7d41297d..dfc456ad 100644 --- a/zero/Persistence/Safenames.cs +++ b/zero.Raven/Safenames.cs @@ -1,7 +1,7 @@ using System.IO; using System.Text; -namespace zero.Persistence; +namespace zero.Raven; public class Safenames { diff --git a/zero/Persistence/Tokens/Rfc6238AuthenticationService.cs b/zero.Raven/Tokens/Rfc6238AuthenticationService.cs similarity index 99% rename from zero/Persistence/Tokens/Rfc6238AuthenticationService.cs rename to zero.Raven/Tokens/Rfc6238AuthenticationService.cs index 8c576663..5654900e 100644 --- a/zero/Persistence/Tokens/Rfc6238AuthenticationService.cs +++ b/zero.Raven/Tokens/Rfc6238AuthenticationService.cs @@ -3,7 +3,7 @@ using System.Net; using System.Security.Cryptography; using System.Text; -namespace zero.Persistence; +namespace zero.Raven; /// /// Replicates the Rfc6238AuthenticationService from ASP.NET Core internals as it isn't part of the public API diff --git a/zero/Persistence/Tokens/Token.cs b/zero.Raven/Tokens/Token.cs similarity index 89% rename from zero/Persistence/Tokens/Token.cs rename to zero.Raven/Tokens/Token.cs index 866b85fd..35c125c1 100644 --- a/zero/Persistence/Tokens/Token.cs +++ b/zero.Raven/Tokens/Token.cs @@ -1,4 +1,4 @@ -namespace zero.Persistence; +namespace zero.Raven; [RavenCollection("Tokens")] public class SecurityToken : ISupportsDbConventions diff --git a/zero/Persistence/Tokens/ZeroTokenProvider.cs b/zero.Raven/Tokens/ZeroTokenProvider.cs similarity index 99% rename from zero/Persistence/Tokens/ZeroTokenProvider.cs rename to zero.Raven/Tokens/ZeroTokenProvider.cs index ff1e37a0..60318077 100644 --- a/zero/Persistence/Tokens/ZeroTokenProvider.cs +++ b/zero.Raven/Tokens/ZeroTokenProvider.cs @@ -3,7 +3,7 @@ using Raven.Client.Documents.Session; using System.Security.Cryptography; using System.Text; -namespace zero.Persistence; +namespace zero.Raven; public class ZeroTokenProvider : IZeroTokenProvider { diff --git a/zero.Raven/Usings.cs b/zero.Raven/Usings.cs new file mode 100644 index 00000000..58742184 --- /dev/null +++ b/zero.Raven/Usings.cs @@ -0,0 +1,19 @@ + +global using System; +global using System.Collections; +global using System.Collections.Generic; +global using System.Linq; +global using System.Threading; +global using System.Threading.Tasks; + +global using zero.Utils; +global using zero.Configuration; +global using zero.Extensions; +global using zero.FileStorage; +global using zero.Models; +global using zero.Architecture; +global using zero.Rendering; +global using zero.Validation; +global using zero.Localization; +global using zero.Context; +global using zero.Communication; \ No newline at end of file diff --git a/zero.Raven/ZeroBuilderExtensions.cs b/zero.Raven/ZeroBuilderExtensions.cs new file mode 100644 index 00000000..ea6631cc --- /dev/null +++ b/zero.Raven/ZeroBuilderExtensions.cs @@ -0,0 +1,12 @@ +using zero.Raven; + +namespace zero; + +public static class ZeroBuilderExtensions +{ + public static ZeroBuilder AddRavenDb(this ZeroBuilder builder) + { + builder.AddModule(); + return builder; + } +} \ No newline at end of file diff --git a/zero/Persistence/ZeroDocumentConventionsBuilder.cs b/zero.Raven/ZeroDocumentConventionsBuilder.cs similarity index 97% rename from zero/Persistence/ZeroDocumentConventionsBuilder.cs rename to zero.Raven/ZeroDocumentConventionsBuilder.cs index 423a11e2..3df1c23f 100644 --- a/zero/Persistence/ZeroDocumentConventionsBuilder.cs +++ b/zero.Raven/ZeroDocumentConventionsBuilder.cs @@ -2,8 +2,9 @@ using System.Collections.Concurrent; using System.Reflection; using System.Text; +using Rv = Raven.Client; -namespace zero.Persistence; +namespace zero.Raven; public class ZeroDocumentConventionsBuilder : IZeroDocumentConventionsBuilder { @@ -67,7 +68,7 @@ public class ZeroDocumentConventionsBuilder : IZeroDocumentConventionsBuilder }; // get inner type for revisions - if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Raven.Client.Documents.Subscriptions.Revision<>)) + if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Rv.Documents.Subscriptions.Revision<>)) { type = type.GetGenericArguments().FirstOrDefault(); } diff --git a/zero/Persistence/ZeroDocumentSession.cs b/zero.Raven/ZeroDocumentSession.cs similarity index 96% rename from zero/Persistence/ZeroDocumentSession.cs rename to zero.Raven/ZeroDocumentSession.cs index cf5b0d07..9f6bbe62 100644 --- a/zero/Persistence/ZeroDocumentSession.cs +++ b/zero.Raven/ZeroDocumentSession.cs @@ -1,7 +1,7 @@ using Raven.Client.Documents; using Raven.Client.Documents.Session; -namespace zero.Persistence; +namespace zero.Raven; public class ZeroDocumentSession : AsyncDocumentSession, IZeroDocumentSession { diff --git a/zero.Raven/ZeroDocumentSessionExtensions.cs b/zero.Raven/ZeroDocumentSessionExtensions.cs new file mode 100644 index 00000000..d009c2eb --- /dev/null +++ b/zero.Raven/ZeroDocumentSessionExtensions.cs @@ -0,0 +1,16 @@ +using Rv = Raven.Client; + +namespace zero.Raven; + +public static class ZeroDocumentSessionExtensions +{ + public static void SetCollection(this IZeroDocumentSession session, T model, string collectionName) + { + session.Advanced.GetMetadataFor(model)[Rv.Constants.Documents.Metadata.Collection] = collectionName; + } + + public static void Expires(this IZeroDocumentSession session, T model, TimeSpan expires) + { + session.Advanced.GetMetadataFor(model)[Rv.Constants.Documents.Metadata.Expires] = DateTime.UtcNow.AddSeconds(expires.TotalSeconds); + } +} \ No newline at end of file diff --git a/zero/Persistence/ZeroDocumentStore.cs b/zero.Raven/ZeroDocumentStore.cs similarity index 99% rename from zero/Persistence/ZeroDocumentStore.cs rename to zero.Raven/ZeroDocumentStore.cs index dea2b020..b8088861 100644 --- a/zero/Persistence/ZeroDocumentStore.cs +++ b/zero.Raven/ZeroDocumentStore.cs @@ -5,7 +5,7 @@ using Raven.Client.Documents.Operations; using Raven.Client.Documents.Queries; using Raven.Client.Documents.Session; -namespace zero.Persistence; +namespace zero.Raven; public class ZeroDocumentStore : DocumentStore, IZeroDocumentStore { diff --git a/zero/Persistence/ZeroPersistenceModule.cs b/zero.Raven/ZeroPersistenceModule.cs similarity index 85% rename from zero/Persistence/ZeroPersistenceModule.cs rename to zero.Raven/ZeroPersistenceModule.cs index b0a22629..f5893efa 100644 --- a/zero/Persistence/ZeroPersistenceModule.cs +++ b/zero.Raven/ZeroPersistenceModule.cs @@ -4,9 +4,9 @@ using Raven.Client.Documents; using Raven.Client.Documents.Indexes; using Raven.Client.Http; -namespace zero.Persistence; +namespace zero.Raven; -internal class ZeroPersistenceModule : ZeroModule +internal class ZeroRavenModule : ZeroModule { public override void ConfigureServices(IServiceCollection services, IConfiguration configuration) { @@ -16,6 +16,7 @@ internal class ZeroPersistenceModule : ZeroModule services.AddScoped(); services.AddScoped(); services.AddTransient(); + services.AddScoped(); services.AddOptions(); services.AddOptions().Bind(configuration.GetSection("Zero:Raven")); @@ -50,12 +51,10 @@ internal class ZeroPersistenceModule : ZeroModule IDocumentStore raven = store.Initialize(); // create all indexes - if (options.Initialized) - { - var indexes = ravenOptions.Indexes.BuildAll(options, store); - IndexCreation.CreateIndexes(indexes, store, database: ravenOptions.Database); - } + IEnumerable indexes = ravenOptions.Indexes.BuildAll(options, store); + IndexCreation.CreateIndexes(indexes, store, database: ravenOptions.Database); + return (ZeroDocumentStore)raven; } } \ No newline at end of file diff --git a/zero/Persistence/ZeroStore.cs b/zero.Raven/ZeroStore.cs similarity index 98% rename from zero/Persistence/ZeroStore.cs rename to zero.Raven/ZeroStore.cs index 90d287f6..9431b290 100644 --- a/zero/Persistence/ZeroStore.cs +++ b/zero.Raven/ZeroStore.cs @@ -1,6 +1,6 @@ using Raven.Client.Documents.Session; -namespace zero.Persistence; +namespace zero.Raven; public class ZeroStore : IZeroStore { diff --git a/zero.Raven/zero.Raven.csproj b/zero.Raven/zero.Raven.csproj new file mode 100644 index 00000000..9824c024 --- /dev/null +++ b/zero.Raven/zero.Raven.csproj @@ -0,0 +1,22 @@ + + + + zero.Raven + 1.0.0 + preview + net7.0 + true + zero.Raven + embedded + + + + + + + + + + + + \ No newline at end of file diff --git a/zero.sln b/zero.sln index 9aaf0b4b..11524066 100644 --- a/zero.sln +++ b/zero.sln @@ -17,6 +17,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "zero", "zero\zero.csproj", EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "legacy", "legacy", "{93A1CCEB-A323-445E-8116-4575C5939B46}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "zero.Raven", "zero.Raven\zero.Raven.csproj", "{DC79D7EA-FAA1-4701-9C36-8295CD1C45D0}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -43,6 +45,10 @@ Global {33CD6E46-CD81-42C3-9019-C0EAD557EE99}.Debug|Any CPU.Build.0 = Debug|Any CPU {33CD6E46-CD81-42C3-9019-C0EAD557EE99}.Release|Any CPU.ActiveCfg = Release|Any CPU {33CD6E46-CD81-42C3-9019-C0EAD557EE99}.Release|Any CPU.Build.0 = Release|Any CPU + {DC79D7EA-FAA1-4701-9C36-8295CD1C45D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DC79D7EA-FAA1-4701-9C36-8295CD1C45D0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DC79D7EA-FAA1-4701-9C36-8295CD1C45D0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DC79D7EA-FAA1-4701-9C36-8295CD1C45D0}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/zero/Communication/ZeroCommunicationModule.cs b/zero/Communication/ZeroCommunicationModule.cs index bd3a05c4..85396218 100644 --- a/zero/Communication/ZeroCommunicationModule.cs +++ b/zero/Communication/ZeroCommunicationModule.cs @@ -7,7 +7,6 @@ internal class ZeroCommunicationModule : ZeroModule { public override void ConfigureServices(IServiceCollection services, IConfiguration configuration) { - services.AddScoped(); services.AddScoped(); services.AddTransient(); services.AddTransient(typeof(Lazy<>), typeof(LazilyResolved<>)); diff --git a/zero/Configuration/ZeroOptions.cs b/zero/Configuration/ZeroOptions.cs index 19e0b611..483bf31a 100644 --- a/zero/Configuration/ZeroOptions.cs +++ b/zero/Configuration/ZeroOptions.cs @@ -6,9 +6,6 @@ namespace zero.Configuration; public class ZeroOptions : IZeroOptions { - /// - public bool Initialized => !string.IsNullOrEmpty(For()?.Database); - /// public string Version { get; set; } @@ -46,11 +43,6 @@ public interface IZeroOptions /// string Version { get; set; } - /// - /// Whether this zero instance is initialized (setup is completed) - /// - bool Initialized { get; } - /// /// Expiration of a generated change token for an entity /// diff --git a/zero/Context/ZeroContext.cs b/zero/Context/ZeroContext.cs index b7bfae84..7e92d0fd 100644 --- a/zero/Context/ZeroContext.cs +++ b/zero/Context/ZeroContext.cs @@ -9,10 +9,6 @@ public class ZeroContext : IZeroContext { /// public IZeroOptions Options { get; protected set; } - - /// - public IZeroStore Store { get; private set; } - /// public IServiceProvider Services { get; private set; } @@ -31,12 +27,11 @@ public class ZeroContext : IZeroContext public ZeroContext(IZeroOptions options, IHttpContextAccessor httpContextAccessor, ICultureResolver cultureResolver, - ILogger logger, IZeroStore store, IHandlerHolder handler, IServiceProvider services) + ILogger logger, IHandlerHolder handler, IServiceProvider services) { Options = options; CultureResolver = cultureResolver; Logger = logger; - Store = store; Handler = handler; ValueCollection = new PrimitiveTypeCollection(); HttpContextAccessor = httpContextAccessor; @@ -80,11 +75,6 @@ public interface IZeroContext /// IZeroOptions Options { get; } - /// - /// Document store - /// - IZeroStore Store { get; } - /// /// Service container /// diff --git a/zero/Localization/FileLocalizer.cs b/zero/Localization/FileLocalizer.cs new file mode 100644 index 00000000..c09a93b5 --- /dev/null +++ b/zero/Localization/FileLocalizer.cs @@ -0,0 +1,48 @@ +using System.IO; +using Microsoft.AspNetCore.Hosting; +using Newtonsoft.Json; +using System.Text; +using Microsoft.Extensions.Options; + +namespace zero.Localization; + +public class FileLocalizer : Localizer +{ + private List _fileList; + private IWebHostEnvironment _env; + + + public FileLocalizer(IWebHostEnvironment env, IOptionsMonitor options) : base() + { + _env = env; + LoadIntoCache(options.CurrentValue.FilePath); + options.OnChange((opts, _) => LoadIntoCache(opts.FilePath)); + } + + + protected void LoadIntoCache(string filePath) + { + string path = Path.Combine(_env.ContentRootPath, filePath); + + if (!File.Exists(path)) + { + _fileList = new(); + } + else + { + Dictionary texts = JsonConvert.DeserializeObject>(File.ReadAllText(path, Encoding.Latin1)); + _fileList = texts.Select(kvp => new Translation() { Key = kvp.Key, Value = kvp.Value }).ToList(); + } + } + + + protected override Translation LoadTranslation(string key) + { + //return new Translation() + //{ + // Value = "{@" + key + "}" + //}; + + return _fileList.FirstOrDefault(x => x.Key == key); + } +} \ No newline at end of file diff --git a/zero/Localization/LocalizationOptions.cs b/zero/Localization/LocalizationOptions.cs new file mode 100644 index 00000000..1302660c --- /dev/null +++ b/zero/Localization/LocalizationOptions.cs @@ -0,0 +1,6 @@ +namespace zero.Localization; + +public class LocalizationOptions +{ + public string FilePath { get; set; } +} \ No newline at end of file diff --git a/zero/Localization/Localizer.cs b/zero/Localization/Localizer.cs index d4eb9929..de07d020 100644 --- a/zero/Localization/Localizer.cs +++ b/zero/Localization/Localizer.cs @@ -3,17 +3,10 @@ using System.Reflection; namespace zero.Localization; -public class Localizer : ILocalizer +public abstract class Localizer : ILocalizer { protected ConcurrentDictionary Cache { get; private set; } = new(); - protected IRavenOperations Raven { get; private set; } - - public Localizer(IRavenOperations raven) - { - Raven = raven; - } - /// public string Text(string key) => Text(key, null); @@ -76,10 +69,7 @@ public class Localizer : ILocalizer /// /// Get translation from database or any other source /// - protected virtual Translation LoadTranslation(string key) - { - return Raven.Session.Synchronous.Query().FirstOrDefault(x => x.Key == key); - } + protected abstract Translation LoadTranslation(string key); } public interface ILocalizer diff --git a/zero/Localization/Models/Translation.cs b/zero/Localization/Models/Translation.cs index 0d893918..0a635d69 100644 --- a/zero/Localization/Models/Translation.cs +++ b/zero/Localization/Models/Translation.cs @@ -1,13 +1,12 @@ namespace zero.Localization; -[RavenCollection("Translations")] -public class Translation : ZeroEntity, IAlwaysActive +public class Translation { - public Translation() - { - IsActive = true; - } - + /// + /// Key of the translation + /// + public string Key { get; set; } + /// /// Value of the translation /// @@ -23,5 +22,5 @@ public class Translation : ZeroEntity, IAlwaysActive public enum TranslationDisplay { Text = 0, - HTML = 1 + Html = 1 } \ No newline at end of file diff --git a/zero/Localization/ZeroLocalizationModule.cs b/zero/Localization/ZeroLocalizationModule.cs index 1a6c7935..2d6826b6 100644 --- a/zero/Localization/ZeroLocalizationModule.cs +++ b/zero/Localization/ZeroLocalizationModule.cs @@ -10,6 +10,11 @@ internal class ZeroLocalizationModule : ZeroModule { services.AddScoped(); services.AddScoped(); - services.AddScoped(); + services.AddScoped(); + + services.AddOptions().Bind(configuration.GetSection("Zero:Localization")).Configure(opts => + { + opts.FilePath = "Config/texts.json"; + }); } } \ No newline at end of file diff --git a/zero/Models/ISupportsDbConventions.cs b/zero/Models/ISupportsDbConventions.cs new file mode 100644 index 00000000..309576c8 --- /dev/null +++ b/zero/Models/ISupportsDbConventions.cs @@ -0,0 +1,6 @@ +namespace zero.Models; + +/// +/// Triggers custom conventions for database operations +/// +public interface ISupportsDbConventions { } \ No newline at end of file diff --git a/zero/Persistence/ISupportsDbConventions.cs b/zero/Persistence/ISupportsDbConventions.cs deleted file mode 100644 index 1ce4ec3b..00000000 --- a/zero/Persistence/ISupportsDbConventions.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace zero.Persistence; - -/// -/// Triggers custom Raven conventions for database operations -/// -public interface ISupportsDbConventions { } \ No newline at end of file diff --git a/zero/Persistence/ZeroDocumentSessionExtensions.cs b/zero/Persistence/ZeroDocumentSessionExtensions.cs deleted file mode 100644 index 57704f01..00000000 --- a/zero/Persistence/ZeroDocumentSessionExtensions.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace zero.Persistence; - -public static class ZeroDocumentSessionExtensions -{ - public static void SetCollection(this IZeroDocumentSession session, T model, string collectionName) - { - session.Advanced.GetMetadataFor(model)[Raven.Client.Constants.Documents.Metadata.Collection] = collectionName; - } - - public static void Expires(this IZeroDocumentSession session, T model, TimeSpan expires) - { - session.Advanced.GetMetadataFor(model)[Raven.Client.Constants.Documents.Metadata.Expires] = DateTime.UtcNow.AddSeconds(expires.TotalSeconds); - } -} \ No newline at end of file diff --git a/zero/Usings.cs b/zero/Usings.cs index 849d9c67..c647c926 100644 --- a/zero/Usings.cs +++ b/zero/Usings.cs @@ -6,7 +6,7 @@ global using System.Linq; global using System.Threading; global using System.Threading.Tasks; -global using zero.Persistence; +//global using zero.Persistence; global using zero.Utils; global using zero.Configuration; global using zero.Extensions; diff --git a/zero/Validation/ValidatorExtensions.cs b/zero/Validation/ValidatorExtensions.cs index 68dfe4f3..0e9e4a7e 100644 --- a/zero/Validation/ValidatorExtensions.cs +++ b/zero/Validation/ValidatorExtensions.cs @@ -114,64 +114,4 @@ public static class ValidatorExtensions } }).WithMessage("@errors.forms.culture"); } - - - - - /// - /// Check if this value is unique within a collection - /// - public static IRuleBuilderOptions Unique(this IRuleBuilder ruleBuilder, IZeroStore store) where T : ZeroEntity - { - return ruleBuilder.MustAsync(async (entity, value, context, cancellation) => - { - bool any = await store.Session().Advanced.AsyncDocumentQuery() - .WhereNotEquals(nameof(ZeroIdEntity.Id), entity.Id) - .WhereEquals(context.PropertyName.ToPascalCaseId(), value) - .AnyAsync(cancellation); - - return !any; - }).WithMessage("@errors.forms.not_unique"); - } - - - /// - /// Check if this value is at least set once to the expected value within a collection - /// - public static IRuleBuilderOptions ExpectAnyUnique(this IRuleBuilder ruleBuilder, IZeroStore store, TProperty expectedValue) where T : ZeroEntity - { - return ruleBuilder.MustAsync(async (entity, value, context, cancellation) => - { - return await store.Session().Advanced.AsyncDocumentQuery() - .WhereNotEquals(nameof(ZeroIdEntity.Id), entity.Id) - .WhereEquals(context.PropertyName.ToPascalCaseId(), expectedValue) - .AnyAsync(cancellation); - }).WithMessage("@errors.forms.not_unique_alone"); - } - - - /// - /// Check if this reference exists and is an entity which can be referenced (appId = shared for shareable entities or appId = current) - /// - public static IRuleBuilderOptions Exists(this IRuleBuilder ruleBuilder, IZeroStore store) where T : ZeroEntity - { - return ruleBuilder.Exists(store); - } - - - /// - /// Check if this reference exists and is an entity which can be referenced (appId = shared for shareable entities or appId = current) - /// - public static IRuleBuilderOptions Exists(this IRuleBuilder ruleBuilder, IZeroStore store) where T : ZeroEntity where TReference : ZeroEntity - { - return ruleBuilder.MustAsync(async (entity, id, context, cancellation) => - { - if (id.IsNullOrWhiteSpace()) - { - return true; - } - - return await store.Session().Query().AnyAsync(x => x.Id == id); - }).WithMessage("@errors.forms.reference_notfound"); - } } diff --git a/zero/ZeroBuilder.cs b/zero/ZeroBuilder.cs index 5978e0b3..deafab10 100644 --- a/zero/ZeroBuilder.cs +++ b/zero/ZeroBuilder.cs @@ -47,7 +47,6 @@ public class ZeroBuilder //Modules.Add(); //Modules.Add(); //Modules.Add(); - Modules.Add(); Modules.Add(); //Modules.Add(); @@ -66,4 +65,21 @@ public class ZeroBuilder Services.Configure(configureOptions); return this; } + + + public ZeroBuilder AddModule(IZeroModule module) + { + module.ConfigureServices(Services, _configuration); + Modules.Add(module); + return this; + } + + + public ZeroBuilder AddModule() where T : class, IZeroModule, new() + { + T module = new(); + module.ConfigureServices(Services, _configuration); + Modules.Add(module); + return this; + } }