From fb1665a74da878cbeffcf9fe66d1420f6a82eeaf Mon Sep 17 00:00:00 2001 From: colin Date: Wed, 9 Apr 2025 17:15:44 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BF=AE=E5=A4=8DSqlServer=E5=88=9D?= =?UTF-8?q?=E5=A7=8B=E5=8C=96=E8=84=9A=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ....Elsa.EntityFrameworkCore.SqlServer.csproj | 10 +- ...pElsaEntityFrameworkCoreSqlServerModule.cs | 9 + .../SqlServer/Migrations/Initial.sql | 432 ++++++++++++++++++ .../SqlServerElsaDataBaseInstaller.cs | 140 ++++++ .../AbpQuartzSqlInstallerModule.cs | 27 +- .../FodyWeavers.xsd | 30 ++ .../SqlServerInstaller/Scripts/Initial.sql | 20 +- .../SqlServerQuartzSqlInstaller.cs | 2 +- 8 files changed, 648 insertions(+), 22 deletions(-) create mode 100644 aspnet-core/modules/elsa/LINGYUN.Abp.Elsa.EntityFrameworkCore.SqlServer/LINGYUN/Abp/Elsa/EntityFrameworkCore/SqlServer/Migrations/Initial.sql create mode 100644 aspnet-core/modules/elsa/LINGYUN.Abp.Elsa.EntityFrameworkCore.SqlServer/LINGYUN/Abp/Elsa/EntityFrameworkCore/SqlServer/Migrations/SqlServerElsaDataBaseInstaller.cs create mode 100644 aspnet-core/modules/task-management/LINGYUN.Abp.Quartz.SqlServerInstaller/FodyWeavers.xsd diff --git a/aspnet-core/modules/elsa/LINGYUN.Abp.Elsa.EntityFrameworkCore.SqlServer/LINGYUN.Abp.Elsa.EntityFrameworkCore.SqlServer.csproj b/aspnet-core/modules/elsa/LINGYUN.Abp.Elsa.EntityFrameworkCore.SqlServer/LINGYUN.Abp.Elsa.EntityFrameworkCore.SqlServer.csproj index 7776abce3..66e74ded7 100644 --- a/aspnet-core/modules/elsa/LINGYUN.Abp.Elsa.EntityFrameworkCore.SqlServer/LINGYUN.Abp.Elsa.EntityFrameworkCore.SqlServer.csproj +++ b/aspnet-core/modules/elsa/LINGYUN.Abp.Elsa.EntityFrameworkCore.SqlServer/LINGYUN.Abp.Elsa.EntityFrameworkCore.SqlServer.csproj @@ -1,4 +1,4 @@ - + @@ -13,6 +13,14 @@ + + + + + + + + diff --git a/aspnet-core/modules/elsa/LINGYUN.Abp.Elsa.EntityFrameworkCore.SqlServer/LINGYUN/Abp/Elsa/EntityFrameworkCore/SqlServer/AbpElsaEntityFrameworkCoreSqlServerModule.cs b/aspnet-core/modules/elsa/LINGYUN.Abp.Elsa.EntityFrameworkCore.SqlServer/LINGYUN/Abp/Elsa/EntityFrameworkCore/SqlServer/AbpElsaEntityFrameworkCoreSqlServerModule.cs index 915ca3c75..3afac3e58 100644 --- a/aspnet-core/modules/elsa/LINGYUN.Abp.Elsa.EntityFrameworkCore.SqlServer/LINGYUN/Abp/Elsa/EntityFrameworkCore/SqlServer/AbpElsaEntityFrameworkCoreSqlServerModule.cs +++ b/aspnet-core/modules/elsa/LINGYUN.Abp.Elsa.EntityFrameworkCore.SqlServer/LINGYUN/Abp/Elsa/EntityFrameworkCore/SqlServer/AbpElsaEntityFrameworkCoreSqlServerModule.cs @@ -3,6 +3,7 @@ using Elsa.Options; using Microsoft.Extensions.DependencyInjection; using Volo.Abp.EntityFrameworkCore.SqlServer; using Volo.Abp.Modularity; +using Volo.Abp.VirtualFileSystem; namespace LINGYUN.Abp.Elsa.EntityFrameworkCore.SqlServer; @@ -26,4 +27,12 @@ public class AbpElsaEntityFrameworkCoreSqlServerModule : 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.SqlServer/LINGYUN/Abp/Elsa/EntityFrameworkCore/SqlServer/Migrations/Initial.sql b/aspnet-core/modules/elsa/LINGYUN.Abp.Elsa.EntityFrameworkCore.SqlServer/LINGYUN/Abp/Elsa/EntityFrameworkCore/SqlServer/Migrations/Initial.sql new file mode 100644 index 000000000..329910788 --- /dev/null +++ b/aspnet-core/modules/elsa/LINGYUN.Abp.Elsa.EntityFrameworkCore.SqlServer/LINGYUN/Abp/Elsa/EntityFrameworkCore/SqlServer/Migrations/Initial.sql @@ -0,0 +1,432 @@ + +USE [${DataBase}]; +-- ---------------------------- +-- Table structure for __EFMigrationsHistory +-- ---------------------------- +IF OBJECT_ID(N'[__EFMigrationsHistory]') IS NULL +BEGIN + CREATE TABLE [__EFMigrationsHistory] ( + [MigrationId] nvarchar(150) NOT NULL, + [ProductVersion] nvarchar(32) NOT NULL, + CONSTRAINT [PK___EFMigrationsHistory] PRIMARY KEY ([MigrationId]) + ); +END; + +-- ---------------------------- +-- Table structure for bookmarks +-- ---------------------------- + +CREATE TABLE [dbo].[Bookmarks] ( + [Id] nvarchar(255) NOT NULL, + [TenantId] nvarchar(255) NULL, + [Hash] nvarchar(255) NOT NULL, + [Model] nvarchar(max) NOT NULL, + [ModelType] nvarchar(max) NOT NULL, + [ActivityType] nvarchar(255) NOT NULL, + [ActivityId] nvarchar(255) NOT NULL, + [WorkflowInstanceId] nvarchar(255) NOT NULL, + [CorrelationId] nvarchar(255) NOT NULL +) + + +-- ---------------------------- +-- Table structure for triggers +-- ---------------------------- + +CREATE TABLE [dbo].[Triggers] ( + [Id] nvarchar(255) NOT NULL, + [TenantId] nvarchar(255) NULL, + [Hash] nvarchar(255) NOT NULL, + [Model] nvarchar(max) NOT NULL, + [ModelType] nvarchar(max) NOT NULL, + [ActivityType] nvarchar(255) NOT NULL, + [ActivityId] nvarchar(255) NOT NULL, + [WorkflowDefinitionId] nvarchar(255) NOT NULL +) + + +-- ---------------------------- +-- Table structure for workflowdefinitions +-- ---------------------------- + +CREATE TABLE [dbo].[WorkflowDefinitions] ( + [Id] nvarchar(255) NOT NULL, + [DefinitionId] nvarchar(255) NOT NULL, + [TenantId] nvarchar(255) NULL, + [Name] nvarchar(255) NULL, + [DisplayName] nvarchar(max) NULL, + [Description] nvarchar(max) NULL, + [Version] int NOT NULL, + [IsSingleton] tinyint NOT NULL, + [PersistenceBehavior] int NOT NULL, + [DeleteCompletedInstances] tinyint NOT NULL, + [IsPublished] tinyint NOT NULL, + [IsLatest] tinyint NOT NULL, + [Tag] nvarchar(255) NULL, + [Data] nvarchar(max) NULL, + [CreatedAt] datetime2 NOT NULL +) + + +-- ---------------------------- +-- Table structure for workflowexecutionlogrecords +-- ---------------------------- + +CREATE TABLE [dbo].[WorkflowExecutionLogRecords] ( + [Id] nvarchar(255) NOT NULL, + [TenantId] nvarchar(255) NULL, + [WorkflowInstanceId] nvarchar(255) NOT NULL, + [ActivityId] nvarchar(255) NOT NULL, + [ActivityType] nvarchar(255) NOT NULL, + [Timestamp] datetime2 NOT NULL, + [EventName] nvarchar(max) NULL, + [Message] nvarchar(max) NULL, + [Source] nvarchar(max) NULL, + [Data] nvarchar(max) NULL +) + + +-- ---------------------------- +-- Table structure for workflowinstances +-- ---------------------------- + +CREATE TABLE [dbo].[WorkflowInstances] ( + [Id] nvarchar(255) NOT NULL, + [DefinitionId] nvarchar(255) NOT NULL, + [TenantId] nvarchar(255) NULL, + [Version] int NOT NULL, + [WorkflowStatus] int NOT NULL, + [CorrelationId] nvarchar(255) NOT NULL, + [ContextType] nvarchar(255) NULL, + [ContextId] nvarchar(255) NULL, + [Name] nvarchar(255) NULL, + [CreatedAt] datetime2 NOT NULL, + [LastExecutedAt] datetime2 NULL, + [FinishedAt] datetime2 NULL, + [CancelledAt] datetime2 NULL, + [FaultedAt] datetime2 NULL, + [Data] nvarchar(max) NULL, + [LastExecutedActivityId] nvarchar(max) NULL, + [DefinitionVersionId] nvarchar(255) NOT NULL +) + + +-- ---------------------------- +-- Table structure for workflowsettings +-- ---------------------------- + +CREATE TABLE [dbo].[WorkflowSettings] ( + [Id] nvarchar(255) NOT NULL, + [WorkflowBlueprintId] nvarchar(255) NULL, + [Key] nvarchar(255) NULL, + [Value] nvarchar(255) NULL +) + + +-- ---------------------------- +-- Indexes structure for table bookmarks +-- ---------------------------- +CREATE NONCLUSTERED INDEX [IX_Bookmark_ActivityId] +ON [dbo].[Bookmarks] ( + [ActivityId] ASC +) + +CREATE NONCLUSTERED INDEX [IX_Bookmark_ActivityType] +ON [dbo].[Bookmarks] ( + [ActivityType] ASC +) + +CREATE NONCLUSTERED INDEX [IX_Bookmark_ActivityType_TenantId_Hash] +ON [dbo].[Bookmarks] ( + [ActivityType] ASC, + [TenantId] ASC, + [Hash] ASC +) + +CREATE NONCLUSTERED INDEX [IX_Bookmark_CorrelationId] +ON [dbo].[Bookmarks] ( + [CorrelationId] ASC +) + +CREATE NONCLUSTERED INDEX [IX_Bookmark_Hash] +ON [dbo].[Bookmarks] ( + [Hash] ASC +) + +CREATE NONCLUSTERED INDEX [IX_Bookmark_Hash_CorrelationId_TenantId] +ON [dbo].[Bookmarks] ( + [Hash] ASC, + [CorrelationId] ASC, + [TenantId] ASC +) + +CREATE NONCLUSTERED INDEX [IX_Bookmark_TenantId] +ON [dbo].[Bookmarks] ( + [TenantId] ASC +) + +CREATE NONCLUSTERED INDEX [IX_Bookmark_WorkflowInstanceId] +ON [dbo].[Bookmarks] ( + [WorkflowInstanceId] ASC +) + + +-- ---------------------------- +-- Primary Key structure for table bookmarks +-- ---------------------------- +ALTER TABLE [dbo].[Bookmarks] ADD PRIMARY KEY CLUSTERED ([Id]) +WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) + + +-- ---------------------------- +-- Indexes structure for table triggers +-- ---------------------------- +CREATE NONCLUSTERED INDEX [IX_Trigger_ActivityId] +ON [dbo].[Triggers] ( + [ActivityId] ASC +) + +CREATE NONCLUSTERED INDEX [IX_Trigger_ActivityType] +ON [dbo].[Triggers] ( + [ActivityType] ASC +) + +CREATE NONCLUSTERED INDEX [IX_Trigger_ActivityType_TenantId_Hash] +ON [dbo].[Triggers] ( + [ActivityType] ASC, + [TenantId] ASC, + [Hash] ASC +) + +CREATE NONCLUSTERED INDEX [IX_Trigger_Hash] +ON [dbo].[Triggers] ( + [Hash] ASC +) + +CREATE NONCLUSTERED INDEX [IX_Trigger_Hash_TenantId] +ON [dbo].[Triggers] ( + [Hash] ASC, + [TenantId] ASC +) + +CREATE NONCLUSTERED INDEX [IX_Trigger_TenantId] +ON [dbo].[Triggers] ( + [TenantId] ASC +) + +CREATE NONCLUSTERED INDEX [IX_Trigger_WorkflowDefinitionId] +ON [dbo].[Triggers] ( + [WorkflowDefinitionId] ASC +) + + +-- ---------------------------- +-- Primary Key structure for table triggers +-- ---------------------------- +ALTER TABLE [dbo].[Triggers] ADD PRIMARY KEY CLUSTERED ([Id]) +WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) + + +-- ---------------------------- +-- Indexes structure for table workflowdefinitions +-- ---------------------------- +CREATE UNIQUE NONCLUSTERED INDEX [IX_WorkflowDefinition_DefinitionId_VersionId] +ON [dbo].[WorkflowDefinitions] ( + [DefinitionId] ASC, + [Version] ASC +) + +CREATE NONCLUSTERED INDEX [IX_WorkflowDefinition_IsLatest] +ON [dbo].[WorkflowDefinitions] ( + [IsLatest] ASC +) + +CREATE NONCLUSTERED INDEX [IX_WorkflowDefinition_IsPublished] +ON [dbo].[WorkflowDefinitions] ( + [IsPublished] ASC +) + +CREATE NONCLUSTERED INDEX [IX_WorkflowDefinition_Name] +ON [dbo].[WorkflowDefinitions] ( + [Name] ASC +) + +CREATE NONCLUSTERED INDEX [IX_WorkflowDefinition_Tag] +ON [dbo].[WorkflowDefinitions] ( + [Tag] ASC +) + +CREATE NONCLUSTERED INDEX [IX_WorkflowDefinition_TenantId] +ON [dbo].[WorkflowDefinitions] ( + [TenantId] ASC +) + +CREATE NONCLUSTERED INDEX [IX_WorkflowDefinition_Version] +ON [dbo].[WorkflowDefinitions] ( + [Version] ASC +) + + +-- ---------------------------- +-- Primary Key structure for table workflowdefinitions +-- ---------------------------- +ALTER TABLE [dbo].[WorkflowDefinitions] ADD PRIMARY KEY CLUSTERED ([Id]) +WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) + + +-- ---------------------------- +-- Indexes structure for table workflowexecutionlogrecords +-- ---------------------------- +CREATE NONCLUSTERED INDEX [IX_WorkflowExecutionLogRecord_ActivityId] +ON [dbo].[WorkflowExecutionLogRecords] ( + [ActivityId] ASC +) + +CREATE NONCLUSTERED INDEX [IX_WorkflowExecutionLogRecord_ActivityType] +ON [dbo].[WorkflowExecutionLogRecords] ( + [ActivityType] ASC +) + +CREATE NONCLUSTERED INDEX [IX_WorkflowExecutionLogRecord_TenantId] +ON [dbo].[WorkflowExecutionLogRecords] ( + [TenantId] ASC +) + +CREATE NONCLUSTERED INDEX [IX_WorkflowExecutionLogRecord_Timestamp] +ON [dbo].[WorkflowExecutionLogRecords] ( + [Timestamp] ASC +) + +CREATE NONCLUSTERED INDEX [IX_WorkflowExecutionLogRecord_WorkflowInstanceId] +ON [dbo].[WorkflowExecutionLogRecords] ( + [WorkflowInstanceId] ASC +) + + +-- ---------------------------- +-- Primary Key structure for table workflowexecutionlogrecords +-- ---------------------------- +ALTER TABLE [dbo].[WorkflowExecutionLogRecords] ADD PRIMARY KEY CLUSTERED ([Id]) +WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) + + +-- ---------------------------- +-- Indexes structure for table workflowinstances +-- ---------------------------- +CREATE NONCLUSTERED INDEX [IX_WorkflowInstance_ContextId] +ON [dbo].[WorkflowInstances] ( + [ContextId] ASC +) + +CREATE NONCLUSTERED INDEX [IX_WorkflowInstance_ContextType] +ON [dbo].[WorkflowInstances] ( + [ContextType] ASC +) + +CREATE NONCLUSTERED INDEX [IX_WorkflowInstance_CorrelationId] +ON [dbo].[WorkflowInstances] ( + [CorrelationId] ASC +) + +CREATE NONCLUSTERED INDEX [IX_WorkflowInstance_CreatedAt] +ON [dbo].[WorkflowInstances] ( + [CreatedAt] ASC +) + +CREATE NONCLUSTERED INDEX [IX_WorkflowInstance_DefinitionId] +ON [dbo].[WorkflowInstances] ( + [DefinitionId] ASC +) + +CREATE NONCLUSTERED INDEX [IX_WorkflowInstance_FaultedAt] +ON [dbo].[WorkflowInstances] ( + [FaultedAt] ASC +) + +CREATE NONCLUSTERED INDEX [IX_WorkflowInstance_FinishedAt] +ON [dbo].[WorkflowInstances] ( + [FinishedAt] ASC +) + +CREATE NONCLUSTERED INDEX [IX_WorkflowInstance_LastExecutedAt] +ON [dbo].[WorkflowInstances] ( + [LastExecutedAt] ASC +) + +CREATE NONCLUSTERED INDEX [IX_WorkflowInstance_Name] +ON [dbo].[WorkflowInstances] ( + [Name] ASC +) + +CREATE NONCLUSTERED INDEX [IX_WorkflowInstance_TenantId] +ON [dbo].[WorkflowInstances] ( + [TenantId] ASC +) + +CREATE NONCLUSTERED INDEX [IX_WorkflowInstance_WorkflowStatus] +ON [dbo].[WorkflowInstances] ( + [WorkflowStatus] ASC +) + +CREATE NONCLUSTERED INDEX [IX_WorkflowInstance_WorkflowStatus_DefinitionId] +ON [dbo].[WorkflowInstances] ( + [WorkflowStatus] ASC, + [DefinitionId] ASC +) + +CREATE NONCLUSTERED INDEX [IX_WorkflowInstance_WorkflowStatus_DefinitionId_Version] +ON [dbo].[WorkflowInstances] ( + [WorkflowStatus] ASC, + [DefinitionId] ASC, + [Version] ASC +) + +CREATE NONCLUSTERED INDEX [IX_WorkflowInstance_DefinitionVersionId] +ON [dbo].[WorkflowInstances] ( + [DefinitionVersionId] ASC +) + + +-- ---------------------------- +-- Primary Key structure for table workflowinstances +-- ---------------------------- +ALTER TABLE [dbo].[WorkflowInstances] ADD PRIMARY KEY CLUSTERED ([Id]) +WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) + + +-- ---------------------------- +-- Indexes structure for table workflowsettings +-- ---------------------------- +CREATE NONCLUSTERED INDEX [IX_WorkflowSetting_Key] +ON [dbo].[WorkflowSettings] ( + [Key] ASC +) + +CREATE NONCLUSTERED INDEX [IX_WorkflowSetting_Value] +ON [dbo].[WorkflowSettings] ( + [Value] ASC +) + +CREATE NONCLUSTERED INDEX [IX_WorkflowSetting_WorkflowBlueprintId] +ON [dbo].[WorkflowSettings] ( + [WorkflowBlueprintId] ASC +) + + +-- ---------------------------- +-- Primary Key structure for table workflowsettings +-- ---------------------------- +ALTER TABLE [dbo].[WorkflowSettings] ADD PRIMARY KEY CLUSTERED ([Id]) +WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) + +INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion]) +VALUES +(N'20210523093427_Initial', '5.0.10'), +(N'20210611200027_Update21', '5.0.10'), +(N'20210923112211_Update23', '5.0.10'), +(N'20211215100204_Update24', '5.0.10'), +(N'20220120170050_Update241', '5.0.10'), +(N'20220120204150_Update25', '5.0.10'), +(N'20220512203646_Update28', '5.0.10'), +(N'20210604065041_Initial', '5.0.10'), +(N'20210730112043_Initial', '5.0.10'); diff --git a/aspnet-core/modules/elsa/LINGYUN.Abp.Elsa.EntityFrameworkCore.SqlServer/LINGYUN/Abp/Elsa/EntityFrameworkCore/SqlServer/Migrations/SqlServerElsaDataBaseInstaller.cs b/aspnet-core/modules/elsa/LINGYUN.Abp.Elsa.EntityFrameworkCore.SqlServer/LINGYUN/Abp/Elsa/EntityFrameworkCore/SqlServer/Migrations/SqlServerElsaDataBaseInstaller.cs new file mode 100644 index 000000000..9f2f047de --- /dev/null +++ b/aspnet-core/modules/elsa/LINGYUN.Abp.Elsa.EntityFrameworkCore.SqlServer/LINGYUN/Abp/Elsa/EntityFrameworkCore/SqlServer/Migrations/SqlServerElsaDataBaseInstaller.cs @@ -0,0 +1,140 @@ +using LINGYUN.Abp.Elsa.EntityFrameworkCore.Migrations; +using Microsoft.Data.SqlClient; +using Microsoft.Extensions.FileProviders; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; +using Microsoft.Extensions.Options; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Threading.Tasks; +using Volo.Abp.Data; +using Volo.Abp.DependencyInjection; +using Volo.Abp.VirtualFileSystem; + +namespace LINGYUN.Abp.Elsa.EntityFrameworkCore.SqlServer.Migrations; + +public class SqlServerElsaDataBaseInstaller : IElsaDataBaseInstaller, ITransientDependency +{ + public ILogger Logger { protected get; set; } + + private readonly IVirtualFileProvider _virtualFileProvider; + private readonly IConnectionStringResolver _connectionStringResolver; + + private readonly AbpElsaDataBaseInstallerOptions _installerOptions; + + public SqlServerElsaDataBaseInstaller( + IVirtualFileProvider virtualFileProvider, + IConnectionStringResolver connectionStringResolver, + IOptions installerOptions) + { + _installerOptions = installerOptions.Value; + _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 SqlConnectionStringBuilder(connectionString); + + var dataBaseName = await CreateDataBaseIfNotExists(builder.InitialCatalog, builder); + + builder.InitialCatalog = dataBaseName; + + using var sqlConnection = new SqlConnection(builder.ConnectionString); + + if (sqlConnection.State == ConnectionState.Closed) + { + await sqlConnection.OpenAsync(); + } + + var tableParams = _installerOptions.InstallTables.Select((_, index) => $"@Table_{index}").JoinAsString(","); + using (var sqlCommand = new SqlCommand($"SELECT COUNT(1) FROM [sys].[objects] WHERE type=N'U' AND name IN ({tableParams});", sqlConnection)) + { + sqlCommand.Parameters.Add("@DataBaseName", SqlDbType.NVarChar).Value = dataBaseName; + for (var index = 0; index < _installerOptions.InstallTables.Count; index++) + { + sqlCommand.Parameters.Add($"@Table_{index}", SqlDbType.NVarChar).Value = _installerOptions.InstallTables[index]; + } + + var rowsAffects = await sqlCommand.ExecuteScalarAsync() as int?; + if (rowsAffects > 0) + { + Logger.LogInformation($"The `{dataBaseName}` tables has already exists."); + return; + } + } + + var sqlScript = await GetInitSqlScript(); + + // USE `${DataBase}` -> USE `Workflow`;; + sqlScript = sqlScript.ReplaceFirst("${DataBase}", dataBaseName); + + using (var sqlCommand = new SqlCommand(sqlScript, sqlConnection)) + { + Logger.LogInformation("The database initialization script `Initial.sql` starts..."); + await sqlCommand.ExecuteNonQueryAsync(); + } + + Logger.LogInformation("Database initialization script `Initial.sql` complete!"); + } + + public async virtual Task CreateDataBaseIfNotExists(string dataBase, SqlConnectionStringBuilder connectionStringBuilder) + { + // 切换主数据库查询数据库是否存在 + connectionStringBuilder.InitialCatalog = "master"; + using var sqlConnection = new SqlConnection(connectionStringBuilder.ConnectionString); + if (sqlConnection.State == ConnectionState.Closed) + { + await sqlConnection.OpenAsync(); + } + + var checkDataBaseName = ""; + using (var sqlCommand = new SqlCommand("SELECT [name] FROM [master].[dbo].[sysdatabases] WHERE [name] = @DataBaseName;", sqlConnection)) + { + var dataBaseParamter = sqlCommand.Parameters.Add("DataBaseName", SqlDbType.NVarChar); + dataBaseParamter.Value = dataBase; + + checkDataBaseName = await sqlCommand.ExecuteScalarAsync() as string; + } + + if (checkDataBaseName.IsNullOrWhiteSpace()) + { + using (var sqlCommand = new SqlCommand($"CREATE DATABASE {dataBase};", sqlConnection)) + { + await sqlCommand.ExecuteNonQueryAsync(); + } + } + + return dataBase; + } + + public async virtual Task GetInitSqlScript() + { + var sqlScriptFileInfo = _virtualFileProvider.GetFileInfo("/LINGYUN/Abp/Elsa/EntityFrameworkCore/SqlServer/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/task-management/LINGYUN.Abp.Quartz.SqlInstaller/LINGYUN/Abp/Quartz/SqlInstaller/AbpQuartzSqlInstallerModule.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.Quartz.SqlInstaller/LINGYUN/Abp/Quartz/SqlInstaller/AbpQuartzSqlInstallerModule.cs index 75dc7ca18..a58056d1e 100644 --- a/aspnet-core/modules/task-management/LINGYUN.Abp.Quartz.SqlInstaller/LINGYUN/Abp/Quartz/SqlInstaller/AbpQuartzSqlInstallerModule.cs +++ b/aspnet-core/modules/task-management/LINGYUN.Abp.Quartz.SqlInstaller/LINGYUN/Abp/Quartz/SqlInstaller/AbpQuartzSqlInstallerModule.cs @@ -1,5 +1,9 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; +using Quartz; +using Quartz.Impl; +using Quartz.Simpl; +using Quartz.Util; using System.Threading.Tasks; using Volo.Abp; using Volo.Abp.Modularity; @@ -10,10 +14,31 @@ namespace LINGYUN.Abp.Quartz.SqlInstaller; [DependsOn(typeof(AbpQuartzModule))] public class AbpQuartzSqlInstallerModule : AbpModule { + public override void ConfigureServices(ServiceConfigurationContext context) + { + var abpQuartzOptions = context.Services.ExecutePreConfiguredActions(); + Configure(options => + { + foreach (var settingKey in abpQuartzOptions.Properties.AllKeys) + { + options[settingKey] = abpQuartzOptions.Properties[settingKey]; + } + + if (abpQuartzOptions.Properties[StdSchedulerFactory.PropertyJobStoreType] == null) + { + var defaultJobStoreType = typeof(RAMJobStore).AssemblyQualifiedNameWithoutVersion(); + + options[StdSchedulerFactory.PropertyJobStoreType] = defaultJobStoreType; + abpQuartzOptions.Properties[StdSchedulerFactory.PropertyJobStoreType] = defaultJobStoreType; + } + }); + } + public async override Task OnPreApplicationInitializationAsync(ApplicationInitializationContext context) { var configuration = context.ServiceProvider.GetRequiredService(); - if (configuration.GetValue("Quartz:UsePersistentStore", false)) + if (configuration.GetValue("Quartz:UsePersistentStore", false) && + !configuration[StdSchedulerFactory.PropertyJobStoreType].IsNullOrWhiteSpace()) { // 初始化 Quartz 数据库 await context.ServiceProvider diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.Quartz.SqlServerInstaller/FodyWeavers.xsd b/aspnet-core/modules/task-management/LINGYUN.Abp.Quartz.SqlServerInstaller/FodyWeavers.xsd new file mode 100644 index 000000000..3f3946e28 --- /dev/null +++ b/aspnet-core/modules/task-management/LINGYUN.Abp.Quartz.SqlServerInstaller/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.Quartz.SqlServerInstaller/LINGYUN/Abp/Quartz/SqlServerInstaller/Scripts/Initial.sql b/aspnet-core/modules/task-management/LINGYUN.Abp.Quartz.SqlServerInstaller/LINGYUN/Abp/Quartz/SqlServerInstaller/Scripts/Initial.sql index d95fa9574..97442ae5d 100644 --- a/aspnet-core/modules/task-management/LINGYUN.Abp.Quartz.SqlServerInstaller/LINGYUN/Abp/Quartz/SqlServerInstaller/Scripts/Initial.sql +++ b/aspnet-core/modules/task-management/LINGYUN.Abp.Quartz.SqlServerInstaller/LINGYUN/Abp/Quartz/SqlServerInstaller/Scripts/Initial.sql @@ -5,7 +5,6 @@ -- Should you only require it to create the tables, set @DropDb to 0. USE [${DataBase}]; -GO DECLARE @DropDb BIT = 1; -- Set this to 0 to skip DROP statements, 1 to include them @@ -204,7 +203,6 @@ CREATE TABLE [dbo].[${TablePrefix}TRIGGERS] ( [MISFIRE_INSTR] int NULL, [JOB_DATA] varbinary(max) NULL ); -GO ALTER TABLE [dbo].[${TablePrefix}CALENDARS] WITH NOCHECK ADD CONSTRAINT [PK_${TablePrefix}CALENDARS] PRIMARY KEY CLUSTERED @@ -212,7 +210,6 @@ ALTER TABLE [dbo].[${TablePrefix}CALENDARS] WITH NOCHECK ADD [SCHED_NAME], [CALENDAR_NAME] ); -GO ALTER TABLE [dbo].[${TablePrefix}CRON_TRIGGERS] WITH NOCHECK ADD CONSTRAINT [PK_${TablePrefix}CRON_TRIGGERS] PRIMARY KEY CLUSTERED @@ -221,7 +218,6 @@ ALTER TABLE [dbo].[${TablePrefix}CRON_TRIGGERS] WITH NOCHECK ADD [TRIGGER_NAME], [TRIGGER_GROUP] ); -GO ALTER TABLE [dbo].[${TablePrefix}FIRED_TRIGGERS] WITH NOCHECK ADD CONSTRAINT [PK_${TablePrefix}FIRED_TRIGGERS] PRIMARY KEY CLUSTERED @@ -229,7 +225,6 @@ ALTER TABLE [dbo].[${TablePrefix}FIRED_TRIGGERS] WITH NOCHECK ADD [SCHED_NAME], [ENTRY_ID] ); -GO ALTER TABLE [dbo].[${TablePrefix}PAUSED_TRIGGER_GRPS] WITH NOCHECK ADD CONSTRAINT [PK_${TablePrefix}PAUSED_TRIGGER_GRPS] PRIMARY KEY CLUSTERED @@ -237,7 +232,6 @@ ALTER TABLE [dbo].[${TablePrefix}PAUSED_TRIGGER_GRPS] WITH NOCHECK ADD [SCHED_NAME], [TRIGGER_GROUP] ); -GO ALTER TABLE [dbo].[${TablePrefix}SCHEDULER_STATE] WITH NOCHECK ADD CONSTRAINT [PK_${TablePrefix}SCHEDULER_STATE] PRIMARY KEY CLUSTERED @@ -245,7 +239,6 @@ ALTER TABLE [dbo].[${TablePrefix}SCHEDULER_STATE] WITH NOCHECK ADD [SCHED_NAME], [INSTANCE_NAME] ); -GO ALTER TABLE [dbo].[${TablePrefix}LOCKS] WITH NOCHECK ADD CONSTRAINT [PK_${TablePrefix}LOCKS] PRIMARY KEY CLUSTERED @@ -253,7 +246,6 @@ ALTER TABLE [dbo].[${TablePrefix}LOCKS] WITH NOCHECK ADD [SCHED_NAME], [LOCK_NAME] ); -GO ALTER TABLE [dbo].[${TablePrefix}JOB_DETAILS] WITH NOCHECK ADD CONSTRAINT [PK_${TablePrefix}JOB_DETAILS] PRIMARY KEY CLUSTERED @@ -262,7 +254,6 @@ ALTER TABLE [dbo].[${TablePrefix}JOB_DETAILS] WITH NOCHECK ADD [JOB_NAME], [JOB_GROUP] ); -GO ALTER TABLE [dbo].[${TablePrefix}SIMPLE_TRIGGERS] WITH NOCHECK ADD CONSTRAINT [PK_${TablePrefix}SIMPLE_TRIGGERS] PRIMARY KEY CLUSTERED @@ -271,7 +262,6 @@ ALTER TABLE [dbo].[${TablePrefix}SIMPLE_TRIGGERS] WITH NOCHECK ADD [TRIGGER_NAME], [TRIGGER_GROUP] ); -GO ALTER TABLE [dbo].[${TablePrefix}SIMPROP_TRIGGERS] WITH NOCHECK ADD CONSTRAINT [PK_${TablePrefix}SIMPROP_TRIGGERS] PRIMARY KEY CLUSTERED @@ -280,7 +270,6 @@ ALTER TABLE [dbo].[${TablePrefix}SIMPROP_TRIGGERS] WITH NOCHECK ADD [TRIGGER_NAME], [TRIGGER_GROUP] ); -GO ALTER TABLE [dbo].[${TablePrefix}TRIGGERS] WITH NOCHECK ADD CONSTRAINT [PK_${TablePrefix}TRIGGERS] PRIMARY KEY CLUSTERED @@ -289,7 +278,6 @@ ALTER TABLE [dbo].[${TablePrefix}TRIGGERS] WITH NOCHECK ADD [TRIGGER_NAME], [TRIGGER_GROUP] ); -GO ALTER TABLE [dbo].[${TablePrefix}BLOB_TRIGGERS] WITH NOCHECK ADD CONSTRAINT [PK_${TablePrefix}BLOB_TRIGGERS] PRIMARY KEY CLUSTERED @@ -298,7 +286,6 @@ ALTER TABLE [dbo].[${TablePrefix}BLOB_TRIGGERS] WITH NOCHECK ADD [TRIGGER_NAME], [TRIGGER_GROUP] ); -GO ALTER TABLE [dbo].[${TablePrefix}CRON_TRIGGERS] ADD CONSTRAINT [FK_${TablePrefix}CRON_TRIGGERS_${TablePrefix}TRIGGERS] FOREIGN KEY @@ -311,7 +298,6 @@ ALTER TABLE [dbo].[${TablePrefix}CRON_TRIGGERS] ADD [TRIGGER_NAME], [TRIGGER_GROUP] ) ON DELETE CASCADE; -GO ALTER TABLE [dbo].[${TablePrefix}SIMPLE_TRIGGERS] ADD CONSTRAINT [FK_${TablePrefix}SIMPLE_TRIGGERS_${TablePrefix}TRIGGERS] FOREIGN KEY @@ -324,7 +310,6 @@ ALTER TABLE [dbo].[${TablePrefix}SIMPLE_TRIGGERS] ADD [TRIGGER_NAME], [TRIGGER_GROUP] ) ON DELETE CASCADE; -GO ALTER TABLE [dbo].[${TablePrefix}SIMPROP_TRIGGERS] ADD CONSTRAINT [FK_${TablePrefix}SIMPROP_TRIGGERS_${TablePrefix}TRIGGERS] FOREIGN KEY @@ -337,7 +322,6 @@ ALTER TABLE [dbo].[${TablePrefix}SIMPROP_TRIGGERS] ADD [TRIGGER_NAME], [TRIGGER_GROUP] ) ON DELETE CASCADE; -GO ALTER TABLE [dbo].[${TablePrefix}TRIGGERS] ADD CONSTRAINT [FK_${TablePrefix}TRIGGERS_${TablePrefix}JOB_DETAILS] FOREIGN KEY @@ -350,7 +334,6 @@ ALTER TABLE [dbo].[${TablePrefix}TRIGGERS] ADD [JOB_NAME], [JOB_GROUP] ); -GO -- Create indexes CREATE INDEX [IDX_${TablePrefix}T_G_J] ON [dbo].[${TablePrefix}TRIGGERS](SCHED_NAME, JOB_GROUP, JOB_NAME); @@ -366,5 +349,4 @@ CREATE INDEX [IDX_${TablePrefix}T_NFT_ST_MISFIRE_GRP] ON [dbo].[${TablePrefix}T CREATE INDEX [IDX_${TablePrefix}FT_INST_JOB_REQ_RCVRY] ON [dbo].[${TablePrefix}FIRED_TRIGGERS](SCHED_NAME, INSTANCE_NAME, REQUESTS_RECOVERY); CREATE INDEX [IDX_${TablePrefix}FT_G_J] ON [dbo].[${TablePrefix}FIRED_TRIGGERS](SCHED_NAME, JOB_GROUP, JOB_NAME); -CREATE INDEX [IDX_${TablePrefix}FT_G_T] ON [dbo].[${TablePrefix}FIRED_TRIGGERS](SCHED_NAME, TRIGGER_GROUP, TRIGGER_NAME); -GO \ No newline at end of file +CREATE INDEX [IDX_${TablePrefix}FT_G_T] ON [dbo].[${TablePrefix}FIRED_TRIGGERS](SCHED_NAME, TRIGGER_GROUP, TRIGGER_NAME); \ No newline at end of file diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.Quartz.SqlServerInstaller/LINGYUN/Abp/Quartz/SqlServerInstaller/SqlServerQuartzSqlInstaller.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.Quartz.SqlServerInstaller/LINGYUN/Abp/Quartz/SqlServerInstaller/SqlServerQuartzSqlInstaller.cs index cc1d54703..3d8a7858f 100644 --- a/aspnet-core/modules/task-management/LINGYUN.Abp.Quartz.SqlServerInstaller/LINGYUN/Abp/Quartz/SqlServerInstaller/SqlServerQuartzSqlInstaller.cs +++ b/aspnet-core/modules/task-management/LINGYUN.Abp.Quartz.SqlServerInstaller/LINGYUN/Abp/Quartz/SqlServerInstaller/SqlServerQuartzSqlInstaller.cs @@ -73,7 +73,7 @@ public class SqlServerQuartzSqlInstaller : IQuartzSqlInstaller, ITransientDepend sqlCommand.Parameters.Add($"@Table_{index}", SqlDbType.NVarChar).Value = $"{tablePrefix}{_installerOptions.InstallTables[index]}"; } - var rowsAffects = await sqlCommand.ExecuteScalarAsync() as long?; + var rowsAffects = await sqlCommand.ExecuteScalarAsync() as int?; if (rowsAffects > 0) { Logger.LogInformation($"The `{dataBaseName}` tables has already exists.");