diff --git a/Elsa.sln b/Elsa.sln index 619e260be..0091ff928 100644 --- a/Elsa.sln +++ b/Elsa.sln @@ -89,9 +89,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docker", "docker", "{986E54 docker\ElsaServer.Dockerfile = docker\ElsaServer.Dockerfile docker\ElsaServerAndStudio.Dockerfile = docker\ElsaServerAndStudio.Dockerfile docker\ElsaStudio.Dockerfile = docker\ElsaStudio.Dockerfile - docker\init-db.sh = docker\init-db.sh docker\otel-collector-config.yaml = docker\otel-collector-config.yaml docker\docker-compose-kafka.yml = docker\docker-compose-kafka.yml + docker\init-db-postgres.sh = docker\init-db-postgres.sh EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.Elasticsearch", "src\modules\Elsa.Elasticsearch\Elsa.Elasticsearch.csproj", "{3246883E-2FA7-4B4A-BDC5-99039A2869BC}" @@ -387,6 +387,11 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Agents.Persistence.Ent EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Kafka", "src\modules\Elsa.Kafka\Elsa.Kafka.csproj", "{BF934627-F531-44FB-BEC2-ECA801FF31E7}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "oracle-setup", "oracle-setup", "{66E2E2CF-967F-4564-89E8-F46FA973C99B}" + ProjectSection(SolutionItems) = preProject + docker\oracle-setup\setup.sql = docker\oracle-setup\setup.sql + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -968,6 +973,7 @@ Global {2B939AC9-03A4-479E-AA0D-CB58F4A7F480} = {50470834-4CD8-479A-8B58-0A1869BA5D37} {2CDF3E1C-267D-4198-B1C7-7E1F548FC120} = {5BA4A8FA-F7F4-45B3-AEC8-8886D35AAC79} {BF934627-F531-44FB-BEC2-ECA801FF31E7} = {DD089B8B-DA73-492A-9010-F772D1C178DA} + {66E2E2CF-967F-4564-89E8-F46FA973C99B} = {986E5482-0482-448C-B9E4-EC67A9474B85} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {D4B5CEAA-7D70-4FCB-A68E-B03FBE5E0E5E} diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 58f37a11b..8d76746a1 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -27,16 +27,15 @@ oracle: image: container-registry.oracle.com/database/free:latest - container_name: oracle + container_name: oracle-db environment: - ORACLE_PDB: ORCLPDB1 ORACLE_PWD: elsa ports: - "1521:1521" - "5500:5500" volumes: - - oracle-data-free:/opt/oracle/oradata - shm_size: '1g' + - ./oracle-data-free1:/opt/oracle/oradata + - ./oracle-setup:/opt/oracle/scripts/setup mongodb: image: mongo:latest @@ -128,7 +127,7 @@ volumes: postgres-data: - oracle-data-free: + oracle-data-free1: mysql_data2: cockroachdb-data: mongodb_data: diff --git a/docker/init-db.sh b/docker/init-db-postgres.sh similarity index 100% rename from docker/init-db.sh rename to docker/init-db-postgres.sh diff --git a/docker/oracle-setup/setup.sql b/docker/oracle-setup/setup.sql new file mode 100755 index 000000000..311441d40 --- /dev/null +++ b/docker/oracle-setup/setup.sql @@ -0,0 +1,3 @@ +alter session set "_ORACLE_SCRIPT"=true; +CREATE USER ELSA IDENTIFIED BY elsa; +GRANT ALL PRIVILEGES TO ELSA; \ No newline at end of file diff --git a/src/apps/Elsa.Server.Web/Program.cs b/src/apps/Elsa.Server.Web/Program.cs index 0e9985ad8..af30c1b66 100644 --- a/src/apps/Elsa.Server.Web/Program.cs +++ b/src/apps/Elsa.Server.Web/Program.cs @@ -9,6 +9,7 @@ using Elsa.Common.Serialization; using Elsa.Dapper.Extensions; using Elsa.Dapper.Services; using Elsa.DropIns.Extensions; +using Elsa.EntityFrameworkCore; using Elsa.EntityFrameworkCore.Extensions; using Elsa.EntityFrameworkCore.Modules.Alterations; using Elsa.EntityFrameworkCore.Modules.Identity; @@ -197,7 +198,7 @@ services else if (sqlDatabaseProvider == SqlDatabaseProvider.CockroachDb) ef.UsePostgreSql(cockroachDbConnectionString!); else if (sqlDatabaseProvider == SqlDatabaseProvider.Oracle) - ef.UseOracle(oracleConnectionString); + ef.UseOracle(oracleConnectionString, new ElsaDbContextOptions{ SchemaName = "ELSA"}); else ef.UseSqlite(sp => sp.GetSqliteConnectionString()); @@ -235,7 +236,7 @@ services else if (sqlDatabaseProvider == SqlDatabaseProvider.CockroachDb) ef.UsePostgreSql(cockroachDbConnectionString!); else if (sqlDatabaseProvider == SqlDatabaseProvider.Oracle) - ef.UseOracle(oracleConnectionString); + ef.UseOracle(oracleConnectionString, new ElsaDbContextOptions{ SchemaName = "ELSA"}); else ef.UseSqlite(sp => sp.GetSqliteConnectionString()); @@ -283,7 +284,7 @@ services else if (sqlDatabaseProvider == SqlDatabaseProvider.CockroachDb) ef.UsePostgreSql(cockroachDbConnectionString); else if (sqlDatabaseProvider == SqlDatabaseProvider.Oracle) - ef.UseOracle(oracleConnectionString); + ef.UseOracle(oracleConnectionString, new ElsaDbContextOptions{ SchemaName = "ELSA"}); else ef.UseSqlite(sp => sp.GetSqliteConnectionString()); @@ -420,7 +421,7 @@ services else if (sqlDatabaseProvider == SqlDatabaseProvider.CockroachDb) ef.UsePostgreSql(cockroachDbConnectionString); else if (sqlDatabaseProvider == SqlDatabaseProvider.Oracle) - ef.UseOracle(oracleConnectionString); + ef.UseOracle(oracleConnectionString, new ElsaDbContextOptions{ SchemaName = "ELSA"}); else ef.UseSqlite(sp => sp.GetSqliteConnectionString()); @@ -623,7 +624,7 @@ services if (sqlDatabaseProvider == SqlDatabaseProvider.Sqlite) ef.UseSqlite(sqliteConnectionString); if (sqlDatabaseProvider == SqlDatabaseProvider.SqlServer) ef.UseSqlServer(sqlServerConnectionString); if (sqlDatabaseProvider == SqlDatabaseProvider.PostgreSql) ef.UsePostgreSql(postgresConnectionString); - if (sqlDatabaseProvider == SqlDatabaseProvider.Oracle) ef.UseOracle(oracleConnectionString); + if (sqlDatabaseProvider == SqlDatabaseProvider.Oracle) ef.UseOracle(oracleConnectionString, new ElsaDbContextOptions{ SchemaName = "ELSA"}); #if !NET9_0 if (sqlDatabaseProvider == SqlDatabaseProvider.MySql) ef.UseMySql(mySqlConnectionString); diff --git a/src/apps/Elsa.Server.Web/appsettings.json b/src/apps/Elsa.Server.Web/appsettings.json index 20591e80b..a1d35303b 100644 --- a/src/apps/Elsa.Server.Web/appsettings.json +++ b/src/apps/Elsa.Server.Web/appsettings.json @@ -13,7 +13,7 @@ "Sqlite": "Data Source=App_Data/elsa.sqlite.db;Cache=Shared;", "MySql": "Server=localhost;Database=elsa;Uid=admin;Pwd=password;", "PostgreSql": "Server=localhost;Username=elsa;Database=elsa;Port=5432;Password=elsa;SSLMode=Prefer;MaxPoolSize=2000;Timeout=60", - "Oracle": "User Id=SYSTEM;Password=elsa;Data Source=localhost:1521/FREE;", + "Oracle": "Data Source=(DESCRIPTION = (ADDRESS_LIST = (FAILOVER =ON) (LOAD_BALANCE = OFF) (ADDRESS = (PROTOCOL =TCP)(HOST=localhost)(PORT=1521))) (CONNECT_DATA = (SID= FREE) ));User Id=ELSA;Password=elsa;", "CockroachDb": "Host=localhost;Port=26257;Database=elsa;SslMode=Disable;Username=root;IncludeErrorDetail=true", "MongoDb": "mongodb://localhost:27017/elsa-workflows", "AzureServiceBus": "", diff --git a/src/modules/Elsa.Agents.Persistence.EntityFrameworkCore/Feature.cs b/src/modules/Elsa.Agents.Persistence.EntityFrameworkCore/Feature.cs index d5c99065e..67f4d0240 100644 --- a/src/modules/Elsa.Agents.Persistence.EntityFrameworkCore/Feature.cs +++ b/src/modules/Elsa.Agents.Persistence.EntityFrameworkCore/Feature.cs @@ -34,6 +34,5 @@ public class EFCoreAgentPersistenceFeature(IModule module) : PersistenceFeatureB AddEntityStore(); AddEntityStore(); AddEntityStore(); - Services.AddScoped(); } } \ No newline at end of file diff --git a/src/modules/Elsa.Agents.Persistence.EntityFrameworkCore/SetupForOracle.cs b/src/modules/Elsa.Agents.Persistence.EntityFrameworkCore/SetupForOracle.cs deleted file mode 100644 index 1dec01e7d..000000000 --- a/src/modules/Elsa.Agents.Persistence.EntityFrameworkCore/SetupForOracle.cs +++ /dev/null @@ -1,25 +0,0 @@ -using Elsa.Agents.Persistence.Entities; -using Elsa.EntityFrameworkCore; -using Elsa.EntityFrameworkCore.Extensions; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Metadata; - -namespace Elsa.Agents.Persistence.EntityFrameworkCore; - -/// -/// Represents a class that handles entity model creation for SQLite databases. -/// -public class SetupForOracle : IEntityModelCreatingHandler -{ - /// - public void Handle(ElsaDbContextBase dbContext, ModelBuilder modelBuilder, IMutableEntityType entityType) - { - if(!dbContext.Database.IsOracle()) - return; - - // In order to use data more than 2000 char we have to use NCLOB. - // In Oracle, we have to explicitly say the column is NCLOB otherwise it would be considered nvarchar(2000). - modelBuilder.Entity().Property("SerializedSettings").HasColumnType("NCLOB"); - modelBuilder.Entity().Property("SerializedAgentConfig").HasColumnType("NCLOB"); - } -} \ No newline at end of file diff --git a/src/modules/Elsa.EntityFrameworkCore.Common/CommonPersistenceFeature.cs b/src/modules/Elsa.EntityFrameworkCore.Common/CommonPersistenceFeature.cs index 42f681a5d..835574f21 100644 --- a/src/modules/Elsa.EntityFrameworkCore.Common/CommonPersistenceFeature.cs +++ b/src/modules/Elsa.EntityFrameworkCore.Common/CommonPersistenceFeature.cs @@ -13,6 +13,5 @@ public class CommonPersistenceFeature(IModule module) : FeatureBase(module) { Services.AddScoped(); Services.AddScoped(); - Services.AddScoped(); } } \ No newline at end of file diff --git a/src/modules/Elsa.EntityFrameworkCore.Common/DbSchemaAwareMigrationAssembly.cs b/src/modules/Elsa.EntityFrameworkCore.Common/DbSchemaAwareMigrationAssembly.cs index 21ab52188..5e31b710e 100644 --- a/src/modules/Elsa.EntityFrameworkCore.Common/DbSchemaAwareMigrationAssembly.cs +++ b/src/modules/Elsa.EntityFrameworkCore.Common/DbSchemaAwareMigrationAssembly.cs @@ -10,17 +10,14 @@ namespace Elsa.EntityFrameworkCore; /// /// Class That enable Schema change for Migration /// -public class DbSchemaAwareMigrationAssembly : MigrationsAssembly +public class DbSchemaAwareMigrationAssembly( + ICurrentDbContext currentContext, + IDbContextOptions options, + IMigrationsIdGenerator idGenerator, + IDiagnosticsLogger logger) + : MigrationsAssembly(currentContext, options, idGenerator, logger) { - private readonly DbContext _context; - - public DbSchemaAwareMigrationAssembly(ICurrentDbContext currentContext, - IDbContextOptions options, IMigrationsIdGenerator idGenerator, - IDiagnosticsLogger logger) - : base(currentContext, options, idGenerator, logger) - { - _context = currentContext.Context; - } + private readonly DbContext _context = currentContext.Context; public override Migration CreateMigration(TypeInfo migrationClass, string activeProvider) { diff --git a/src/modules/Elsa.EntityFrameworkCore.Common/Elsa.EntityFrameworkCore.Common.csproj b/src/modules/Elsa.EntityFrameworkCore.Common/Elsa.EntityFrameworkCore.Common.csproj index 723566266..e3f4635d9 100644 --- a/src/modules/Elsa.EntityFrameworkCore.Common/Elsa.EntityFrameworkCore.Common.csproj +++ b/src/modules/Elsa.EntityFrameworkCore.Common/Elsa.EntityFrameworkCore.Common.csproj @@ -12,7 +12,6 @@ - diff --git a/src/modules/Elsa.EntityFrameworkCore.Common/ElsaDbContextBase.cs b/src/modules/Elsa.EntityFrameworkCore.Common/ElsaDbContextBase.cs index 85407dff4..4e14923f2 100644 --- a/src/modules/Elsa.EntityFrameworkCore.Common/ElsaDbContextBase.cs +++ b/src/modules/Elsa.EntityFrameworkCore.Common/ElsaDbContextBase.cs @@ -61,6 +61,7 @@ public abstract class ElsaDbContextBase : DbContext, IElsaDbContextSchema protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { + optionsBuilder.EnableSensitiveDataLogging(); #if NET9_0_OR_GREATER optionsBuilder.ConfigureWarnings(w => w.Ignore(RelationalEventId.PendingModelChangesWarning)); #endif @@ -71,8 +72,7 @@ public abstract class ElsaDbContextBase : DbContext, IElsaDbContextSchema { if (!string.IsNullOrWhiteSpace(Schema)) { - if (!Database.IsSqlite()) - modelBuilder.HasDefaultSchema(Schema); + modelBuilder.HasDefaultSchema(Schema); } var entityTypeHandlers = ServiceProvider.GetServices().ToList(); diff --git a/src/modules/Elsa.EntityFrameworkCore.Common/PersistenceFeatureBase.cs b/src/modules/Elsa.EntityFrameworkCore.Common/PersistenceFeatureBase.cs index 031f69397..5df4f3a07 100644 --- a/src/modules/Elsa.EntityFrameworkCore.Common/PersistenceFeatureBase.cs +++ b/src/modules/Elsa.EntityFrameworkCore.Common/PersistenceFeatureBase.cs @@ -39,11 +39,7 @@ public abstract class PersistenceFeatureBase : FeatureBase /// /// Gets or sets the callback used to configure the . /// - public Action DbContextOptionsBuilder = (_, options) => options - .UseElsaDbContextOptions(default) - .UseSqlite("Data Source=elsa.sqlite.db;Cache=Shared;", sqlite => sqlite - .MigrationsAssembly("Elsa.EntityFrameworkCore.Sqlite") - .MigrationsHistoryTable(ElsaDbContextBase.MigrationsHistoryTable, ElsaDbContextBase.ElsaSchema)); + public virtual Action DbContextOptionsBuilder { get; set; } = null!; public override void ConfigureHostedServices() { @@ -54,6 +50,9 @@ public abstract class PersistenceFeatureBase : FeatureBase /// public override void Apply() { + if(DbContextOptionsBuilder == null) + throw new InvalidOperationException("The DbContextOptionsBuilder must be configured."); + if (UseContextPooling) Services.AddPooledDbContextFactory(DbContextOptionsBuilder); else diff --git a/src/modules/Elsa.EntityFrameworkCore.Oracle/Migrations/Alterations/20241212211620_V3_3.cs b/src/modules/Elsa.EntityFrameworkCore.Oracle/Migrations/Alterations/20241212211620_V3_3.cs index 97bd8dd6c..fb7daa451 100644 --- a/src/modules/Elsa.EntityFrameworkCore.Oracle/Migrations/Alterations/20241212211620_V3_3.cs +++ b/src/modules/Elsa.EntityFrameworkCore.Oracle/Migrations/Alterations/20241212211620_V3_3.cs @@ -20,7 +20,7 @@ namespace Elsa.EntityFrameworkCore.Oracle.Migrations.Alterations protected override void Up(MigrationBuilder migrationBuilder) { migrationBuilder.EnsureSchema( - name: "Elsa"); + name: _schema.Schema); migrationBuilder.CreateTable( name: "AlterationJobs", diff --git a/src/modules/Elsa.EntityFrameworkCore.Oracle/Migrations/Identity/20241212211936_V3_3.cs b/src/modules/Elsa.EntityFrameworkCore.Oracle/Migrations/Identity/20241212211936_V3_3.cs index baed52c99..f9c5d3188 100644 --- a/src/modules/Elsa.EntityFrameworkCore.Oracle/Migrations/Identity/20241212211936_V3_3.cs +++ b/src/modules/Elsa.EntityFrameworkCore.Oracle/Migrations/Identity/20241212211936_V3_3.cs @@ -19,7 +19,7 @@ namespace Elsa.EntityFrameworkCore.Oracle.Migrations.Identity protected override void Up(MigrationBuilder migrationBuilder) { migrationBuilder.EnsureSchema( - name: "Elsa"); + name: _schema.Schema); migrationBuilder.CreateTable( name: "Applications", diff --git a/src/modules/Elsa.EntityFrameworkCore.Oracle/Migrations/Labels/20241212212100_V3_3.cs b/src/modules/Elsa.EntityFrameworkCore.Oracle/Migrations/Labels/20241212212100_V3_3.cs index dbfb65ccd..af7faf037 100644 --- a/src/modules/Elsa.EntityFrameworkCore.Oracle/Migrations/Labels/20241212212100_V3_3.cs +++ b/src/modules/Elsa.EntityFrameworkCore.Oracle/Migrations/Labels/20241212212100_V3_3.cs @@ -19,7 +19,7 @@ namespace Elsa.EntityFrameworkCore.Oracle.Migrations.Labels protected override void Up(MigrationBuilder migrationBuilder) { migrationBuilder.EnsureSchema( - name: "Elsa"); + name: _schema.Schema); migrationBuilder.CreateTable( name: "Labels", diff --git a/src/modules/Elsa.EntityFrameworkCore.Oracle/Migrations/Management/20241212211817_V3_3.cs b/src/modules/Elsa.EntityFrameworkCore.Oracle/Migrations/Management/20241212211817_V3_3.cs index 57217614d..e3ba33c57 100644 --- a/src/modules/Elsa.EntityFrameworkCore.Oracle/Migrations/Management/20241212211817_V3_3.cs +++ b/src/modules/Elsa.EntityFrameworkCore.Oracle/Migrations/Management/20241212211817_V3_3.cs @@ -20,7 +20,7 @@ namespace Elsa.EntityFrameworkCore.Oracle.Migrations.Management protected override void Up(MigrationBuilder migrationBuilder) { migrationBuilder.EnsureSchema( - name: "Elsa"); + name: _schema.Schema); migrationBuilder.CreateTable( name: "WorkflowDefinitions", diff --git a/src/modules/Elsa.EntityFrameworkCore.Oracle/Migrations/Runtime/20250116193207_V3_3.cs b/src/modules/Elsa.EntityFrameworkCore.Oracle/Migrations/Runtime/20250116193207_V3_3.cs index a026586c5..133e73074 100644 --- a/src/modules/Elsa.EntityFrameworkCore.Oracle/Migrations/Runtime/20250116193207_V3_3.cs +++ b/src/modules/Elsa.EntityFrameworkCore.Oracle/Migrations/Runtime/20250116193207_V3_3.cs @@ -20,7 +20,7 @@ namespace Elsa.EntityFrameworkCore.Oracle.Migrations.Runtime protected override void Up(MigrationBuilder migrationBuilder) { migrationBuilder.EnsureSchema( - name: "Elsa"); + name: _schema.Schema); migrationBuilder.CreateTable( name: "ActivityExecutionRecords", diff --git a/src/modules/Elsa.EntityFrameworkCore.Oracle/Migrations/Tenants/20241212212227_V3_3.cs b/src/modules/Elsa.EntityFrameworkCore.Oracle/Migrations/Tenants/20241212212227_V3_3.cs index 8ca9f1711..1860609ac 100644 --- a/src/modules/Elsa.EntityFrameworkCore.Oracle/Migrations/Tenants/20241212212227_V3_3.cs +++ b/src/modules/Elsa.EntityFrameworkCore.Oracle/Migrations/Tenants/20241212212227_V3_3.cs @@ -19,7 +19,7 @@ namespace Elsa.EntityFrameworkCore.Oracle.Migrations.Tenants protected override void Up(MigrationBuilder migrationBuilder) { migrationBuilder.EnsureSchema( - name: "Elsa"); + name: _schema.Schema); migrationBuilder.CreateTable( name: "Tenants", diff --git a/src/modules/Elsa.EntityFrameworkCore.Oracle/OracleProvidersExtensions.cs b/src/modules/Elsa.EntityFrameworkCore.Oracle/OracleProvidersExtensions.cs index 002b87541..191a08eb2 100644 --- a/src/modules/Elsa.EntityFrameworkCore.Oracle/OracleProvidersExtensions.cs +++ b/src/modules/Elsa.EntityFrameworkCore.Oracle/OracleProvidersExtensions.cs @@ -1,5 +1,10 @@ using System.Reflection; +using Elsa.EntityFrameworkCore.Modules.Alterations; +using Elsa.EntityFrameworkCore.Oracle; +using Elsa.Extensions; using JetBrains.Annotations; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; using Oracle.EntityFrameworkCore.Infrastructure; // ReSharper disable once CheckNamespace @@ -12,49 +17,53 @@ namespace Elsa.EntityFrameworkCore.Extensions; public static class OracleProvidersExtensions { private static Assembly Assembly => typeof(OracleProvidersExtensions).Assembly; - - public static TFeature UseOracle(this PersistenceFeatureBase feature, - string connectionString, - ElsaDbContextOptions? options = null, - Action? configure = null) + + public static TFeature UseOracle(this PersistenceFeatureBase feature, + string connectionString, + ElsaDbContextOptions? options = null, + Action? configure = null) where TDbContext : ElsaDbContextBase where TFeature : PersistenceFeatureBase { return feature.UseOracle(Assembly, connectionString, options, configure); } - - public static TFeature UseOracle(this PersistenceFeatureBase feature, + + public static TFeature UseOracle(this PersistenceFeatureBase feature, Func connectionStringFunc, ElsaDbContextOptions? options = null, Action? configure = null - ) + ) where TDbContext : ElsaDbContextBase where TFeature : PersistenceFeatureBase { return feature.UseOracle(Assembly, connectionStringFunc, options, configure); } - - public static TFeature UseOracle(this PersistenceFeatureBase feature, - Assembly migrationsAssembly, + + public static TFeature UseOracle(this PersistenceFeatureBase feature, + Assembly migrationsAssembly, string connectionString, ElsaDbContextOptions? options = null, Action? configure = null - ) + ) where TDbContext : ElsaDbContextBase where TFeature : PersistenceFeatureBase { return feature.UseOracle(migrationsAssembly, _ => connectionString, options, configure); } - - public static TFeature UseOracle(this PersistenceFeatureBase feature, - Assembly migrationsAssembly, + + public static TFeature UseOracle(this PersistenceFeatureBase feature, + Assembly migrationsAssembly, Func connectionStringFunc, ElsaDbContextOptions? options = null, Action? configure = null - ) + ) where TDbContext : ElsaDbContextBase where TFeature : PersistenceFeatureBase { + feature.Services.TryAddScopedImplementation(); + feature.Services.TryAddScopedImplementation(); + feature.Services.TryAddScopedImplementation(); + feature.DbContextOptionsBuilder = (sp, db) => db.UseElsaOracle(migrationsAssembly, connectionStringFunc(sp), options, configure: configure); return (TFeature)feature; } diff --git a/src/modules/Elsa.EntityFrameworkCore/Modules/Alterations/SetupForOracle.cs b/src/modules/Elsa.EntityFrameworkCore.Oracle/SetupForAlterations.cs similarity index 88% rename from src/modules/Elsa.EntityFrameworkCore/Modules/Alterations/SetupForOracle.cs rename to src/modules/Elsa.EntityFrameworkCore.Oracle/SetupForAlterations.cs index 8c3b5b2a3..81dc4bff3 100644 --- a/src/modules/Elsa.EntityFrameworkCore/Modules/Alterations/SetupForOracle.cs +++ b/src/modules/Elsa.EntityFrameworkCore.Oracle/SetupForAlterations.cs @@ -1,14 +1,13 @@ using Elsa.Alterations.Core.Entities; -using Elsa.EntityFrameworkCore.Extensions; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata; -namespace Elsa.EntityFrameworkCore.Modules.Alterations; +namespace Elsa.EntityFrameworkCore.Oracle; /// /// Represents a class that handles entity model creation for SQLite databases. /// -public class SetupForOracle : IEntityModelCreatingHandler +public class SetupForAlterations : IEntityModelCreatingHandler { /// public void Handle(ElsaDbContextBase dbContext, ModelBuilder modelBuilder, IMutableEntityType entityType) diff --git a/src/modules/Elsa.EntityFrameworkCore.Oracle/SetupForManagement.cs b/src/modules/Elsa.EntityFrameworkCore.Oracle/SetupForManagement.cs new file mode 100644 index 000000000..c7ba3e7bb --- /dev/null +++ b/src/modules/Elsa.EntityFrameworkCore.Oracle/SetupForManagement.cs @@ -0,0 +1,39 @@ +using System.Linq.Expressions; +using Elsa.Workflows.Management.Entities; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata; + +namespace Elsa.EntityFrameworkCore.Oracle; + +/// +/// Represents a class that handles entity model creation for SQLite databases. +/// +public class SetupForManagement : IEntityModelCreatingHandler +{ + private static Expression> VersionToStringConverter => v => v != null ? v.ToString() : null; + private static Expression> StringToVersionConverter => v => v != null ? Version.Parse(v) : null; + + /// + public void Handle(ElsaDbContextBase dbContext, ModelBuilder modelBuilder, IMutableEntityType entityType) + { + if(!dbContext.Database.IsOracle()) + return; + + // In order to use data more than 2000 char we have to use NCLOB. + // In Oracle, we have to explicitly say the column is NCLOB otherwise it would be considered nvarchar(2000). + modelBuilder.Entity().Property("Data").HasColumnType("NCLOB"); + modelBuilder.Entity().Ignore(x => x.WorkflowState); + modelBuilder.Entity().Ignore(x => x.CustomProperties); + modelBuilder.Entity().Ignore(x => x.Variables); + modelBuilder.Entity().Ignore(x => x.Inputs); + modelBuilder.Entity().Ignore(x => x.Outputs); + modelBuilder.Entity().Ignore(x => x.Outcomes); + modelBuilder.Entity().Ignore(x => x.Options); + modelBuilder.Entity().Property(x => x.ToolVersion).HasConversion(VersionToStringConverter, StringToVersionConverter); + modelBuilder.Entity().Property("StringData").HasColumnType("NCLOB"); + modelBuilder.Entity().Property("Data").HasColumnType("NCLOB"); + modelBuilder.Entity().Property(x => x.Description).HasColumnType("NCLOB"); + modelBuilder.Entity().Property(x => x.MaterializerContext).HasColumnType("NCLOB"); + modelBuilder.Entity().Property(x => x.BinaryData).HasColumnType("BLOB"); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.EntityFrameworkCore/Modules/Runtime/SetupForOracle.cs b/src/modules/Elsa.EntityFrameworkCore.Oracle/SetupForRuntime.cs similarity index 95% rename from src/modules/Elsa.EntityFrameworkCore/Modules/Runtime/SetupForOracle.cs rename to src/modules/Elsa.EntityFrameworkCore.Oracle/SetupForRuntime.cs index 9820dfbab..1ccab2951 100644 --- a/src/modules/Elsa.EntityFrameworkCore/Modules/Runtime/SetupForOracle.cs +++ b/src/modules/Elsa.EntityFrameworkCore.Oracle/SetupForRuntime.cs @@ -1,15 +1,14 @@ -using Elsa.EntityFrameworkCore.Extensions; using Elsa.KeyValues.Entities; using Elsa.Workflows.Runtime.Entities; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata; -namespace Elsa.EntityFrameworkCore.Modules.Runtime; +namespace Elsa.EntityFrameworkCore.Oracle; /// /// Represents a class that handles entity model creation for SQLite databases. /// -public class SetupForOracle : IEntityModelCreatingHandler +public class SetupForRuntime : IEntityModelCreatingHandler { /// public void Handle(ElsaDbContextBase dbContext, ModelBuilder modelBuilder, IMutableEntityType entityType) diff --git a/src/modules/Elsa.EntityFrameworkCore.Common/EntityHandlers/SetupForSqlite.cs b/src/modules/Elsa.EntityFrameworkCore.Sqlite/SetupForSqlite.cs similarity index 95% rename from src/modules/Elsa.EntityFrameworkCore.Common/EntityHandlers/SetupForSqlite.cs rename to src/modules/Elsa.EntityFrameworkCore.Sqlite/SetupForSqlite.cs index 500c6f176..8d60ac962 100644 --- a/src/modules/Elsa.EntityFrameworkCore.Common/EntityHandlers/SetupForSqlite.cs +++ b/src/modules/Elsa.EntityFrameworkCore.Sqlite/SetupForSqlite.cs @@ -2,7 +2,7 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -namespace Elsa.EntityFrameworkCore.EntityHandlers; +namespace Elsa.EntityFrameworkCore.Sqlite; /// /// Represents a class that handles entity model creation for SQLite databases. diff --git a/src/modules/Elsa.EntityFrameworkCore.Sqlite/SqliteProvidersExtensions.cs b/src/modules/Elsa.EntityFrameworkCore.Sqlite/SqliteProvidersExtensions.cs index 635abfac5..561b35428 100644 --- a/src/modules/Elsa.EntityFrameworkCore.Sqlite/SqliteProvidersExtensions.cs +++ b/src/modules/Elsa.EntityFrameworkCore.Sqlite/SqliteProvidersExtensions.cs @@ -1,7 +1,10 @@ using System.Reflection; using Elsa.EntityFrameworkCore.EntityHandlers; +using Elsa.EntityFrameworkCore.Sqlite; +using Elsa.Extensions; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; // ReSharper disable once CheckNamespace namespace Elsa.EntityFrameworkCore.Extensions; @@ -65,7 +68,8 @@ public static class SqliteProvidersExtensions where TDbContext : ElsaDbContextBase where TFeature : PersistenceFeatureBase { - feature.Module.Services.AddScoped(); + + feature.Module.Services.TryAddScopedImplementation(); feature.DbContextOptionsBuilder = (sp, db) => db.UseElsaSqlite(migrationsAssembly, connectionStringFunc(sp), options, configure: configure); return (TFeature)feature; } diff --git a/src/modules/Elsa.EntityFrameworkCore/Modules/Alterations/Feature.cs b/src/modules/Elsa.EntityFrameworkCore/Modules/Alterations/Feature.cs index f05d8442d..de79b7815 100644 --- a/src/modules/Elsa.EntityFrameworkCore/Modules/Alterations/Feature.cs +++ b/src/modules/Elsa.EntityFrameworkCore/Modules/Alterations/Feature.cs @@ -28,6 +28,5 @@ public class EFCoreAlterationsPersistenceFeature(IModule module) : PersistenceFe base.Apply(); AddEntityStore(); AddEntityStore(); - Services.AddScoped(); } } \ No newline at end of file diff --git a/src/modules/Elsa.EntityFrameworkCore/Modules/Management/SetupForOracle.cs b/src/modules/Elsa.EntityFrameworkCore/Modules/Management/SetupForOracle.cs deleted file mode 100644 index da338d428..000000000 --- a/src/modules/Elsa.EntityFrameworkCore/Modules/Management/SetupForOracle.cs +++ /dev/null @@ -1,25 +0,0 @@ -using Elsa.EntityFrameworkCore.Extensions; -using Elsa.Workflows.Management.Entities; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Metadata; - -namespace Elsa.EntityFrameworkCore.Modules.Management; - -/// -/// Represents a class that handles entity model creation for SQLite databases. -/// -public class SetupForOracle : IEntityModelCreatingHandler -{ - /// - public void Handle(ElsaDbContextBase dbContext, ModelBuilder modelBuilder, IMutableEntityType entityType) - { - if(!dbContext.Database.IsOracle()) - return; - - // In order to use data more than 2000 char we have to use NCLOB. - // In Oracle, we have to explicitly say the column is NCLOB otherwise it would be considered nvarchar(2000). - modelBuilder.Entity().Property("Data").HasColumnType("NCLOB"); - modelBuilder.Entity().Property("StringData").HasColumnType("NCLOB"); - modelBuilder.Entity().Property("Data").HasColumnType("NCLOB"); - } -} \ No newline at end of file diff --git a/src/modules/Elsa.EntityFrameworkCore/Modules/Management/WorkflowDefinitionPersistenceFeature.cs b/src/modules/Elsa.EntityFrameworkCore/Modules/Management/WorkflowDefinitionPersistenceFeature.cs index b84f3ef23..3b808a942 100644 --- a/src/modules/Elsa.EntityFrameworkCore/Modules/Management/WorkflowDefinitionPersistenceFeature.cs +++ b/src/modules/Elsa.EntityFrameworkCore/Modules/Management/WorkflowDefinitionPersistenceFeature.cs @@ -10,6 +10,7 @@ namespace Elsa.EntityFrameworkCore.Modules.Management; /// Configures the feature with an Entity Framework Core persistence provider. /// [DependsOn(typeof(WorkflowManagementFeature))] +[DependsOn(typeof(WorkflowDefinitionsFeature))] public class EFCoreWorkflowDefinitionPersistenceFeature(IModule module) : PersistenceFeatureBase(module) { /// diff --git a/src/modules/Elsa.EntityFrameworkCore/Modules/Management/WorkflowInstancePersistenceFeature.cs b/src/modules/Elsa.EntityFrameworkCore/Modules/Management/WorkflowInstancePersistenceFeature.cs index 8858c9757..de019e808 100644 --- a/src/modules/Elsa.EntityFrameworkCore/Modules/Management/WorkflowInstancePersistenceFeature.cs +++ b/src/modules/Elsa.EntityFrameworkCore/Modules/Management/WorkflowInstancePersistenceFeature.cs @@ -10,6 +10,7 @@ namespace Elsa.EntityFrameworkCore.Modules.Management; /// Configures the feature with an Entity Framework Core persistence provider. /// [DependsOn(typeof(WorkflowManagementFeature))] +[DependsOn(typeof(WorkflowInstancesFeature))] public class EFCoreWorkflowInstancePersistenceFeature(IModule module) : PersistenceFeatureBase(module) { /// @@ -23,6 +24,5 @@ public class EFCoreWorkflowInstancePersistenceFeature(IModule module) : Persiste { base.Apply(); AddEntityStore(); - Services.AddScoped(); } } \ No newline at end of file diff --git a/src/modules/Elsa.EntityFrameworkCore/Modules/Management/WorkflowManagementPersistenceFeature.cs b/src/modules/Elsa.EntityFrameworkCore/Modules/Management/WorkflowManagementPersistenceFeature.cs index 5699442c6..09e9e20b2 100644 --- a/src/modules/Elsa.EntityFrameworkCore/Modules/Management/WorkflowManagementPersistenceFeature.cs +++ b/src/modules/Elsa.EntityFrameworkCore/Modules/Management/WorkflowManagementPersistenceFeature.cs @@ -1,33 +1,27 @@ using Elsa.Features.Attributes; using Elsa.Features.Services; -using Elsa.Workflows.Management.Entities; using Elsa.Workflows.Management.Features; using JetBrains.Annotations; -using Microsoft.Extensions.DependencyInjection; +using Microsoft.EntityFrameworkCore; namespace Elsa.EntityFrameworkCore.Modules.Management; /// /// Configures the and features with an Entity Framework Core persistence provider. /// -[DependsOn(typeof(WorkflowManagementFeature))] -[DependsOn(typeof(WorkflowInstancesFeature))] -[DependsOn(typeof(WorkflowDefinitionsFeature))] +[DependsOn(typeof(EFCoreWorkflowInstancePersistenceFeature))] +[DependsOn(typeof(EFCoreWorkflowDefinitionPersistenceFeature))] [PublicAPI] public class WorkflowManagementPersistenceFeature(IModule module) : PersistenceFeatureBase(module) { - /// - public override void Configure() + public override Action DbContextOptionsBuilder { - Module.Configure(feature => feature.WorkflowInstanceStore = sp => sp.GetRequiredService()); - Module.Configure(feature => feature.WorkflowDefinitionStore = sp => sp.GetRequiredService()); - } - - /// - public override void Apply() - { - base.Apply(); - AddEntityStore(); - AddEntityStore(); + get => base.DbContextOptionsBuilder; + set + { + base.DbContextOptionsBuilder = value; + Module.Configure(x => x.DbContextOptionsBuilder = value); + Module.Configure(x => x.DbContextOptionsBuilder = value); + } } } \ No newline at end of file diff --git a/src/modules/Elsa.EntityFrameworkCore/Modules/Runtime/WorkflowRuntimePersistenceFeature.cs b/src/modules/Elsa.EntityFrameworkCore/Modules/Runtime/WorkflowRuntimePersistenceFeature.cs index f7b5a00be..a3ab463db 100644 --- a/src/modules/Elsa.EntityFrameworkCore/Modules/Runtime/WorkflowRuntimePersistenceFeature.cs +++ b/src/modules/Elsa.EntityFrameworkCore/Modules/Runtime/WorkflowRuntimePersistenceFeature.cs @@ -41,6 +41,5 @@ public class EFCoreWorkflowRuntimePersistenceFeature(IModule module) : Persisten AddEntityStore(); AddEntityStore(); AddStore(); - Services.AddScoped(); } } \ No newline at end of file