From cd187f93c1b9b002e5242f769fe12f382be118c8 Mon Sep 17 00:00:00 2001 From: Akash Jadhav Date: Sun, 28 May 2023 15:26:49 +0530 Subject: [PATCH] Schema Name editable in V3 (#4072) * add ElsaDbContextOptions * set Schema from elsaDbContextOptions * file rename * add options as arg to DbContextOptionsBuilderExtensions * add options to module extensions in Elsa.EntityFrameworkCore.MySql * add options to module extensions in Elsa.EntityFrameworkCore.PostgreSql * add options to module extensions in Elsa.EntityFrameworkCore.Sqlite * add options to module extensions in Elsa.EntityFrameworkCore.SqlServer * add validations * update doc strings --- .../DbContextOptionsBuilderExtensions.cs | 10 +++--- .../Modules/Identity/Extensions.cs | 6 ++-- .../Modules/Labels/Extensions.cs | 5 +-- .../Modules/Management/Extensions.cs | 13 ++++---- .../Modules/Runtime/Extensions.cs | 9 +++--- ...stgreSqlDesignTimeDbContextFactoryBase.cs} | 0 .../DbContextOptionsBuilderExtensions.cs | 10 +++--- .../Modules/Identity/Extensions.cs | 8 +++-- .../Modules/Labels/Extensions.cs | 7 ++-- .../Modules/Management/Extensions.cs | 15 +++++---- .../Modules/Runtime/Extensions.cs | 11 ++++--- .../DbContextOptionsBuilderExtensions.cs | 10 +++--- .../Modules/Identity/Extensions.cs | 8 +++-- .../Modules/Labels/Extensions.cs | 7 ++-- .../Modules/Management/Extensions.cs | 15 +++++---- .../Modules/Runtime/Extensions.cs | 11 ++++--- .../DbContextOptionsBuilderExtensions.cs | 10 +++--- .../Modules/Identity/Extensions.cs | 8 +++-- .../Modules/Labels/Extensions.cs | 7 ++-- .../Modules/Management/Extensions.cs | 15 +++++---- .../Modules/Runtime/Extensions.cs | 15 +++++---- .../CustomDbContextOptionsExtensionInfo.cs | 30 +++++++++++++++++ .../Common/ElsaDbContextBase.cs | 10 +++--- .../Common/ElsaDbContextOptions.cs | 8 +++++ .../Common/ElsaDbContextOptionsExtension.cs | 32 +++++++++++++++++++ .../Common/ElsaDbContextOptionsExtensions.cs | 17 ++++++++++ 26 files changed, 207 insertions(+), 90 deletions(-) rename src/modules/Elsa.EntityFrameworkCore.PostgreSql/Abstractions/{SqlServerDesignTimeDbContextFactoryBase.cs => PostgreSqlDesignTimeDbContextFactoryBase.cs} (100%) create mode 100644 src/modules/Elsa.EntityFrameworkCore/Common/CustomDbContextOptionsExtensionInfo.cs create mode 100644 src/modules/Elsa.EntityFrameworkCore/Common/ElsaDbContextOptions.cs create mode 100644 src/modules/Elsa.EntityFrameworkCore/Common/ElsaDbContextOptionsExtension.cs create mode 100644 src/modules/Elsa.EntityFrameworkCore/Common/ElsaDbContextOptionsExtensions.cs diff --git a/src/modules/Elsa.EntityFrameworkCore.MySql/Extensions/DbContextOptionsBuilderExtensions.cs b/src/modules/Elsa.EntityFrameworkCore.MySql/Extensions/DbContextOptionsBuilderExtensions.cs index 2c82ee2350..802551b206 100644 --- a/src/modules/Elsa.EntityFrameworkCore.MySql/Extensions/DbContextOptionsBuilderExtensions.cs +++ b/src/modules/Elsa.EntityFrameworkCore.MySql/Extensions/DbContextOptionsBuilderExtensions.cs @@ -8,12 +8,14 @@ namespace Elsa.EntityFrameworkCore.Extensions; public static class DbContextOptionsBuilderExtensions { - public static DbContextOptionsBuilder UseElsaMySql(this DbContextOptionsBuilder builder, string connectionString, Action? configure = default) => - builder.UseMySql(connectionString, ServerVersion.AutoDetect(connectionString), db => + public static DbContextOptionsBuilder UseElsaMySql(this DbContextOptionsBuilder builder, string connectionString,ElsaDbContextOptions? options = default, Action? configure = default) => + builder + .UseElsaDbContextOptions(options) + .UseMySql(connectionString, ServerVersion.AutoDetect(connectionString), db => { db - .MigrationsAssembly(typeof(DbContextOptionsBuilderExtensions).Assembly.GetName().Name) - .MigrationsHistoryTable(ElsaDbContextBase.MigrationsHistoryTable, ElsaDbContextBase.ElsaSchema) + .MigrationsAssembly(options?.MigrationsAssemblyName ?? typeof(DbContextOptionsBuilderExtensions).Assembly.GetName().Name) + .MigrationsHistoryTable(options?.MigrationsHistoryTableName ?? ElsaDbContextBase.MigrationsHistoryTable, options?.SchemaName ?? ElsaDbContextBase.ElsaSchema) .SchemaBehavior(MySqlSchemaBehavior.Ignore); configure?.Invoke(db); diff --git a/src/modules/Elsa.EntityFrameworkCore.MySql/Modules/Identity/Extensions.cs b/src/modules/Elsa.EntityFrameworkCore.MySql/Modules/Identity/Extensions.cs index 37eb99c4a7..e848403c40 100644 --- a/src/modules/Elsa.EntityFrameworkCore.MySql/Modules/Identity/Extensions.cs +++ b/src/modules/Elsa.EntityFrameworkCore.MySql/Modules/Identity/Extensions.cs @@ -1,4 +1,5 @@ using Elsa.EntityFrameworkCore.Modules.Identity; +using Elsa.EntityFrameworkCore.Common; // ReSharper disable once CheckNamespace namespace Elsa.EntityFrameworkCore.Extensions; @@ -10,10 +11,11 @@ public static partial class Extensions /// /// The feature to configure. /// The connection string to use. + /// Options specified via allows to configure for manual database migrations. /// The configured feature. - public static EFCoreIdentityPersistenceFeature UseMySql(this EFCoreIdentityPersistenceFeature feature, string connectionString) + public static EFCoreIdentityPersistenceFeature UseMySql(this EFCoreIdentityPersistenceFeature feature, string connectionString, ElsaDbContextOptions? options = default) { - feature.DbContextOptionsBuilder = (_, db) => db.UseElsaMySql(connectionString); + feature.DbContextOptionsBuilder = (_, db) => db.UseElsaMySql(connectionString, options); return feature; } } \ No newline at end of file diff --git a/src/modules/Elsa.EntityFrameworkCore.MySql/Modules/Labels/Extensions.cs b/src/modules/Elsa.EntityFrameworkCore.MySql/Modules/Labels/Extensions.cs index 49f8bb17c2..658d08a556 100644 --- a/src/modules/Elsa.EntityFrameworkCore.MySql/Modules/Labels/Extensions.cs +++ b/src/modules/Elsa.EntityFrameworkCore.MySql/Modules/Labels/Extensions.cs @@ -1,13 +1,14 @@ using Elsa.EntityFrameworkCore.Modules.Labels; +using Elsa.EntityFrameworkCore.Common; // ReSharper disable once CheckNamespace namespace Elsa.EntityFrameworkCore.Extensions; public static partial class Extensions { - public static EFCoreLabelPersistenceFeature UseMySql(this EFCoreLabelPersistenceFeature feature, string connectionString) + public static EFCoreLabelPersistenceFeature UseMySql(this EFCoreLabelPersistenceFeature feature, string connectionString, ElsaDbContextOptions? options = default) { - feature.DbContextOptionsBuilder = (_, db) => db.UseElsaMySql(connectionString); + feature.DbContextOptionsBuilder = (_, db) => db.UseElsaMySql(connectionString, options); return feature; } } \ No newline at end of file diff --git a/src/modules/Elsa.EntityFrameworkCore.MySql/Modules/Management/Extensions.cs b/src/modules/Elsa.EntityFrameworkCore.MySql/Modules/Management/Extensions.cs index 6af28a9208..4ec08fc854 100644 --- a/src/modules/Elsa.EntityFrameworkCore.MySql/Modules/Management/Extensions.cs +++ b/src/modules/Elsa.EntityFrameworkCore.MySql/Modules/Management/Extensions.cs @@ -1,4 +1,5 @@ using Elsa.EntityFrameworkCore.Modules.Management; +using Elsa.EntityFrameworkCore.Common; using JetBrains.Annotations; // ReSharper disable once CheckNamespace @@ -10,21 +11,21 @@ namespace Elsa.EntityFrameworkCore.Extensions; [PublicAPI] public static partial class Extensions { - public static EFCoreWorkflowDefinitionPersistenceFeature UseMySql(this EFCoreWorkflowDefinitionPersistenceFeature feature, string connectionString) + public static EFCoreWorkflowDefinitionPersistenceFeature UseMySql(this EFCoreWorkflowDefinitionPersistenceFeature feature, string connectionString, ElsaDbContextOptions? options = default) { - feature.DbContextOptionsBuilder = (_, db) => db.UseElsaMySql(connectionString); + feature.DbContextOptionsBuilder = (_, db) => db.UseElsaMySql(connectionString, options); return feature; } - public static EFCoreWorkflowInstancePersistenceFeature UseMySql(this EFCoreWorkflowInstancePersistenceFeature feature, string connectionString) + public static EFCoreWorkflowInstancePersistenceFeature UseMySql(this EFCoreWorkflowInstancePersistenceFeature feature, string connectionString, ElsaDbContextOptions? options = default) { - feature.DbContextOptionsBuilder = (_, db) => db.UseElsaMySql(connectionString); + feature.DbContextOptionsBuilder = (_, db) => db.UseElsaMySql(connectionString, options); return feature; } - public static EFCoreWorkflowManagementPersistenceFeature UseMySql(this EFCoreWorkflowManagementPersistenceFeature feature, string connectionString) + public static EFCoreWorkflowManagementPersistenceFeature UseMySql(this EFCoreWorkflowManagementPersistenceFeature feature, string connectionString, ElsaDbContextOptions? options = default) { - feature.DbContextOptionsBuilder = (_, db) => db.UseElsaMySql(connectionString); + feature.DbContextOptionsBuilder = (_, db) => db.UseElsaMySql(connectionString, options); return feature; } } \ No newline at end of file diff --git a/src/modules/Elsa.EntityFrameworkCore.MySql/Modules/Runtime/Extensions.cs b/src/modules/Elsa.EntityFrameworkCore.MySql/Modules/Runtime/Extensions.cs index c73fca49c3..f30781a86b 100644 --- a/src/modules/Elsa.EntityFrameworkCore.MySql/Modules/Runtime/Extensions.cs +++ b/src/modules/Elsa.EntityFrameworkCore.MySql/Modules/Runtime/Extensions.cs @@ -1,19 +1,20 @@ using Elsa.EntityFrameworkCore.Modules.Runtime; +using Elsa.EntityFrameworkCore.Common; // ReSharper disable once CheckNamespace namespace Elsa.EntityFrameworkCore.Extensions; public static partial class Extensions { - public static EFCoreDefaultWorkflowRuntimePersistenceFeature UseMySql(this EFCoreDefaultWorkflowRuntimePersistenceFeature feature, string connectionString) + public static EFCoreDefaultWorkflowRuntimePersistenceFeature UseMySql(this EFCoreDefaultWorkflowRuntimePersistenceFeature feature, string connectionString, ElsaDbContextOptions? options = default) { - feature.DbContextOptionsBuilder = (_, db) => db.UseElsaMySql(connectionString); + feature.DbContextOptionsBuilder = (_, db) => db.UseElsaMySql(connectionString, options); return feature; } - public static EFCoreExecutionLogRecordPersistenceFeature UseMySql(this EFCoreExecutionLogRecordPersistenceFeature feature, string connectionString) + public static EFCoreExecutionLogRecordPersistenceFeature UseMySql(this EFCoreExecutionLogRecordPersistenceFeature feature, string connectionString, ElsaDbContextOptions? options = default) { - feature.DbContextOptionsBuilder = (_, db) => db.UseElsaMySql(connectionString); + feature.DbContextOptionsBuilder = (_, db) => db.UseElsaMySql(connectionString, options); return feature; } } \ No newline at end of file diff --git a/src/modules/Elsa.EntityFrameworkCore.PostgreSql/Abstractions/SqlServerDesignTimeDbContextFactoryBase.cs b/src/modules/Elsa.EntityFrameworkCore.PostgreSql/Abstractions/PostgreSqlDesignTimeDbContextFactoryBase.cs similarity index 100% rename from src/modules/Elsa.EntityFrameworkCore.PostgreSql/Abstractions/SqlServerDesignTimeDbContextFactoryBase.cs rename to src/modules/Elsa.EntityFrameworkCore.PostgreSql/Abstractions/PostgreSqlDesignTimeDbContextFactoryBase.cs diff --git a/src/modules/Elsa.EntityFrameworkCore.PostgreSql/Extensions/DbContextOptionsBuilderExtensions.cs b/src/modules/Elsa.EntityFrameworkCore.PostgreSql/Extensions/DbContextOptionsBuilderExtensions.cs index e92895aae6..d5e52347ef 100644 --- a/src/modules/Elsa.EntityFrameworkCore.PostgreSql/Extensions/DbContextOptionsBuilderExtensions.cs +++ b/src/modules/Elsa.EntityFrameworkCore.PostgreSql/Extensions/DbContextOptionsBuilderExtensions.cs @@ -7,12 +7,14 @@ namespace Elsa.EntityFrameworkCore.Extensions; public static class DbContextOptionsBuilderExtensions { - public static DbContextOptionsBuilder UseElsaPostgreSql(this DbContextOptionsBuilder builder, string connectionString, Action? configure = default) => - builder.UseNpgsql(connectionString, db => + public static DbContextOptionsBuilder UseElsaPostgreSql(this DbContextOptionsBuilder builder, string connectionString,ElsaDbContextOptions? options = default, Action? configure = default) => + builder + .UseElsaDbContextOptions(options) + .UseNpgsql(connectionString, db => { db - .MigrationsAssembly(typeof(DbContextOptionsBuilderExtensions).Assembly.GetName().Name) - .MigrationsHistoryTable(ElsaDbContextBase.MigrationsHistoryTable, ElsaDbContextBase.ElsaSchema); + .MigrationsAssembly(options?.MigrationsAssemblyName ?? typeof(DbContextOptionsBuilderExtensions).Assembly.GetName().Name) + .MigrationsHistoryTable(options?.MigrationsHistoryTableName ?? ElsaDbContextBase.MigrationsHistoryTable, options?.SchemaName ?? ElsaDbContextBase.ElsaSchema); configure?.Invoke(db); }); diff --git a/src/modules/Elsa.EntityFrameworkCore.PostgreSql/Modules/Identity/Extensions.cs b/src/modules/Elsa.EntityFrameworkCore.PostgreSql/Modules/Identity/Extensions.cs index f0b5d92691..9a52d0b198 100644 --- a/src/modules/Elsa.EntityFrameworkCore.PostgreSql/Modules/Identity/Extensions.cs +++ b/src/modules/Elsa.EntityFrameworkCore.PostgreSql/Modules/Identity/Extensions.cs @@ -1,4 +1,5 @@ -using Elsa.EntityFrameworkCore.Modules.Identity; +using Elsa.EntityFrameworkCore.Common; +using Elsa.EntityFrameworkCore.Modules.Identity; // ReSharper disable once CheckNamespace namespace Elsa.EntityFrameworkCore.Extensions; @@ -10,10 +11,11 @@ public static partial class Extensions /// /// The feature to configure. /// The connection string to use. + /// Options specified via allows to configure for manual database migrations. /// The configured feature. - public static EFCoreIdentityPersistenceFeature UsePostgreSql(this EFCoreIdentityPersistenceFeature feature, string connectionString) + public static EFCoreIdentityPersistenceFeature UsePostgreSql(this EFCoreIdentityPersistenceFeature feature, string connectionString, ElsaDbContextOptions? options = default) { - feature.DbContextOptionsBuilder = (_, db) => db.UseElsaPostgreSql(connectionString); + feature.DbContextOptionsBuilder = (_, db) => db.UseElsaPostgreSql(connectionString, options); return feature; } } \ No newline at end of file diff --git a/src/modules/Elsa.EntityFrameworkCore.PostgreSql/Modules/Labels/Extensions.cs b/src/modules/Elsa.EntityFrameworkCore.PostgreSql/Modules/Labels/Extensions.cs index 0c60603cbf..ef78f78047 100644 --- a/src/modules/Elsa.EntityFrameworkCore.PostgreSql/Modules/Labels/Extensions.cs +++ b/src/modules/Elsa.EntityFrameworkCore.PostgreSql/Modules/Labels/Extensions.cs @@ -1,13 +1,14 @@ -using Elsa.EntityFrameworkCore.Modules.Labels; +using Elsa.EntityFrameworkCore.Common; +using Elsa.EntityFrameworkCore.Modules.Labels; // ReSharper disable once CheckNamespace namespace Elsa.EntityFrameworkCore.Extensions; public static partial class Extensions { - public static EFCoreLabelPersistenceFeature UsePostgreSql(this EFCoreLabelPersistenceFeature feature, string connectionString) + public static EFCoreLabelPersistenceFeature UsePostgreSql(this EFCoreLabelPersistenceFeature feature, string connectionString, ElsaDbContextOptions? options = default) { - feature.DbContextOptionsBuilder = (_, db) => db.UseElsaPostgreSql(connectionString); + feature.DbContextOptionsBuilder = (_, db) => db.UseElsaPostgreSql(connectionString, options); return feature; } } \ No newline at end of file diff --git a/src/modules/Elsa.EntityFrameworkCore.PostgreSql/Modules/Management/Extensions.cs b/src/modules/Elsa.EntityFrameworkCore.PostgreSql/Modules/Management/Extensions.cs index 36b288d203..90159d0e9c 100644 --- a/src/modules/Elsa.EntityFrameworkCore.PostgreSql/Modules/Management/Extensions.cs +++ b/src/modules/Elsa.EntityFrameworkCore.PostgreSql/Modules/Management/Extensions.cs @@ -1,4 +1,5 @@ -using Elsa.EntityFrameworkCore.Modules.Management; +using Elsa.EntityFrameworkCore.Common; +using Elsa.EntityFrameworkCore.Modules.Management; using JetBrains.Annotations; // ReSharper disable once CheckNamespace @@ -10,21 +11,21 @@ namespace Elsa.EntityFrameworkCore.Extensions; [PublicAPI] public static partial class Extensions { - public static EFCoreWorkflowDefinitionPersistenceFeature UsePostgreSql(this EFCoreWorkflowDefinitionPersistenceFeature feature, string connectionString) + public static EFCoreWorkflowDefinitionPersistenceFeature UsePostgreSql(this EFCoreWorkflowDefinitionPersistenceFeature feature, string connectionString, ElsaDbContextOptions? options = default) { - feature.DbContextOptionsBuilder = (_, db) => db.UseElsaPostgreSql(connectionString); + feature.DbContextOptionsBuilder = (_, db) => db.UseElsaPostgreSql(connectionString, options); return feature; } - public static EFCoreWorkflowInstancePersistenceFeature UsePostgreSql(this EFCoreWorkflowInstancePersistenceFeature feature, string connectionString) + public static EFCoreWorkflowInstancePersistenceFeature UsePostgreSql(this EFCoreWorkflowInstancePersistenceFeature feature, string connectionString, ElsaDbContextOptions? options = default) { - feature.DbContextOptionsBuilder = (_, db) => db.UseElsaPostgreSql(connectionString); + feature.DbContextOptionsBuilder = (_, db) => db.UseElsaPostgreSql(connectionString, options); return feature; } - public static EFCoreWorkflowManagementPersistenceFeature UsePostgreSql(this EFCoreWorkflowManagementPersistenceFeature feature, string connectionString) + public static EFCoreWorkflowManagementPersistenceFeature UsePostgreSql(this EFCoreWorkflowManagementPersistenceFeature feature, string connectionString, ElsaDbContextOptions? options = default) { - feature.DbContextOptionsBuilder = (_, db) => db.UseElsaPostgreSql(connectionString); + feature.DbContextOptionsBuilder = (_, db) => db.UseElsaPostgreSql(connectionString, options); return feature; } } \ No newline at end of file diff --git a/src/modules/Elsa.EntityFrameworkCore.PostgreSql/Modules/Runtime/Extensions.cs b/src/modules/Elsa.EntityFrameworkCore.PostgreSql/Modules/Runtime/Extensions.cs index 3b10929cd4..6fbf42eac7 100644 --- a/src/modules/Elsa.EntityFrameworkCore.PostgreSql/Modules/Runtime/Extensions.cs +++ b/src/modules/Elsa.EntityFrameworkCore.PostgreSql/Modules/Runtime/Extensions.cs @@ -1,19 +1,20 @@ -using Elsa.EntityFrameworkCore.Modules.Runtime; +using Elsa.EntityFrameworkCore.Common; +using Elsa.EntityFrameworkCore.Modules.Runtime; // ReSharper disable once CheckNamespace namespace Elsa.EntityFrameworkCore.Extensions; public static partial class Extensions { - public static EFCoreDefaultWorkflowRuntimePersistenceFeature UsePostgreSql(this EFCoreDefaultWorkflowRuntimePersistenceFeature feature, string connectionString) + public static EFCoreDefaultWorkflowRuntimePersistenceFeature UsePostgreSql(this EFCoreDefaultWorkflowRuntimePersistenceFeature feature, string connectionString, ElsaDbContextOptions? options = default) { - feature.DbContextOptionsBuilder = (_, db) => db.UseElsaPostgreSql(connectionString); + feature.DbContextOptionsBuilder = (_, db) => db.UseElsaPostgreSql(connectionString, options); return feature; } - public static EFCoreExecutionLogRecordPersistenceFeature UsePostgreSql(this EFCoreExecutionLogRecordPersistenceFeature feature, string connectionString) + public static EFCoreExecutionLogRecordPersistenceFeature UsePostgreSql(this EFCoreExecutionLogRecordPersistenceFeature feature, string connectionString, ElsaDbContextOptions? options = default) { - feature.DbContextOptionsBuilder = (_, db) => db.UseElsaPostgreSql(connectionString); + feature.DbContextOptionsBuilder = (_, db) => db.UseElsaPostgreSql(connectionString, options); return feature; } } \ No newline at end of file diff --git a/src/modules/Elsa.EntityFrameworkCore.SqlServer/Extensions/DbContextOptionsBuilderExtensions.cs b/src/modules/Elsa.EntityFrameworkCore.SqlServer/Extensions/DbContextOptionsBuilderExtensions.cs index 04988bd7bc..5de2789927 100644 --- a/src/modules/Elsa.EntityFrameworkCore.SqlServer/Extensions/DbContextOptionsBuilderExtensions.cs +++ b/src/modules/Elsa.EntityFrameworkCore.SqlServer/Extensions/DbContextOptionsBuilderExtensions.cs @@ -7,12 +7,14 @@ namespace Elsa.EntityFrameworkCore.Extensions; public static class DbContextOptionsBuilderExtensions { - public static DbContextOptionsBuilder UseElsaSqlServer(this DbContextOptionsBuilder builder, string connectionString, Action? configure = default) => - builder.UseSqlServer(connectionString, db => + public static DbContextOptionsBuilder UseElsaSqlServer(this DbContextOptionsBuilder builder, string connectionString, ElsaDbContextOptions? options = default, Action? configure = default) => + builder + .UseElsaDbContextOptions(options) + .UseSqlServer(connectionString, db => { db - .MigrationsAssembly(typeof(DbContextOptionsBuilderExtensions).Assembly.GetName().Name) - .MigrationsHistoryTable(ElsaDbContextBase.MigrationsHistoryTable, ElsaDbContextBase.ElsaSchema); + .MigrationsAssembly(options?.MigrationsAssemblyName ?? typeof(DbContextOptionsBuilderExtensions).Assembly.GetName().Name) + .MigrationsHistoryTable(options?.MigrationsHistoryTableName ?? ElsaDbContextBase.MigrationsHistoryTable, options?.SchemaName ?? ElsaDbContextBase.ElsaSchema); configure?.Invoke(db); }); diff --git a/src/modules/Elsa.EntityFrameworkCore.SqlServer/Modules/Identity/Extensions.cs b/src/modules/Elsa.EntityFrameworkCore.SqlServer/Modules/Identity/Extensions.cs index ae30a87e4a..9dac72b7e9 100644 --- a/src/modules/Elsa.EntityFrameworkCore.SqlServer/Modules/Identity/Extensions.cs +++ b/src/modules/Elsa.EntityFrameworkCore.SqlServer/Modules/Identity/Extensions.cs @@ -1,4 +1,5 @@ -using Elsa.EntityFrameworkCore.Modules.Identity; +using Elsa.EntityFrameworkCore.Common; +using Elsa.EntityFrameworkCore.Modules.Identity; // ReSharper disable once CheckNamespace namespace Elsa.EntityFrameworkCore.Extensions; @@ -13,10 +14,11 @@ public static partial class Extensions /// /// The feature to configure. /// The connection string to use. + /// Options specified via allows to configure for manual database migrations. /// The configured feature. - public static EFCoreIdentityPersistenceFeature UseSqlServer(this EFCoreIdentityPersistenceFeature feature, string connectionString) + public static EFCoreIdentityPersistenceFeature UseSqlServer(this EFCoreIdentityPersistenceFeature feature, string connectionString, ElsaDbContextOptions? options = default) { - feature.DbContextOptionsBuilder = (_, db) => db.UseElsaSqlServer(connectionString); + feature.DbContextOptionsBuilder = (_, db) => db.UseElsaSqlServer(connectionString, options); return feature; } } \ No newline at end of file diff --git a/src/modules/Elsa.EntityFrameworkCore.SqlServer/Modules/Labels/Extensions.cs b/src/modules/Elsa.EntityFrameworkCore.SqlServer/Modules/Labels/Extensions.cs index 00bf80245f..8e62458fbc 100644 --- a/src/modules/Elsa.EntityFrameworkCore.SqlServer/Modules/Labels/Extensions.cs +++ b/src/modules/Elsa.EntityFrameworkCore.SqlServer/Modules/Labels/Extensions.cs @@ -1,13 +1,14 @@ -using Elsa.EntityFrameworkCore.Modules.Labels; +using Elsa.EntityFrameworkCore.Common; +using Elsa.EntityFrameworkCore.Modules.Labels; // ReSharper disable once CheckNamespace namespace Elsa.EntityFrameworkCore.Extensions; public static partial class Extensions { - public static EFCoreLabelPersistenceFeature UseSqlServer(this EFCoreLabelPersistenceFeature feature, string connectionString) + public static EFCoreLabelPersistenceFeature UseSqlServer(this EFCoreLabelPersistenceFeature feature, string connectionString, ElsaDbContextOptions? options = default) { - feature.DbContextOptionsBuilder = (_, db) => db.UseElsaSqlServer(connectionString); + feature.DbContextOptionsBuilder = (_, db) => db.UseElsaSqlServer(connectionString, options); return feature; } } \ No newline at end of file diff --git a/src/modules/Elsa.EntityFrameworkCore.SqlServer/Modules/Management/Extensions.cs b/src/modules/Elsa.EntityFrameworkCore.SqlServer/Modules/Management/Extensions.cs index 0b165f2ea2..192a048511 100644 --- a/src/modules/Elsa.EntityFrameworkCore.SqlServer/Modules/Management/Extensions.cs +++ b/src/modules/Elsa.EntityFrameworkCore.SqlServer/Modules/Management/Extensions.cs @@ -1,4 +1,5 @@ -using Elsa.EntityFrameworkCore.Modules.Management; +using Elsa.EntityFrameworkCore.Common; +using Elsa.EntityFrameworkCore.Modules.Management; using JetBrains.Annotations; // ReSharper disable once CheckNamespace @@ -7,21 +8,21 @@ namespace Elsa.EntityFrameworkCore.Extensions; [PublicAPI] public static partial class Extensions { - public static EFCoreWorkflowDefinitionPersistenceFeature UseSqlServer(this EFCoreWorkflowDefinitionPersistenceFeature feature, string connectionString) + public static EFCoreWorkflowDefinitionPersistenceFeature UseSqlServer(this EFCoreWorkflowDefinitionPersistenceFeature feature, string connectionString, ElsaDbContextOptions? options = default) { - feature.DbContextOptionsBuilder = (_, db) => db.UseElsaSqlServer(connectionString); + feature.DbContextOptionsBuilder = (_, db) => db.UseElsaSqlServer(connectionString, options); return feature; } - public static EFCoreWorkflowInstancePersistenceFeature UseSqlServer(this EFCoreWorkflowInstancePersistenceFeature feature, string connectionString) + public static EFCoreWorkflowInstancePersistenceFeature UseSqlServer(this EFCoreWorkflowInstancePersistenceFeature feature, string connectionString, ElsaDbContextOptions? options = default) { - feature.DbContextOptionsBuilder = (_, db) => db.UseElsaSqlServer(connectionString); + feature.DbContextOptionsBuilder = (_, db) => db.UseElsaSqlServer(connectionString, options); return feature; } - public static EFCoreWorkflowManagementPersistenceFeature UseSqlServer(this EFCoreWorkflowManagementPersistenceFeature feature, string connectionString) + public static EFCoreWorkflowManagementPersistenceFeature UseSqlServer(this EFCoreWorkflowManagementPersistenceFeature feature, string connectionString, ElsaDbContextOptions? options = default) { - feature.DbContextOptionsBuilder = (_, db) => db.UseElsaSqlServer(connectionString); + feature.DbContextOptionsBuilder = (_, db) => db.UseElsaSqlServer(connectionString, options); return feature; } } \ No newline at end of file diff --git a/src/modules/Elsa.EntityFrameworkCore.SqlServer/Modules/Runtime/Extensions.cs b/src/modules/Elsa.EntityFrameworkCore.SqlServer/Modules/Runtime/Extensions.cs index 873cab7cee..6081ce508e 100644 --- a/src/modules/Elsa.EntityFrameworkCore.SqlServer/Modules/Runtime/Extensions.cs +++ b/src/modules/Elsa.EntityFrameworkCore.SqlServer/Modules/Runtime/Extensions.cs @@ -1,19 +1,20 @@ -using Elsa.EntityFrameworkCore.Modules.Runtime; +using Elsa.EntityFrameworkCore.Common; +using Elsa.EntityFrameworkCore.Modules.Runtime; // ReSharper disable once CheckNamespace namespace Elsa.EntityFrameworkCore.Extensions; public static partial class Extensions { - public static EFCoreDefaultWorkflowRuntimePersistenceFeature UseSqlServer(this EFCoreDefaultWorkflowRuntimePersistenceFeature feature, string connectionString) + public static EFCoreDefaultWorkflowRuntimePersistenceFeature UseSqlServer(this EFCoreDefaultWorkflowRuntimePersistenceFeature feature, string connectionString, ElsaDbContextOptions? options = default) { - feature.DbContextOptionsBuilder = (_, db) => db.UseElsaSqlServer(connectionString); + feature.DbContextOptionsBuilder = (_, db) => db.UseElsaSqlServer(connectionString, options); return feature; } - public static EFCoreExecutionLogRecordPersistenceFeature UseSqlServer(this EFCoreExecutionLogRecordPersistenceFeature feature, string connectionString) + public static EFCoreExecutionLogRecordPersistenceFeature UseSqlServer(this EFCoreExecutionLogRecordPersistenceFeature feature, string connectionString, ElsaDbContextOptions? options = default) { - feature.DbContextOptionsBuilder = (_, db) => db.UseElsaSqlServer(connectionString); + feature.DbContextOptionsBuilder = (_, db) => db.UseElsaSqlServer(connectionString, options); return feature; } } \ No newline at end of file diff --git a/src/modules/Elsa.EntityFrameworkCore.Sqlite/Extensions/DbContextOptionsBuilderExtensions.cs b/src/modules/Elsa.EntityFrameworkCore.Sqlite/Extensions/DbContextOptionsBuilderExtensions.cs index d4fbe3b7c9..80bbca9879 100644 --- a/src/modules/Elsa.EntityFrameworkCore.Sqlite/Extensions/DbContextOptionsBuilderExtensions.cs +++ b/src/modules/Elsa.EntityFrameworkCore.Sqlite/Extensions/DbContextOptionsBuilderExtensions.cs @@ -8,12 +8,14 @@ namespace Elsa.EntityFrameworkCore.Extensions; public static class DbContextOptionsBuilderExtensions { - public static DbContextOptionsBuilder UseElsaSqlite(this DbContextOptionsBuilder builder, string connectionString = Constants.DefaultConnectionString, Action? configure = default) => - builder.UseSqlite(connectionString, db => + public static DbContextOptionsBuilder UseElsaSqlite(this DbContextOptionsBuilder builder, string connectionString = Constants.DefaultConnectionString, ElsaDbContextOptions? options = default, Action? configure = default) => + builder + .UseElsaDbContextOptions(options) + .UseSqlite(connectionString, db => { db - .MigrationsAssembly(typeof(DbContextOptionsBuilderExtensions).Assembly.GetName().Name) - .MigrationsHistoryTable(ElsaDbContextBase.MigrationsHistoryTable, ElsaDbContextBase.ElsaSchema); + .MigrationsAssembly(options?.MigrationsAssemblyName ?? typeof(DbContextOptionsBuilderExtensions).Assembly.GetName().Name) + .MigrationsHistoryTable(options?.MigrationsHistoryTableName ?? ElsaDbContextBase.MigrationsHistoryTable, options?.SchemaName ?? ElsaDbContextBase.ElsaSchema); configure?.Invoke(db); }); diff --git a/src/modules/Elsa.EntityFrameworkCore.Sqlite/Modules/Identity/Extensions.cs b/src/modules/Elsa.EntityFrameworkCore.Sqlite/Modules/Identity/Extensions.cs index 53ca34219c..37bbba997c 100644 --- a/src/modules/Elsa.EntityFrameworkCore.Sqlite/Modules/Identity/Extensions.cs +++ b/src/modules/Elsa.EntityFrameworkCore.Sqlite/Modules/Identity/Extensions.cs @@ -1,4 +1,5 @@ -using Elsa.EntityFrameworkCore.Modules.Identity; +using Elsa.EntityFrameworkCore.Common; +using Elsa.EntityFrameworkCore.Modules.Identity; // ReSharper disable once CheckNamespace namespace Elsa.EntityFrameworkCore.Extensions; @@ -13,10 +14,11 @@ public static partial class Extensions /// /// The feature to configure. /// The connection string to use. + /// Options specified via allows to configure for manual database migrations. /// The configured feature. - public static EFCoreIdentityPersistenceFeature UseSqlite(this EFCoreIdentityPersistenceFeature feature, string connectionString) + public static EFCoreIdentityPersistenceFeature UseSqlite(this EFCoreIdentityPersistenceFeature feature, string connectionString, ElsaDbContextOptions? options = default) { - feature.DbContextOptionsBuilder = (_, db) => db.UseElsaSqlite(connectionString); + feature.DbContextOptionsBuilder = (_, db) => db.UseElsaSqlite(connectionString, options); return feature; } } \ No newline at end of file diff --git a/src/modules/Elsa.EntityFrameworkCore.Sqlite/Modules/Labels/Extensions.cs b/src/modules/Elsa.EntityFrameworkCore.Sqlite/Modules/Labels/Extensions.cs index 9a6f895a32..f5a374b3dc 100644 --- a/src/modules/Elsa.EntityFrameworkCore.Sqlite/Modules/Labels/Extensions.cs +++ b/src/modules/Elsa.EntityFrameworkCore.Sqlite/Modules/Labels/Extensions.cs @@ -1,4 +1,5 @@ -using Elsa.EntityFrameworkCore.Modules.Labels; +using Elsa.EntityFrameworkCore.Common; +using Elsa.EntityFrameworkCore.Modules.Labels; using Elsa.EntityFrameworkCore.Sqlite; // ReSharper disable once CheckNamespace @@ -6,9 +7,9 @@ namespace Elsa.EntityFrameworkCore.Extensions; public static partial class Extensions { - public static EFCoreLabelPersistenceFeature UseSqlite(this EFCoreLabelPersistenceFeature feature, string connectionString = Constants.DefaultConnectionString) + public static EFCoreLabelPersistenceFeature UseSqlite(this EFCoreLabelPersistenceFeature feature, string connectionString = Constants.DefaultConnectionString, ElsaDbContextOptions? options = default) { - feature.DbContextOptionsBuilder = (_, db) => db.UseElsaSqlite(connectionString); + feature.DbContextOptionsBuilder = (_, db) => db.UseElsaSqlite(connectionString, options); return feature; } } \ No newline at end of file diff --git a/src/modules/Elsa.EntityFrameworkCore.Sqlite/Modules/Management/Extensions.cs b/src/modules/Elsa.EntityFrameworkCore.Sqlite/Modules/Management/Extensions.cs index 0357129511..9c38005f22 100644 --- a/src/modules/Elsa.EntityFrameworkCore.Sqlite/Modules/Management/Extensions.cs +++ b/src/modules/Elsa.EntityFrameworkCore.Sqlite/Modules/Management/Extensions.cs @@ -1,4 +1,5 @@ -using Elsa.EntityFrameworkCore.Modules.Management; +using Elsa.EntityFrameworkCore.Common; +using Elsa.EntityFrameworkCore.Modules.Management; using Elsa.EntityFrameworkCore.Sqlite; using JetBrains.Annotations; @@ -8,21 +9,21 @@ namespace Elsa.EntityFrameworkCore.Extensions; [PublicAPI] public static partial class Extensions { - public static EFCoreWorkflowDefinitionPersistenceFeature UseSqlite(this EFCoreWorkflowDefinitionPersistenceFeature feature, string connectionString = Constants.DefaultConnectionString) + public static EFCoreWorkflowDefinitionPersistenceFeature UseSqlite(this EFCoreWorkflowDefinitionPersistenceFeature feature, string connectionString = Constants.DefaultConnectionString, ElsaDbContextOptions? options = default) { - feature.DbContextOptionsBuilder = (_, db) => db.UseElsaSqlite(connectionString); + feature.DbContextOptionsBuilder = (_, db) => db.UseElsaSqlite(connectionString, options); return feature; } - public static EFCoreWorkflowInstancePersistenceFeature UseSqlite(this EFCoreWorkflowInstancePersistenceFeature feature, string connectionString = Constants.DefaultConnectionString) + public static EFCoreWorkflowInstancePersistenceFeature UseSqlite(this EFCoreWorkflowInstancePersistenceFeature feature, string connectionString = Constants.DefaultConnectionString, ElsaDbContextOptions? options = default) { - feature.DbContextOptionsBuilder = (_, db) => db.UseElsaSqlite(connectionString); + feature.DbContextOptionsBuilder = (_, db) => db.UseElsaSqlite(connectionString, options); return feature; } - public static EFCoreWorkflowManagementPersistenceFeature UseSqlite(this EFCoreWorkflowManagementPersistenceFeature feature, string connectionString = Constants.DefaultConnectionString) + public static EFCoreWorkflowManagementPersistenceFeature UseSqlite(this EFCoreWorkflowManagementPersistenceFeature feature, string connectionString = Constants.DefaultConnectionString, ElsaDbContextOptions? options = default) { - feature.DbContextOptionsBuilder = (_, db) => db.UseElsaSqlite(connectionString); + feature.DbContextOptionsBuilder = (_, db) => db.UseElsaSqlite(connectionString, options); return feature; } } \ No newline at end of file diff --git a/src/modules/Elsa.EntityFrameworkCore.Sqlite/Modules/Runtime/Extensions.cs b/src/modules/Elsa.EntityFrameworkCore.Sqlite/Modules/Runtime/Extensions.cs index db3f0e5f1d..b046297f1e 100644 --- a/src/modules/Elsa.EntityFrameworkCore.Sqlite/Modules/Runtime/Extensions.cs +++ b/src/modules/Elsa.EntityFrameworkCore.Sqlite/Modules/Runtime/Extensions.cs @@ -1,4 +1,5 @@ -using Elsa.EntityFrameworkCore.Modules.Runtime; +using Elsa.EntityFrameworkCore.Common; +using Elsa.EntityFrameworkCore.Modules.Runtime; using Elsa.EntityFrameworkCore.Sqlite; // ReSharper disable once CheckNamespace @@ -6,21 +7,21 @@ namespace Elsa.EntityFrameworkCore.Extensions; public static partial class Extensions { - public static EFCoreWorkflowRuntimePersistenceFeature UseSqlite(this EFCoreWorkflowRuntimePersistenceFeature feature, string connectionString = Constants.DefaultConnectionString) + public static EFCoreWorkflowRuntimePersistenceFeature UseSqlite(this EFCoreWorkflowRuntimePersistenceFeature feature, string connectionString = Constants.DefaultConnectionString, ElsaDbContextOptions? options = default) { - feature.DbContextOptionsBuilder = (_, db) => db.UseElsaSqlite(connectionString); + feature.DbContextOptionsBuilder = (_, db) => db.UseElsaSqlite(connectionString, options); return feature; } - public static EFCoreDefaultWorkflowRuntimePersistenceFeature UseSqlite(this EFCoreDefaultWorkflowRuntimePersistenceFeature feature, string connectionString = Constants.DefaultConnectionString) + public static EFCoreDefaultWorkflowRuntimePersistenceFeature UseSqlite(this EFCoreDefaultWorkflowRuntimePersistenceFeature feature, string connectionString = Constants.DefaultConnectionString, ElsaDbContextOptions? options = default) { - feature.DbContextOptionsBuilder = (_, db) => db.UseElsaSqlite(connectionString); + feature.DbContextOptionsBuilder = (_, db) => db.UseElsaSqlite(connectionString, options); return feature; } - public static EFCoreExecutionLogRecordPersistenceFeature UseSqlite(this EFCoreExecutionLogRecordPersistenceFeature feature, string connectionString = Constants.DefaultConnectionString) + public static EFCoreExecutionLogRecordPersistenceFeature UseSqlite(this EFCoreExecutionLogRecordPersistenceFeature feature, string connectionString = Constants.DefaultConnectionString, ElsaDbContextOptions? options = default) { - feature.DbContextOptionsBuilder = (_, db) => db.UseElsaSqlite(connectionString); + feature.DbContextOptionsBuilder = (_, db) => db.UseElsaSqlite(connectionString, options); return feature; } } \ No newline at end of file diff --git a/src/modules/Elsa.EntityFrameworkCore/Common/CustomDbContextOptionsExtensionInfo.cs b/src/modules/Elsa.EntityFrameworkCore/Common/CustomDbContextOptionsExtensionInfo.cs new file mode 100644 index 0000000000..ab22cffbc1 --- /dev/null +++ b/src/modules/Elsa.EntityFrameworkCore/Common/CustomDbContextOptionsExtensionInfo.cs @@ -0,0 +1,30 @@ +using Microsoft.EntityFrameworkCore.Infrastructure; + +namespace Elsa.EntityFrameworkCore.Common; + +public class CustomDbContextOptionsExtensionInfo : DbContextOptionsExtensionInfo +{ + public CustomDbContextOptionsExtensionInfo(IDbContextOptionsExtension extension) + : base(extension) + { + } + + public override bool IsDatabaseProvider => false; + + public override string LogFragment => ""; + + public override int GetServiceProviderHashCode() + { + // Return a unique hash code for your custom extension + return 0; + } + + public override void PopulateDebugInfo(IDictionary debugInfo) + { + } + + public override bool ShouldUseSameServiceProvider(DbContextOptionsExtensionInfo other) + { + return true; + } +} diff --git a/src/modules/Elsa.EntityFrameworkCore/Common/ElsaDbContextBase.cs b/src/modules/Elsa.EntityFrameworkCore/Common/ElsaDbContextBase.cs index 5ab39e1ae0..68aa7ae166 100644 --- a/src/modules/Elsa.EntityFrameworkCore/Common/ElsaDbContextBase.cs +++ b/src/modules/Elsa.EntityFrameworkCore/Common/ElsaDbContextBase.cs @@ -12,24 +12,26 @@ public abstract class ElsaDbContextBase : DbContext /// /// The schema used by Elsa. /// - public const string ElsaSchema = "Elsa"; - + public static string ElsaSchema = "Elsa"; + /// /// The table used to store the migrations history. /// - public const string MigrationsHistoryTable = "__EFMigrationsHistory"; + public static string MigrationsHistoryTable = "__EFMigrationsHistory"; /// /// Initializes a new instance of the class. /// protected ElsaDbContextBase(DbContextOptions options) : base(options) { + var elsaDbContextOptions = options.FindExtension()?.Options; + Schema = !string.IsNullOrWhiteSpace(elsaDbContextOptions?.SchemaName) ? elsaDbContextOptions.SchemaName : ElsaSchema; } /// /// The schema used by Elsa. /// - protected virtual string Schema => ElsaSchema; + protected virtual string Schema { get; set; } /// protected override void OnModelCreating(ModelBuilder modelBuilder) diff --git a/src/modules/Elsa.EntityFrameworkCore/Common/ElsaDbContextOptions.cs b/src/modules/Elsa.EntityFrameworkCore/Common/ElsaDbContextOptions.cs new file mode 100644 index 0000000000..7f0c77c158 --- /dev/null +++ b/src/modules/Elsa.EntityFrameworkCore/Common/ElsaDbContextOptions.cs @@ -0,0 +1,8 @@ +namespace Elsa.EntityFrameworkCore.Common; + +public class ElsaDbContextOptions +{ + public string? SchemaName { get; set; } + public string? MigrationsHistoryTableName { get; set; } + public string? MigrationsAssemblyName { get; set; } +} diff --git a/src/modules/Elsa.EntityFrameworkCore/Common/ElsaDbContextOptionsExtension.cs b/src/modules/Elsa.EntityFrameworkCore/Common/ElsaDbContextOptionsExtension.cs new file mode 100644 index 0000000000..345f7ef520 --- /dev/null +++ b/src/modules/Elsa.EntityFrameworkCore/Common/ElsaDbContextOptionsExtension.cs @@ -0,0 +1,32 @@ +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.Extensions.DependencyInjection; + +namespace Elsa.EntityFrameworkCore.Common; + +public class ElsaDbContextOptionsExtension : IDbContextOptionsExtension +{ + private ElsaDbContextOptions _options; + + public ElsaDbContextOptionsExtension(ElsaDbContextOptions? options) + { + _options = options; + } + + public ElsaDbContextOptions Options => _options; + + public string LogFragment => ""; + + public DbContextOptionsExtensionInfo Info => new CustomDbContextOptionsExtensionInfo(this); + + public void ApplyServices(IServiceCollection services) + { + } + + public void Validate(IDbContextOptions options) + { + if(!string.IsNullOrWhiteSpace(_options.SchemaName) && string.IsNullOrWhiteSpace(_options.MigrationsAssemblyName)) + { + throw new ArgumentException("MigrationsAssemblyName must be defined for manual migration"); + } + } +} \ No newline at end of file diff --git a/src/modules/Elsa.EntityFrameworkCore/Common/ElsaDbContextOptionsExtensions.cs b/src/modules/Elsa.EntityFrameworkCore/Common/ElsaDbContextOptionsExtensions.cs new file mode 100644 index 0000000000..dd5a41f88d --- /dev/null +++ b/src/modules/Elsa.EntityFrameworkCore/Common/ElsaDbContextOptionsExtensions.cs @@ -0,0 +1,17 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; + +namespace Elsa.EntityFrameworkCore.Common; + +public static class ElsaDbContextOptionsExtensions +{ + public static DbContextOptionsBuilder UseElsaDbContextOptions( + this DbContextOptionsBuilder optionsBuilder, + ElsaDbContextOptions? options) + { + ((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension( + new ElsaDbContextOptionsExtension(options)); + + return optionsBuilder; + } +}