From 2d3ab102b5d96f864c28c53d49527e8a152cb619 Mon Sep 17 00:00:00 2001 From: colin Date: Wed, 2 Apr 2025 08:16:48 +0800 Subject: [PATCH] feat(elsa): Added automatic elsa database migration --- ....Abp.Elsa.EntityFrameworkCore.MySql.csproj | 8 + .../AbpElsaEntityFrameworkCoreMySqlModule.cs | 9 + .../MySql/Migrations/Initial.sql | 315 ++++++++++++++++++ .../Migrations/MySqlElsaDataBaseInstaller.cs | 130 ++++++++ .../AbpElsaEntityFrameworkCoreModule.cs | 13 +- .../Migrations/IElsaDataBaseInstaller.cs | 8 + 6 files changed, 482 insertions(+), 1 deletion(-) create mode 100644 aspnet-core/modules/elsa/LINGYUN.Abp.Elsa.EntityFrameworkCore.MySql/LINGYUN/Abp/Elsa/EntityFrameworkCore/MySql/Migrations/Initial.sql create mode 100644 aspnet-core/modules/elsa/LINGYUN.Abp.Elsa.EntityFrameworkCore.MySql/LINGYUN/Abp/Elsa/EntityFrameworkCore/MySql/Migrations/MySqlElsaDataBaseInstaller.cs create mode 100644 aspnet-core/modules/elsa/LINGYUN.Abp.Elsa.EntityFrameworkCore/LINGYUN/Abp/Elsa/EntityFrameworkCore/Migrations/IElsaDataBaseInstaller.cs diff --git a/aspnet-core/modules/elsa/LINGYUN.Abp.Elsa.EntityFrameworkCore.MySql/LINGYUN.Abp.Elsa.EntityFrameworkCore.MySql.csproj b/aspnet-core/modules/elsa/LINGYUN.Abp.Elsa.EntityFrameworkCore.MySql/LINGYUN.Abp.Elsa.EntityFrameworkCore.MySql.csproj index ab9fcb726..e77867d78 100644 --- a/aspnet-core/modules/elsa/LINGYUN.Abp.Elsa.EntityFrameworkCore.MySql/LINGYUN.Abp.Elsa.EntityFrameworkCore.MySql.csproj +++ b/aspnet-core/modules/elsa/LINGYUN.Abp.Elsa.EntityFrameworkCore.MySql/LINGYUN.Abp.Elsa.EntityFrameworkCore.MySql.csproj @@ -13,6 +13,14 @@ + + + + + + + + diff --git a/aspnet-core/modules/elsa/LINGYUN.Abp.Elsa.EntityFrameworkCore.MySql/LINGYUN/Abp/Elsa/EntityFrameworkCore/MySql/AbpElsaEntityFrameworkCoreMySqlModule.cs b/aspnet-core/modules/elsa/LINGYUN.Abp.Elsa.EntityFrameworkCore.MySql/LINGYUN/Abp/Elsa/EntityFrameworkCore/MySql/AbpElsaEntityFrameworkCoreMySqlModule.cs index 45069e0a8..5b8ce2f5a 100644 --- a/aspnet-core/modules/elsa/LINGYUN.Abp.Elsa.EntityFrameworkCore.MySql/LINGYUN/Abp/Elsa/EntityFrameworkCore/MySql/AbpElsaEntityFrameworkCoreMySqlModule.cs +++ b/aspnet-core/modules/elsa/LINGYUN.Abp.Elsa.EntityFrameworkCore.MySql/LINGYUN/Abp/Elsa/EntityFrameworkCore/MySql/AbpElsaEntityFrameworkCoreMySqlModule.cs @@ -3,6 +3,7 @@ using Elsa.Options; using Microsoft.Extensions.DependencyInjection; using Volo.Abp.EntityFrameworkCore.MySQL; using Volo.Abp.Modularity; +using Volo.Abp.VirtualFileSystem; namespace LINGYUN.Abp.Elsa.EntityFrameworkCore.MySql; @@ -26,4 +27,12 @@ public class AbpElsaEntityFrameworkCoreMySqlModule : AbpModule elsa.AddFeatures(startups, configuration); }); } + + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(options => + { + options.FileSets.AddEmbedded(); + }); + } } diff --git a/aspnet-core/modules/elsa/LINGYUN.Abp.Elsa.EntityFrameworkCore.MySql/LINGYUN/Abp/Elsa/EntityFrameworkCore/MySql/Migrations/Initial.sql b/aspnet-core/modules/elsa/LINGYUN.Abp.Elsa.EntityFrameworkCore.MySql/LINGYUN/Abp/Elsa/EntityFrameworkCore/MySql/Migrations/Initial.sql new file mode 100644 index 000000000..0ca9b20ae --- /dev/null +++ b/aspnet-core/modules/elsa/LINGYUN.Abp.Elsa.EntityFrameworkCore.MySql/LINGYUN/Abp/Elsa/EntityFrameworkCore/MySql/Migrations/Initial.sql @@ -0,0 +1,315 @@ +-- basic script + +USE `${DataBase}`; + +CREATE TABLE IF NOT EXISTS `__EFMigrationsHistory` ( + `MigrationId` varchar(150) CHARACTER SET utf8mb4 NOT NULL, + `ProductVersion` varchar(32) CHARACTER SET utf8mb4 NOT NULL, + CONSTRAINT `PK___EFMigrationsHistory` PRIMARY KEY (`MigrationId`) +) CHARACTER SET utf8mb4; + +START TRANSACTION; + +ALTER DATABASE CHARACTER SET utf8mb4; + +CREATE TABLE `Bookmarks` ( + `Id` varchar(255) CHARACTER SET utf8mb4 NOT NULL, + `TenantId` varchar(255) CHARACTER SET utf8mb4 NULL, + `Hash` varchar(255) CHARACTER SET utf8mb4 NOT NULL, + `Model` longtext CHARACTER SET utf8mb4 NOT NULL, + `ModelType` longtext CHARACTER SET utf8mb4 NOT NULL, + `ActivityType` varchar(255) CHARACTER SET utf8mb4 NOT NULL, + `ActivityId` varchar(255) CHARACTER SET utf8mb4 NOT NULL, + `WorkflowInstanceId` varchar(255) CHARACTER SET utf8mb4 NOT NULL, + `CorrelationId` varchar(255) CHARACTER SET utf8mb4 NULL, + CONSTRAINT `PK_Bookmarks` PRIMARY KEY (`Id`) +) CHARACTER SET utf8mb4; + +CREATE TABLE `WorkflowDefinitions` ( + `Id` varchar(255) CHARACTER SET utf8mb4 NOT NULL, + `DefinitionId` varchar(255) CHARACTER SET utf8mb4 NOT NULL, + `TenantId` varchar(255) CHARACTER SET utf8mb4 NULL, + `Name` varchar(255) CHARACTER SET utf8mb4 NULL, + `DisplayName` longtext CHARACTER SET utf8mb4 NULL, + `Description` longtext CHARACTER SET utf8mb4 NULL, + `Version` int NOT NULL, + `IsSingleton` tinyint(1) NOT NULL, + `PersistenceBehavior` int NOT NULL, + `DeleteCompletedInstances` tinyint(1) NOT NULL, + `IsPublished` tinyint(1) NOT NULL, + `IsLatest` tinyint(1) NOT NULL, + `Tag` varchar(255) CHARACTER SET utf8mb4 NULL, + `Data` longtext CHARACTER SET utf8mb4 NULL, + CONSTRAINT `PK_WorkflowDefinitions` PRIMARY KEY (`Id`) +) CHARACTER SET utf8mb4; + +CREATE TABLE `WorkflowExecutionLogRecords` ( + `Id` varchar(255) CHARACTER SET utf8mb4 NOT NULL, + `TenantId` varchar(255) CHARACTER SET utf8mb4 NULL, + `WorkflowInstanceId` varchar(255) CHARACTER SET utf8mb4 NOT NULL, + `ActivityId` varchar(255) CHARACTER SET utf8mb4 NOT NULL, + `ActivityType` varchar(255) CHARACTER SET utf8mb4 NOT NULL, + `Timestamp` datetime(6) NOT NULL, + `EventName` longtext CHARACTER SET utf8mb4 NULL, + `Message` longtext CHARACTER SET utf8mb4 NULL, + `Source` longtext CHARACTER SET utf8mb4 NULL, + `Data` longtext CHARACTER SET utf8mb4 NULL, + CONSTRAINT `PK_WorkflowExecutionLogRecords` PRIMARY KEY (`Id`) +) CHARACTER SET utf8mb4; + +CREATE TABLE `WorkflowInstances` ( + `Id` varchar(255) CHARACTER SET utf8mb4 NOT NULL, + `DefinitionId` varchar(255) CHARACTER SET utf8mb4 NOT NULL, + `TenantId` varchar(255) CHARACTER SET utf8mb4 NULL, + `Version` int NOT NULL, + `WorkflowStatus` int NOT NULL, + `CorrelationId` varchar(255) CHARACTER SET utf8mb4 NULL, + `ContextType` varchar(255) CHARACTER SET utf8mb4 NULL, + `ContextId` varchar(255) CHARACTER SET utf8mb4 NULL, + `Name` varchar(255) CHARACTER SET utf8mb4 NULL, + `CreatedAt` datetime(6) NOT NULL, + `LastExecutedAt` datetime(6) NULL, + `FinishedAt` datetime(6) NULL, + `CancelledAt` datetime(6) NULL, + `FaultedAt` datetime(6) NULL, + `Data` longtext CHARACTER SET utf8mb4 NULL, + CONSTRAINT `PK_WorkflowInstances` PRIMARY KEY (`Id`) +) CHARACTER SET utf8mb4; + +CREATE INDEX `IX_Bookmark_ActivityId` ON `Bookmarks` (`ActivityId`); + +CREATE INDEX `IX_Bookmark_ActivityType` ON `Bookmarks` (`ActivityType`); + +CREATE INDEX `IX_Bookmark_ActivityType_TenantId_Hash` ON `Bookmarks` (`ActivityType`, `TenantId`, `Hash`); + +CREATE INDEX `IX_Bookmark_CorrelationId` ON `Bookmarks` (`CorrelationId`); + +CREATE INDEX `IX_Bookmark_Hash` ON `Bookmarks` (`Hash`); + +CREATE INDEX `IX_Bookmark_Hash_CorrelationId_TenantId` ON `Bookmarks` (`Hash`, `CorrelationId`, `TenantId`); + +CREATE INDEX `IX_Bookmark_TenantId` ON `Bookmarks` (`TenantId`); + +CREATE INDEX `IX_Bookmark_WorkflowInstanceId` ON `Bookmarks` (`WorkflowInstanceId`); + +CREATE UNIQUE INDEX `IX_WorkflowDefinition_DefinitionId_VersionId` ON `WorkflowDefinitions` (`DefinitionId`, `Version`); + +CREATE INDEX `IX_WorkflowDefinition_IsLatest` ON `WorkflowDefinitions` (`IsLatest`); + +CREATE INDEX `IX_WorkflowDefinition_IsPublished` ON `WorkflowDefinitions` (`IsPublished`); + +CREATE INDEX `IX_WorkflowDefinition_Name` ON `WorkflowDefinitions` (`Name`); + +CREATE INDEX `IX_WorkflowDefinition_Tag` ON `WorkflowDefinitions` (`Tag`); + +CREATE INDEX `IX_WorkflowDefinition_TenantId` ON `WorkflowDefinitions` (`TenantId`); + +CREATE INDEX `IX_WorkflowDefinition_Version` ON `WorkflowDefinitions` (`Version`); + +CREATE INDEX `IX_WorkflowExecutionLogRecord_ActivityId` ON `WorkflowExecutionLogRecords` (`ActivityId`); + +CREATE INDEX `IX_WorkflowExecutionLogRecord_ActivityType` ON `WorkflowExecutionLogRecords` (`ActivityType`); + +CREATE INDEX `IX_WorkflowExecutionLogRecord_TenantId` ON `WorkflowExecutionLogRecords` (`TenantId`); + +CREATE INDEX `IX_WorkflowExecutionLogRecord_Timestamp` ON `WorkflowExecutionLogRecords` (`Timestamp`); + +CREATE INDEX `IX_WorkflowExecutionLogRecord_WorkflowInstanceId` ON `WorkflowExecutionLogRecords` (`WorkflowInstanceId`); + +CREATE INDEX `IX_WorkflowInstance_ContextId` ON `WorkflowInstances` (`ContextId`); + +CREATE INDEX `IX_WorkflowInstance_ContextType` ON `WorkflowInstances` (`ContextType`); + +CREATE INDEX `IX_WorkflowInstance_CorrelationId` ON `WorkflowInstances` (`CorrelationId`); + +CREATE INDEX `IX_WorkflowInstance_CreatedAt` ON `WorkflowInstances` (`CreatedAt`); + +CREATE INDEX `IX_WorkflowInstance_DefinitionId` ON `WorkflowInstances` (`DefinitionId`); + +CREATE INDEX `IX_WorkflowInstance_FaultedAt` ON `WorkflowInstances` (`FaultedAt`); + +CREATE INDEX `IX_WorkflowInstance_FinishedAt` ON `WorkflowInstances` (`FinishedAt`); + +CREATE INDEX `IX_WorkflowInstance_LastExecutedAt` ON `WorkflowInstances` (`LastExecutedAt`); + +CREATE INDEX `IX_WorkflowInstance_Name` ON `WorkflowInstances` (`Name`); + +CREATE INDEX `IX_WorkflowInstance_TenantId` ON `WorkflowInstances` (`TenantId`); + +CREATE INDEX `IX_WorkflowInstance_WorkflowStatus` ON `WorkflowInstances` (`WorkflowStatus`); + +CREATE INDEX `IX_WorkflowInstance_WorkflowStatus_DefinitionId` ON `WorkflowInstances` (`WorkflowStatus`, `DefinitionId`); + +CREATE INDEX `IX_WorkflowInstance_WorkflowStatus_DefinitionId_Version` ON `WorkflowInstances` (`WorkflowStatus`, `DefinitionId`, `Version`); + +INSERT INTO `__EFMigrationsHistory` (`MigrationId`, `ProductVersion`) +VALUES ('20210523093427_Initial', '5.0.10'); + +COMMIT; + +START TRANSACTION; + +ALTER TABLE `WorkflowInstances` MODIFY COLUMN `CorrelationId` varchar(255) CHARACTER SET utf8mb4 NOT NULL DEFAULT ''; + +ALTER TABLE `WorkflowInstances` ADD `LastExecutedActivityId` longtext CHARACTER SET utf8mb4 NULL; + +ALTER TABLE `WorkflowDefinitions` ADD `OutputStorageProviderName` longtext CHARACTER SET utf8mb4 NULL; + +INSERT INTO `__EFMigrationsHistory` (`MigrationId`, `ProductVersion`) +VALUES ('20210611200027_Update21', '5.0.10'); + +COMMIT; + +START TRANSACTION; + +ALTER TABLE `WorkflowDefinitions` DROP COLUMN `OutputStorageProviderName`; + +ALTER TABLE `WorkflowInstances` RENAME `WorkflowInstances`; + +ALTER TABLE `WorkflowExecutionLogRecords` RENAME `WorkflowExecutionLogRecords`; + +ALTER TABLE `WorkflowDefinitions` RENAME `WorkflowDefinitions`; + +ALTER TABLE `Bookmarks` RENAME `Bookmarks`; + +INSERT INTO `__EFMigrationsHistory` (`MigrationId`, `ProductVersion`) +VALUES ('20210923112211_Update23', '5.0.10'); + +COMMIT; + +START TRANSACTION; + +ALTER TABLE `WorkflowInstances` ADD `DefinitionVersionId` longtext CHARACTER SET utf8mb4 NOT NULL; + +ALTER TABLE `Bookmarks` MODIFY COLUMN `CorrelationId` varchar(255) CHARACTER SET utf8mb4 NOT NULL DEFAULT ''; + +INSERT INTO `__EFMigrationsHistory` (`MigrationId`, `ProductVersion`) +VALUES ('20211215100204_Update24', '5.0.10'); + +COMMIT; + +START TRANSACTION; + +ALTER TABLE `WorkflowInstances` MODIFY COLUMN `DefinitionVersionId` varchar(255) CHARACTER SET utf8mb4 NOT NULL; + +CREATE INDEX `IX_WorkflowInstance_DefinitionVersionId` ON `WorkflowInstances` (`DefinitionVersionId`); + +INSERT INTO `__EFMigrationsHistory` (`MigrationId`, `ProductVersion`) +VALUES ('20220120170050_Update241', '5.0.10'); + +COMMIT; + +START TRANSACTION; + +CREATE TABLE `Triggers` ( + `Id` varchar(255) CHARACTER SET utf8mb4 NOT NULL, + `TenantId` varchar(255) CHARACTER SET utf8mb4 NULL, + `Hash` varchar(255) CHARACTER SET utf8mb4 NOT NULL, + `Model` longtext CHARACTER SET utf8mb4 NOT NULL, + `ModelType` longtext CHARACTER SET utf8mb4 NOT NULL, + `ActivityType` varchar(255) CHARACTER SET utf8mb4 NOT NULL, + `ActivityId` varchar(255) CHARACTER SET utf8mb4 NOT NULL, + `WorkflowDefinitionId` varchar(255) CHARACTER SET utf8mb4 NOT NULL, + CONSTRAINT `PK_Triggers` PRIMARY KEY (`Id`) +) CHARACTER SET utf8mb4; + +CREATE INDEX `IX_Trigger_ActivityId` ON `Triggers` (`ActivityId`); + +CREATE INDEX `IX_Trigger_ActivityType` ON `Triggers` (`ActivityType`); + +CREATE INDEX `IX_Trigger_ActivityType_TenantId_Hash` ON `Triggers` (`ActivityType`, `TenantId`, `Hash`); + +CREATE INDEX `IX_Trigger_Hash` ON `Triggers` (`Hash`); + +CREATE INDEX `IX_Trigger_Hash_TenantId` ON `Triggers` (`Hash`, `TenantId`); + +CREATE INDEX `IX_Trigger_TenantId` ON `Triggers` (`TenantId`); + +CREATE INDEX `IX_Trigger_WorkflowDefinitionId` ON `Triggers` (`WorkflowDefinitionId`); + +INSERT INTO `__EFMigrationsHistory` (`MigrationId`, `ProductVersion`) +VALUES ('20220120204150_Update25', '5.0.10'); + +COMMIT; + +START TRANSACTION; + +ALTER TABLE `WorkflowDefinitions` ADD `CreatedAt` datetime(6) NOT NULL DEFAULT '0001-01-01 00:00:00'; + +INSERT INTO `__EFMigrationsHistory` (`MigrationId`, `ProductVersion`) +VALUES ('20220512203646_Update28', '5.0.10'); + +COMMIT; + + +-- webhooks + +CREATE TABLE IF NOT EXISTS `__EFMigrationsHistory` ( + `MigrationId` varchar(150) CHARACTER SET utf8mb4 NOT NULL, + `ProductVersion` varchar(32) CHARACTER SET utf8mb4 NOT NULL, + CONSTRAINT `PK___EFMigrationsHistory` PRIMARY KEY (`MigrationId`) +) CHARACTER SET utf8mb4; + +START TRANSACTION; + +ALTER DATABASE CHARACTER SET utf8mb4; + +CREATE TABLE `WebhookDefinitions` ( + `Id` varchar(255) CHARACTER SET utf8mb4 NOT NULL, + `TenantId` varchar(255) CHARACTER SET utf8mb4 NULL, + `Name` varchar(255) CHARACTER SET utf8mb4 NOT NULL, + `Path` varchar(255) CHARACTER SET utf8mb4 NOT NULL, + `Description` varchar(255) CHARACTER SET utf8mb4 NULL, + `PayloadTypeName` varchar(255) CHARACTER SET utf8mb4 NULL, + `IsEnabled` tinyint(1) NOT NULL, + CONSTRAINT `PK_WebhookDefinitions` PRIMARY KEY (`Id`) +) CHARACTER SET utf8mb4; + +CREATE INDEX `IX_WebhookDefinition_Description` ON `WebhookDefinitions` (`Description`); + +CREATE INDEX `IX_WebhookDefinition_IsEnabled` ON `WebhookDefinitions` (`IsEnabled`); + +CREATE INDEX `IX_WebhookDefinition_Name` ON `WebhookDefinitions` (`Name`); + +CREATE INDEX `IX_WebhookDefinition_Path` ON `WebhookDefinitions` (`Path`); + +CREATE INDEX `IX_WebhookDefinition_PayloadTypeName` ON `WebhookDefinitions` (`PayloadTypeName`); + +CREATE INDEX `IX_WebhookDefinition_TenantId` ON `WebhookDefinitions` (`TenantId`); + +INSERT INTO `__EFMigrationsHistory` (`MigrationId`, `ProductVersion`) +VALUES ('20210604065041_Initial', '5.0.10'); + +COMMIT; + + +-- workflow-settings + +CREATE TABLE IF NOT EXISTS `__EFMigrationsHistory` ( + `MigrationId` varchar(150) CHARACTER SET utf8mb4 NOT NULL, + `ProductVersion` varchar(32) CHARACTER SET utf8mb4 NOT NULL, + CONSTRAINT `PK___EFMigrationsHistory` PRIMARY KEY (`MigrationId`) +) CHARACTER SET utf8mb4; + +START TRANSACTION; + +ALTER DATABASE CHARACTER SET utf8mb4; + +CREATE TABLE `WorkflowSettings` ( + `Id` varchar(255) CHARACTER SET utf8mb4 NOT NULL, + `WorkflowBlueprintId` varchar(255) CHARACTER SET utf8mb4 NULL, + `Key` varchar(255) CHARACTER SET utf8mb4 NULL, + `Value` varchar(255) CHARACTER SET utf8mb4 NULL, + CONSTRAINT `PK_WorkflowSettings` PRIMARY KEY (`Id`) +) CHARACTER SET utf8mb4; + +CREATE INDEX `IX_WorkflowSetting_Key` ON `WorkflowSettings` (`Key`); + +CREATE INDEX `IX_WorkflowSetting_Value` ON `WorkflowSettings` (`Value`); + +CREATE INDEX `IX_WorkflowSetting_WorkflowBlueprintId` ON `WorkflowSettings` (`WorkflowBlueprintId`); + +INSERT INTO `__EFMigrationsHistory` (`MigrationId`, `ProductVersion`) +VALUES ('20210730112043_Initial', '5.0.10'); + +COMMIT; diff --git a/aspnet-core/modules/elsa/LINGYUN.Abp.Elsa.EntityFrameworkCore.MySql/LINGYUN/Abp/Elsa/EntityFrameworkCore/MySql/Migrations/MySqlElsaDataBaseInstaller.cs b/aspnet-core/modules/elsa/LINGYUN.Abp.Elsa.EntityFrameworkCore.MySql/LINGYUN/Abp/Elsa/EntityFrameworkCore/MySql/Migrations/MySqlElsaDataBaseInstaller.cs new file mode 100644 index 000000000..2c3fbdddb --- /dev/null +++ b/aspnet-core/modules/elsa/LINGYUN.Abp.Elsa.EntityFrameworkCore.MySql/LINGYUN/Abp/Elsa/EntityFrameworkCore/MySql/Migrations/MySqlElsaDataBaseInstaller.cs @@ -0,0 +1,130 @@ +using LINGYUN.Abp.Elsa.EntityFrameworkCore.Migrations; +using Microsoft.Extensions.FileProviders; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; +using MySqlConnector; +using System; +using System.Data; +using System.Threading.Tasks; +using Volo.Abp.Data; +using Volo.Abp.DependencyInjection; +using Volo.Abp.VirtualFileSystem; + +namespace LINGYUN.Abp.Elsa.EntityFrameworkCore.MySql.Migrations; + +[Dependency(ReplaceServices = true)] +public class MySqlElsaDataBaseInstaller : IElsaDataBaseInstaller, ITransientDependency +{ + public ILogger Logger { protected get; set; } + + private readonly IVirtualFileProvider _virtualFileProvider; + private readonly IConnectionStringResolver _connectionStringResolver; + + public MySqlElsaDataBaseInstaller( + IVirtualFileProvider virtualFileProvider, + IConnectionStringResolver connectionStringResolver) + { + _virtualFileProvider = virtualFileProvider; + _connectionStringResolver = connectionStringResolver; + + Logger = NullLogger.Instance; + } + + public async virtual Task InstallAsync() + { + var connectionString = await _connectionStringResolver.ResolveAsync("Workflow"); + if (connectionString.IsNullOrWhiteSpace()) + { + Logger.LogWarning("Please configure the `Workflow` database connection string Workflow!"); + throw new ArgumentNullException(nameof(connectionString)); + } + + var builder = new MySqlConnectionStringBuilder(connectionString); + + var dataBaseName = await CreateDataBaseIfNotExists(builder.Database, builder); + + builder.Database = dataBaseName; + + using var mySqlConnection = new MySqlConnection(builder.ConnectionString); + + if (mySqlConnection.State == ConnectionState.Closed) + { + await mySqlConnection.OpenAsync(); + } + + using (var mySqlCommand = new MySqlCommand("SELECT COUNT(1) FROM `information_schema`.`TABLES` WHERE `TABLE_SCHEMA` = @DataBaseName;", mySqlConnection)) + { + mySqlCommand.Parameters.Add("@DataBaseName", MySqlDbType.String).Value = dataBaseName; + + var rowsAffects = await mySqlCommand.ExecuteScalarAsync() as long?; + if (rowsAffects > 0) + { + Logger.LogInformation($"The `{dataBaseName}` database has already exists."); + return; + } + } + + var sqlScript = await GetInitSqlScript(); + + // USE `${DataBase}` -> USE `Workflow`;; + sqlScript = sqlScript.ReplaceFirst("${DataBase}", dataBaseName); + + using (var mySqlCommand = new MySqlCommand(sqlScript, mySqlConnection)) + { + Logger.LogInformation("The database initialization script `Initial.sql` starts..."); + + await mySqlCommand.ExecuteNonQueryAsync(); + } + + Logger.LogInformation("Database initialization script `Initial.sql` complete!"); + } + + public async virtual Task CreateDataBaseIfNotExists(string dataBase, MySqlConnectionStringBuilder connectionStringBuilder) + { + // 切换主数据库查询数据库是否存在 + connectionStringBuilder.Database = "mysql"; + using var mySqlConnection = new MySqlConnection(connectionStringBuilder.ConnectionString); + if (mySqlConnection.State == ConnectionState.Closed) + { + await mySqlConnection.OpenAsync(); + } + + var checkDataBaseName = ""; + using (var mySqlCommand = new MySqlCommand("SELECT `SCHEMA_NAME` FROM `information_schema`.`SCHEMATA` WHERE `SCHEMA_NAME` = @DataBaseName;", mySqlConnection)) + { + var dataBaseParamter = mySqlCommand.Parameters.Add("DataBaseName", DbType.String); + dataBaseParamter.Value = dataBase; + + checkDataBaseName = await mySqlCommand.ExecuteScalarAsync() as string; + } + + if (checkDataBaseName.IsNullOrWhiteSpace()) + { + using (var mySqlCommand = new MySqlCommand($"CREATE DATABASE `{dataBase}` CHARACTER SET 'utf8mb4' COLLATE 'utf8mb4_general_ci';", mySqlConnection)) + { + await mySqlCommand.ExecuteNonQueryAsync(); + } + } + + return dataBase; + } + + public async virtual Task GetInitSqlScript() + { + var sqlScriptFileInfo = _virtualFileProvider.GetFileInfo("/LINGYUN/Abp/Elsa/EntityFrameworkCore/MySql/Migrations/Initial.sql"); + if (!sqlScriptFileInfo.Exists || sqlScriptFileInfo.IsDirectory) + { + Logger.LogWarning("Please Check that the `Initial.sql` file exists!"); + throw new InvalidOperationException("The `Initial.sql` database initialization script file does not exist or is not valid!"); + } + + var sqlScript = await sqlScriptFileInfo.ReadAsStringAsync(); + if (sqlScript.IsNullOrWhiteSpace()) + { + Logger.LogWarning("The contents of the `Initial.sql` file are empty or invalid!"); + throw new InvalidOperationException("The contents of the `Initial.sql` file are empty or invalid!"); + } + + return sqlScript; + } +} diff --git a/aspnet-core/modules/elsa/LINGYUN.Abp.Elsa.EntityFrameworkCore/LINGYUN/Abp/Elsa/EntityFrameworkCore/AbpElsaEntityFrameworkCoreModule.cs b/aspnet-core/modules/elsa/LINGYUN.Abp.Elsa.EntityFrameworkCore/LINGYUN/Abp/Elsa/EntityFrameworkCore/AbpElsaEntityFrameworkCoreModule.cs index 8d5ba8a20..025f6fb61 100644 --- a/aspnet-core/modules/elsa/LINGYUN.Abp.Elsa.EntityFrameworkCore/LINGYUN/Abp/Elsa/EntityFrameworkCore/AbpElsaEntityFrameworkCoreModule.cs +++ b/aspnet-core/modules/elsa/LINGYUN.Abp.Elsa.EntityFrameworkCore/LINGYUN/Abp/Elsa/EntityFrameworkCore/AbpElsaEntityFrameworkCoreModule.cs @@ -1,4 +1,8 @@ -using Volo.Abp.EntityFrameworkCore; +using LINGYUN.Abp.Elsa.EntityFrameworkCore.Migrations; +using Microsoft.Extensions.DependencyInjection; +using System.Threading.Tasks; +using Volo.Abp; +using Volo.Abp.EntityFrameworkCore; using Volo.Abp.Modularity; namespace LINGYUN.Abp.Elsa.EntityFrameworkCore; @@ -8,4 +12,11 @@ namespace LINGYUN.Abp.Elsa.EntityFrameworkCore; typeof(AbpEntityFrameworkCoreModule))] public class AbpElsaEntityFrameworkCoreModule : AbpModule { + public async override Task OnPreApplicationInitializationAsync(ApplicationInitializationContext context) + { + // 实现 IElsaStoreMigrator 接口自动初始化数据库 + await context.ServiceProvider + .GetService() + ?.InstallAsync(); + } } diff --git a/aspnet-core/modules/elsa/LINGYUN.Abp.Elsa.EntityFrameworkCore/LINGYUN/Abp/Elsa/EntityFrameworkCore/Migrations/IElsaDataBaseInstaller.cs b/aspnet-core/modules/elsa/LINGYUN.Abp.Elsa.EntityFrameworkCore/LINGYUN/Abp/Elsa/EntityFrameworkCore/Migrations/IElsaDataBaseInstaller.cs new file mode 100644 index 000000000..14a98839a --- /dev/null +++ b/aspnet-core/modules/elsa/LINGYUN.Abp.Elsa.EntityFrameworkCore/LINGYUN/Abp/Elsa/EntityFrameworkCore/Migrations/IElsaDataBaseInstaller.cs @@ -0,0 +1,8 @@ +using System.Threading.Tasks; + +namespace LINGYUN.Abp.Elsa.EntityFrameworkCore.Migrations; + +public interface IElsaDataBaseInstaller +{ + Task InstallAsync(); +}