Adds SQL Activities. Includes implimentations for MS SQL Server, PostgreSql, MySql and Sqlite.

This commit is contained in:
Matthew Knibbs 2025-01-01 23:14:09 +00:00
parent f609013a79
commit c4e04c4434
31 changed files with 1084 additions and 187 deletions

View file

@ -1,152 +1,154 @@
<Project>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
<CentralPackageTransitivePinningEnabled>true</CentralPackageTransitivePinningEnabled>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="Antlr4.Runtime.Standard" Version="4.13.1"/>
<PackageVersion Include="AppAny.Quartz.EntityFrameworkCore.Migrations" Version="0.5.1"/>
<PackageVersion Include="AppAny.Quartz.EntityFrameworkCore.Migrations.MySql" Version="0.5.1"/>
<PackageVersion Include="AppAny.Quartz.EntityFrameworkCore.Migrations.PostgreSQL" Version="0.5.1"/>
<PackageVersion Include="AppAny.Quartz.EntityFrameworkCore.Migrations.SQLite" Version="0.5.1"/>
<PackageVersion Include="AppAny.Quartz.EntityFrameworkCore.Migrations.SqlServer" Version="0.5.1"/>
<PackageVersion Include="AutoMapper" Version="13.0.1" PrivateAssets="All"/>
<PackageVersion Include="Azure.Identity" Version="1.13.1"/>
<PackageVersion Include="Azure.Messaging.ServiceBus" Version="7.18.2"/>
<PackageVersion Include="Azure.ResourceManager" Version="1.13.0"/>
<PackageVersion Include="Azure.ResourceManager.AppContainers" Version="1.3.0"/>
<PackageVersion Include="Azure.ResourceManager.Resources" Version="1.9.0"/>
<PackageVersion Include="Azure.ResourceManager.ServiceBus" Version="1.1.0"/>
<PackageVersion Include="BenchmarkDotNet" Version="0.14.0"/>
<PackageVersion Include="Bogus" Version="35.6.1"/>
<PackageVersion Include="ConfigureAwait.Fody" Version="3.3.2" PrivateAssets="All"/>
<PackageVersion Include="Confluent.Kafka" Version="2.6.1"/>
<PackageVersion Include="Confluent.SchemaRegistry.Serdes.Avro" Version="2.6.1"/>
<PackageVersion Include="coverlet.collector" Version="6.0.2" PrivateAssets="All"/>
<PackageVersion Include="Cronos" Version="0.9.0"/>
<PackageVersion Include="Dapper" Version="2.1.35"/>
<PackageVersion Include="DistributedLock.Core" Version="1.0.8"/>
<PackageVersion Include="DistributedLock.FileSystem" Version="1.0.3"/>
<PackageVersion Include="DistributedLock.Postgres" Version="1.2.1"/>
<PackageVersion Include="DistributedLock.Redis" Version="1.0.3"/>
<PackageVersion Include="Elastic.Clients.Elasticsearch" Version="8.16.3"/>
<PackageVersion Include="Elsa.Studio" Version="3.3.0-rc4"/>
<PackageVersion Include="Elsa.Studio.Agents" Version="3.3.0-rc4"/>
<PackageVersion Include="Elsa.Studio.Core.BlazorWasm" Version="3.3.0-rc4"/>
<PackageVersion Include="Elsa.Studio.Login.BlazorWasm" Version="3.3.0-rc4"/>
<PackageVersion Include="FastEndpoints" Version="5.32.0"/>
<PackageVersion Include="FastEndpoints.Security" Version="5.32.0"/>
<PackageVersion Include="FastEndpoints.Swagger" Version="5.32.0"/>
<PackageVersion Include="FluentMigrator" Version="6.2.0"/>
<PackageVersion Include="FluentMigrator.Runner" Version="6.2.0"/>
<PackageVersion Include="FluentStorage" Version="5.6.0"/>
<PackageVersion Include="FluentStorage.Azure.Blobs" Version="5.3.0"/>
<PackageVersion Include="Fluid.Core" Version="2.16.0"/>
<PackageVersion Include="Fody" Version="6.9.1"/>
<PackageVersion Include="GitHubActionsTestLogger" Version="2.4.1"/>
<PackageVersion Include="Google.Protobuf" Version="3.29.2"/>
<PackageVersion Include="Grpc.Net.Client" Version="2.67.0"/>
<PackageVersion Include="Grpc.Tools" Version="2.68.1"/>
<PackageVersion Include="Hangfire" Version="1.8.17"/>
<PackageVersion Include="Hangfire.MemoryStorage" Version="1.8.1.1"/>
<PackageVersion Include="Hangfire.Storage.SQLite" Version="0.4.2"/>
<PackageVersion Include="Humanizer.Core" Version="2.14.1"/>
<PackageVersion Include="IronCompress" Version="1.6.3"/>
<PackageVersion Include="JetBrains.Annotations" Version="2024.3.0"/>
<PackageVersion Include="Jint" Version="4.1.0"/>
<PackageVersion Include="LinqKit.Core" Version="1.2.7"/>
<PackageVersion Include="MailKit" Version="4.9.0"/>
<PackageVersion Include="MassTransit" Version="8.3.4"/>
<PackageVersion Include="MassTransit.Azure.ServiceBus.Core" Version="8.3.4"/>
<PackageVersion Include="MassTransit.RabbitMQ" Version="8.3.4"/>
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp.Scripting" Version="4.12.0"/>
<PackageVersion Include="Microsoft.Identity.Client" Version="4.66.2"/>
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.12.0"/>
<PackageVersion Include="Microsoft.SemanticKernel" Version="1.32.0"/>
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="8.0.0"/>
<PackageVersion Include="MongoDB.Driver" Version="3.1.0"/>
<PackageVersion Include="MongoDB.Driver.Core.Extensions.DiagnosticSources" Version="2.0.0"/>
<PackageVersion Include="MongoDB.Driver.Extensions" Version="2.0.2"/>
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3"/>
<PackageVersion Include="NSubstitute" Version="5.3.0"/>
<PackageVersion Include="NuGet.Packaging" Version="6.12.1"/>
<PackageVersion Include="NuGet.Protocol" Version="6.12.1"/>
<PackageVersion Include="Nuke.Components" Version="9.0.3"/>
<PackageVersion Include="Open.Linq.AsyncExtensions" Version="1.2.0"/>
<PackageVersion Include="Polly.Extensions.Http" Version="3.0.0"/>
<PackageVersion Include="PolySharp" Version="1.15.0"/>
<PackageVersion Include="Proto.Actor" Version="1.7.0"/>
<PackageVersion Include="Proto.Cluster" Version="1.7.0"/>
<PackageVersion Include="Proto.Cluster.AzureContainerApps" Version="1.7.0"/>
<PackageVersion Include="Proto.Cluster.CodeGen" Version="1.7.0"/>
<PackageVersion Include="Proto.Cluster.Kubernetes" Version="1.7.0"/>
<PackageVersion Include="Proto.Cluster.TestProvider" Version="1.7.0"/>
<PackageVersion Include="Proto.OpenTelemetry" Version="1.7.0"/>
<PackageVersion Include="Proto.Persistence" Version="1.7.0"/>
<PackageVersion Include="Proto.Persistence.Sqlite" Version="1.7.0"/>
<PackageVersion Include="Proto.Persistence.SqlServer" Version="1.7.0"/>
<PackageVersion Include="Proto.Remote" Version="1.7.0"/>
<PackageVersion Include="pythonnet" Version="3.0.5"/>
<PackageVersion Include="Quartz.Extensions.Hosting" Version="3.13.1"/>
<PackageVersion Include="Quartz.Serialization.Json" Version="3.13.1"/>
<PackageVersion Include="Scrutor" Version="5.0.2"/>
<PackageVersion Include="ShortGuid" Version="2.0.1"/>
<PackageVersion Include="StackExchange.Redis" Version="2.8.24"/>
<PackageVersion Include="System.CommandLine" Version="2.0.0-beta4.22272.1"/>
<PackageVersion Include="System.Data.SqlClient" Version="4.9.0"/>
<PackageVersion Include="System.Linq.Async" Version="6.0.1"/>
<PackageVersion Include="System.Linq.Dynamic.Core" Version="1.5.1"/>
<PackageVersion Include="System.Net.Http" Version="4.3.4"/>
<PackageVersion Include="System.Text.RegularExpressions" Version="4.3.1"/>
<PackageVersion Include="Testcontainers" Version="4.1.0"/>
<PackageVersion Include="Testcontainers.PostgreSql" Version="4.1.0"/>
<PackageVersion Include="Testcontainers.RabbitMq" Version="4.1.0"/>
<PackageVersion Include="Testcontainers.Redis" Version="4.1.0"/>
<PackageVersion Include="ThrottleDebounce" Version="2.0.0"/>
<PackageVersion Include="WebhooksCore" Version="0.0.1"/>
<PackageVersion Include="xunit" Version="2.9.2"/>
<PackageVersion Include="xunit.abstractions" Version="2.0.3"/>
<PackageVersion Include="xunit.extensibility.core" Version="2.9.2"/>
<PackageVersion Include="xunit.runner.visualstudio" Version="3.0.0"/>
<PackageVersion Include="Yarp.ReverseProxy" Version="2.2.0"/>
<PackageVersion Include="AspNetCore.Authentication.ApiKey" Version="8.0.1"/>
<PackageVersion Include="Microsoft.AspNetCore.Authorization" Version="9.0.0"/>
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly" Version="9.0.0"/>
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="9.0.0"/>
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="9.0.0"/>
<PackageVersion Include="Microsoft.AspNetCore.DataProtection.Abstractions" Version="9.0.0"/>
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Testing" Version="9.0.0"/>
<PackageVersion Include="Microsoft.Data.Sqlite" Version="9.0.0"/>
<PackageVersion Include="Microsoft.Data.Sqlite.Core" Version="9.0.0"/>
<PackageVersion Include="Microsoft.EntityFrameworkCore" Version="9.0.0"/>
<PackageVersion Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.0"/>
<PackageVersion Include="Microsoft.EntityFrameworkCore.Relational" Version="9.0.0"/>
<PackageVersion Include="Microsoft.EntityFrameworkCore.Sqlite" Version="9.0.0"/>
<PackageVersion Include="Microsoft.EntityFrameworkCore.SqlServer" Version="9.0.0"/>
<PackageVersion Include="Microsoft.Extensions.Caching.Abstractions" Version="9.0.0"/>
<PackageVersion Include="Microsoft.Extensions.Caching.Memory" Version="9.0.0"/>
<PackageVersion Include="Microsoft.Extensions.Configuration" Version="9.0.0"/>
<PackageVersion Include="Microsoft.Extensions.Configuration.Abstractions" Version="9.0.0"/>
<PackageVersion Include="Microsoft.Extensions.Configuration.Json" Version="9.0.0"/>
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="9.0.0"/>
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="9.0.0"/>
<PackageVersion Include="Microsoft.Extensions.DependencyModel" Version="9.0.0"/>
<PackageVersion Include="Microsoft.Extensions.Hosting.Abstractions" Version="9.0.0"/>
<PackageVersion Include="Microsoft.Extensions.Http" Version="9.0.0"/>
<PackageVersion Include="Microsoft.Extensions.Http.Polly" Version="9.0.0"/>
<PackageVersion Include="Microsoft.Extensions.Logging" Version="9.0.0"/>
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="9.0.0"/>
<PackageVersion Include="Microsoft.Extensions.Logging.Console" Version="9.0.0"/>
<PackageVersion Include="Microsoft.Extensions.Options" Version="9.0.0"/>
<PackageVersion Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="9.0.0"/>
<PackageVersion Include="Npgsql" Version="9.0.2"/>
<PackageVersion Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="9.0.2"/>
<PackageVersion Include="Oracle.EntityFrameworkCore" Version="9.23.60"/>
<PackageVersion Include="Polly" Version="8.5.0"/>
<PackageVersion Include="Pomelo.EntityFrameworkCore.MySql" Version="9.0.0-preview.2.efcore.9.0.0"/>
<PackageVersion Include="Refit" Version="8.0.0"/>
<PackageVersion Include="Refit.HttpClientFactory" Version="8.0.0"/>
<PackageVersion Include="System.Formats.Asn1" Version="9.0.0"/>
<PackageVersion Include="System.Text.Json" Version="9.0.0"/>
</ItemGroup>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
<CentralPackageTransitivePinningEnabled>true</CentralPackageTransitivePinningEnabled>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="Antlr4.Runtime.Standard" Version="4.13.1" />
<PackageVersion Include="AppAny.Quartz.EntityFrameworkCore.Migrations" Version="0.5.1" />
<PackageVersion Include="AppAny.Quartz.EntityFrameworkCore.Migrations.MySql" Version="0.5.1" />
<PackageVersion Include="AppAny.Quartz.EntityFrameworkCore.Migrations.PostgreSQL" Version="0.5.1" />
<PackageVersion Include="AppAny.Quartz.EntityFrameworkCore.Migrations.SQLite" Version="0.5.1" />
<PackageVersion Include="AppAny.Quartz.EntityFrameworkCore.Migrations.SqlServer" Version="0.5.1" />
<PackageVersion Include="AutoMapper" Version="13.0.1" PrivateAssets="All" />
<PackageVersion Include="Azure.Identity" Version="1.13.1" />
<PackageVersion Include="Azure.Messaging.ServiceBus" Version="7.18.2" />
<PackageVersion Include="Azure.ResourceManager" Version="1.13.0" />
<PackageVersion Include="Azure.ResourceManager.AppContainers" Version="1.3.0" />
<PackageVersion Include="Azure.ResourceManager.Resources" Version="1.9.0" />
<PackageVersion Include="Azure.ResourceManager.ServiceBus" Version="1.1.0" />
<PackageVersion Include="BenchmarkDotNet" Version="0.14.0" />
<PackageVersion Include="Bogus" Version="35.6.1" />
<PackageVersion Include="ConfigureAwait.Fody" Version="3.3.2" PrivateAssets="All" />
<PackageVersion Include="Confluent.Kafka" Version="2.6.1" />
<PackageVersion Include="Confluent.SchemaRegistry.Serdes.Avro" Version="2.6.1" />
<PackageVersion Include="coverlet.collector" Version="6.0.2" PrivateAssets="All" />
<PackageVersion Include="Cronos" Version="0.9.0" />
<PackageVersion Include="Dapper" Version="2.1.35" />
<PackageVersion Include="DistributedLock.Core" Version="1.0.8" />
<PackageVersion Include="DistributedLock.FileSystem" Version="1.0.3" />
<PackageVersion Include="DistributedLock.Postgres" Version="1.2.1" />
<PackageVersion Include="DistributedLock.Redis" Version="1.0.3" />
<PackageVersion Include="Elastic.Clients.Elasticsearch" Version="8.16.3" />
<PackageVersion Include="Elsa.Studio" Version="3.3.0-rc4" />
<PackageVersion Include="Elsa.Studio.Agents" Version="3.3.0-rc4" />
<PackageVersion Include="Elsa.Studio.Core.BlazorWasm" Version="3.3.0-rc4" />
<PackageVersion Include="Elsa.Studio.Login.BlazorWasm" Version="3.3.0-rc4" />
<PackageVersion Include="FastEndpoints" Version="5.32.0" />
<PackageVersion Include="FastEndpoints.Security" Version="5.32.0" />
<PackageVersion Include="FastEndpoints.Swagger" Version="5.32.0" />
<PackageVersion Include="FluentMigrator" Version="6.2.0" />
<PackageVersion Include="FluentMigrator.Runner" Version="6.2.0" />
<PackageVersion Include="FluentStorage" Version="5.6.0" />
<PackageVersion Include="FluentStorage.Azure.Blobs" Version="5.3.0" />
<PackageVersion Include="Fluid.Core" Version="2.16.0" />
<PackageVersion Include="Fody" Version="6.9.1" />
<PackageVersion Include="GitHubActionsTestLogger" Version="2.4.1" />
<PackageVersion Include="Google.Protobuf" Version="3.29.2" />
<PackageVersion Include="Grpc.Net.Client" Version="2.67.0" />
<PackageVersion Include="Grpc.Tools" Version="2.68.1" />
<PackageVersion Include="Hangfire" Version="1.8.17" />
<PackageVersion Include="Hangfire.MemoryStorage" Version="1.8.1.1" />
<PackageVersion Include="Hangfire.Storage.SQLite" Version="0.4.2" />
<PackageVersion Include="Humanizer.Core" Version="2.14.1" />
<PackageVersion Include="IronCompress" Version="1.6.3" />
<PackageVersion Include="JetBrains.Annotations" Version="2024.3.0" />
<PackageVersion Include="Jint" Version="4.1.0" />
<PackageVersion Include="LinqKit.Core" Version="1.2.7" />
<PackageVersion Include="MailKit" Version="4.9.0" />
<PackageVersion Include="MassTransit" Version="8.3.4" />
<PackageVersion Include="MassTransit.Azure.ServiceBus.Core" Version="8.3.4" />
<PackageVersion Include="MassTransit.RabbitMQ" Version="8.3.4" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp.Scripting" Version="4.12.0" />
<PackageVersion Include="Microsoft.Data.SqlClient" Version="5.2.2" />
<PackageVersion Include="Microsoft.Identity.Client" Version="4.66.2" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
<PackageVersion Include="Microsoft.SemanticKernel" Version="1.32.0" />
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="8.0.0" />
<PackageVersion Include="MongoDB.Driver" Version="3.1.0" />
<PackageVersion Include="MongoDB.Driver.Core.Extensions.DiagnosticSources" Version="2.0.0" />
<PackageVersion Include="MongoDB.Driver.Extensions" Version="2.0.2" />
<PackageVersion Include="MySql.Data" Version="9.1.0" />
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
<PackageVersion Include="NSubstitute" Version="5.3.0" />
<PackageVersion Include="NuGet.Packaging" Version="6.12.1" />
<PackageVersion Include="NuGet.Protocol" Version="6.12.1" />
<PackageVersion Include="Nuke.Components" Version="9.0.3" />
<PackageVersion Include="Open.Linq.AsyncExtensions" Version="1.2.0" />
<PackageVersion Include="Polly.Extensions.Http" Version="3.0.0" />
<PackageVersion Include="PolySharp" Version="1.15.0" />
<PackageVersion Include="Proto.Actor" Version="1.7.0" />
<PackageVersion Include="Proto.Cluster" Version="1.7.0" />
<PackageVersion Include="Proto.Cluster.AzureContainerApps" Version="1.7.0" />
<PackageVersion Include="Proto.Cluster.CodeGen" Version="1.7.0" />
<PackageVersion Include="Proto.Cluster.Kubernetes" Version="1.7.0" />
<PackageVersion Include="Proto.Cluster.TestProvider" Version="1.7.0" />
<PackageVersion Include="Proto.OpenTelemetry" Version="1.7.0" />
<PackageVersion Include="Proto.Persistence" Version="1.7.0" />
<PackageVersion Include="Proto.Persistence.Sqlite" Version="1.7.0" />
<PackageVersion Include="Proto.Persistence.SqlServer" Version="1.7.0" />
<PackageVersion Include="Proto.Remote" Version="1.7.0" />
<PackageVersion Include="pythonnet" Version="3.0.5" />
<PackageVersion Include="Quartz.Extensions.Hosting" Version="3.13.1" />
<PackageVersion Include="Quartz.Serialization.Json" Version="3.13.1" />
<PackageVersion Include="Scrutor" Version="5.0.2" />
<PackageVersion Include="ShortGuid" Version="2.0.1" />
<PackageVersion Include="StackExchange.Redis" Version="2.8.24" />
<PackageVersion Include="System.CommandLine" Version="2.0.0-beta4.22272.1" />
<PackageVersion Include="System.Data.SqlClient" Version="4.9.0" />
<PackageVersion Include="System.Linq.Async" Version="6.0.1" />
<PackageVersion Include="System.Linq.Dynamic.Core" Version="1.5.1" />
<PackageVersion Include="System.Net.Http" Version="4.3.4" />
<PackageVersion Include="System.Text.RegularExpressions" Version="4.3.1" />
<PackageVersion Include="Testcontainers" Version="4.1.0" />
<PackageVersion Include="Testcontainers.PostgreSql" Version="4.1.0" />
<PackageVersion Include="Testcontainers.RabbitMq" Version="4.1.0" />
<PackageVersion Include="Testcontainers.Redis" Version="4.1.0" />
<PackageVersion Include="ThrottleDebounce" Version="2.0.0" />
<PackageVersion Include="WebhooksCore" Version="0.0.1" />
<PackageVersion Include="xunit" Version="2.9.2" />
<PackageVersion Include="xunit.abstractions" Version="2.0.3" />
<PackageVersion Include="xunit.extensibility.core" Version="2.9.2" />
<PackageVersion Include="xunit.runner.visualstudio" Version="3.0.0" />
<PackageVersion Include="Yarp.ReverseProxy" Version="2.2.0" />
<PackageVersion Include="AspNetCore.Authentication.ApiKey" Version="8.0.1" />
<PackageVersion Include="Microsoft.AspNetCore.Authorization" Version="9.0.0" />
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly" Version="9.0.0" />
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="9.0.0" />
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="9.0.0" />
<PackageVersion Include="Microsoft.AspNetCore.DataProtection.Abstractions" Version="9.0.0" />
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Testing" Version="9.0.0" />
<PackageVersion Include="Microsoft.Data.Sqlite" Version="9.0.0" />
<PackageVersion Include="Microsoft.Data.Sqlite.Core" Version="9.0.0" />
<PackageVersion Include="Microsoft.EntityFrameworkCore" Version="9.0.0" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.0" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Relational" Version="9.0.0" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Sqlite" Version="9.0.0" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.SqlServer" Version="9.0.0" />
<PackageVersion Include="Microsoft.Extensions.Caching.Abstractions" Version="9.0.0" />
<PackageVersion Include="Microsoft.Extensions.Caching.Memory" Version="9.0.0" />
<PackageVersion Include="Microsoft.Extensions.Configuration" Version="9.0.0" />
<PackageVersion Include="Microsoft.Extensions.Configuration.Abstractions" Version="9.0.0" />
<PackageVersion Include="Microsoft.Extensions.Configuration.Json" Version="9.0.0" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="9.0.0" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="9.0.0" />
<PackageVersion Include="Microsoft.Extensions.DependencyModel" Version="9.0.0" />
<PackageVersion Include="Microsoft.Extensions.Hosting.Abstractions" Version="9.0.0" />
<PackageVersion Include="Microsoft.Extensions.Http" Version="9.0.0" />
<PackageVersion Include="Microsoft.Extensions.Http.Polly" Version="9.0.0" />
<PackageVersion Include="Microsoft.Extensions.Logging" Version="9.0.0" />
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="9.0.0" />
<PackageVersion Include="Microsoft.Extensions.Logging.Console" Version="9.0.0" />
<PackageVersion Include="Microsoft.Extensions.Options" Version="9.0.0" />
<PackageVersion Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="9.0.0" />
<PackageVersion Include="Npgsql" Version="9.0.2" />
<PackageVersion Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="9.0.2" />
<PackageVersion Include="Oracle.EntityFrameworkCore" Version="9.23.60" />
<PackageVersion Include="Polly" Version="8.5.0" />
<PackageVersion Include="Pomelo.EntityFrameworkCore.MySql" Version="9.0.0-preview.2.efcore.9.0.0" />
<PackageVersion Include="Refit" Version="8.0.0" />
<PackageVersion Include="Refit.HttpClientFactory" Version="8.0.0" />
<PackageVersion Include="System.Formats.Asn1" Version="9.0.0" />
<PackageVersion Include="System.Text.Json" Version="9.0.0" />
</ItemGroup>
</Project>

View file

@ -387,6 +387,18 @@ 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}") = "sql", "sql", "{A0DC5F8E-5D7F-4E8A-A5DF-B1FC31F7336E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Sql", "src\modules\Elsa.Sql\Elsa.Sql.csproj", "{FD3CD5A8-E9B3-467F-90EB-2B7D5B83F348}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Sql.MySql", "src\modules\Elsa.Sql.MySql\Elsa.Sql.MySql.csproj", "{3BED411B-79B5-4CCC-BD46-9549A427B908}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Sql.PostgreSql", "src\modules\Elsa.Sql.PostgreSql\Elsa.Sql.PostgreSql.csproj", "{6CC5FBC7-D3D7-4FE3-AD08-C67939BDB24D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Sql.Sqlite", "src\modules\Elsa.Sql.Sqlite\Elsa.Sql.Sqlite.csproj", "{FA5E857F-B173-4B5D-8049-B817A210DEF5}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Sql.SqlServer", "src\modules\Elsa.Sql.SqlServer\Elsa.Sql.SqlServer.csproj", "{A51F9683-DA9F-45E7-82DE-1E261ACD6D68}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -823,6 +835,26 @@ Global
{BF934627-F531-44FB-BEC2-ECA801FF31E7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BF934627-F531-44FB-BEC2-ECA801FF31E7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BF934627-F531-44FB-BEC2-ECA801FF31E7}.Release|Any CPU.Build.0 = Release|Any CPU
{FD3CD5A8-E9B3-467F-90EB-2B7D5B83F348}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FD3CD5A8-E9B3-467F-90EB-2B7D5B83F348}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FD3CD5A8-E9B3-467F-90EB-2B7D5B83F348}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FD3CD5A8-E9B3-467F-90EB-2B7D5B83F348}.Release|Any CPU.Build.0 = Release|Any CPU
{3BED411B-79B5-4CCC-BD46-9549A427B908}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3BED411B-79B5-4CCC-BD46-9549A427B908}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3BED411B-79B5-4CCC-BD46-9549A427B908}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3BED411B-79B5-4CCC-BD46-9549A427B908}.Release|Any CPU.Build.0 = Release|Any CPU
{6CC5FBC7-D3D7-4FE3-AD08-C67939BDB24D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6CC5FBC7-D3D7-4FE3-AD08-C67939BDB24D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6CC5FBC7-D3D7-4FE3-AD08-C67939BDB24D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6CC5FBC7-D3D7-4FE3-AD08-C67939BDB24D}.Release|Any CPU.Build.0 = Release|Any CPU
{FA5E857F-B173-4B5D-8049-B817A210DEF5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FA5E857F-B173-4B5D-8049-B817A210DEF5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FA5E857F-B173-4B5D-8049-B817A210DEF5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FA5E857F-B173-4B5D-8049-B817A210DEF5}.Release|Any CPU.Build.0 = Release|Any CPU
{A51F9683-DA9F-45E7-82DE-1E261ACD6D68}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A51F9683-DA9F-45E7-82DE-1E261ACD6D68}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A51F9683-DA9F-45E7-82DE-1E261ACD6D68}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A51F9683-DA9F-45E7-82DE-1E261ACD6D68}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -968,6 +1000,12 @@ Global
{D5720DBC-8C2B-42D5-9D9F-2FF6EAD4001C} = {2F3E1026-5054-4E1F-899B-F1A7F70F9912}
{2B939AC9-03A4-479E-AA0D-CB58F4A7F480} = {50470834-4CD8-479A-8B58-0A1869BA5D37}
{BF934627-F531-44FB-BEC2-ECA801FF31E7} = {DD089B8B-DA73-492A-9010-F772D1C178DA}
{A0DC5F8E-5D7F-4E8A-A5DF-B1FC31F7336E} = {5BA4A8FA-F7F4-45B3-AEC8-8886D35AAC79}
{FD3CD5A8-E9B3-467F-90EB-2B7D5B83F348} = {A0DC5F8E-5D7F-4E8A-A5DF-B1FC31F7336E}
{3BED411B-79B5-4CCC-BD46-9549A427B908} = {A0DC5F8E-5D7F-4E8A-A5DF-B1FC31F7336E}
{6CC5FBC7-D3D7-4FE3-AD08-C67939BDB24D} = {A0DC5F8E-5D7F-4E8A-A5DF-B1FC31F7336E}
{FA5E857F-B173-4B5D-8049-B817A210DEF5} = {A0DC5F8E-5D7F-4E8A-A5DF-B1FC31F7336E}
{A51F9683-DA9F-45E7-82DE-1E261ACD6D68} = {A0DC5F8E-5D7F-4E8A-A5DF-B1FC31F7336E}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {D4B5CEAA-7D70-4FCB-A68E-B03FBE5E0E5E}

View file

@ -9,9 +9,9 @@
<ProjectReference Include="..\..\modules\Elsa.Caching.Distributed.MassTransit\Elsa.Caching.Distributed.MassTransit.csproj" />
<ProjectReference Include="..\..\modules\Elsa.Caching.Distributed.ProtoActor\Elsa.Caching.Distributed.ProtoActor.csproj" />
<ProjectReference Include="..\..\modules\Elsa.EntityFrameworkCore.MySql\Elsa.EntityFrameworkCore.MySql.csproj" Condition=" '$(TargetFramework)' != 'net9.0' " />
<ProjectReference Include="..\..\modules\Elsa.EntityFrameworkCore.PostgreSql\Elsa.EntityFrameworkCore.PostgreSql.csproj"/>
<ProjectReference Include="..\..\modules\Elsa.EntityFrameworkCore.PostgreSql\Elsa.EntityFrameworkCore.PostgreSql.csproj" />
<ProjectReference Include="..\..\modules\Elsa.Kafka\Elsa.Kafka.csproj" />
<ProjectReference Include="..\..\modules\Elsa.MassTransit.AzureServiceBus\Elsa.MassTransit.AzureServiceBus.csproj"/>
<ProjectReference Include="..\..\modules\Elsa.MassTransit.AzureServiceBus\Elsa.MassTransit.AzureServiceBus.csproj" />
<ProjectReference Include="..\..\modules\Elsa.OpenTelemetry\Elsa.OpenTelemetry.csproj" />
<ProjectReference Include="..\..\modules\Elsa.Quartz.EntityFrameworkCore.MySql\Elsa.Quartz.EntityFrameworkCore.MySql.csproj" Condition=" '$(TargetFramework)' != 'net9.0' " />
<ProjectReference Include="..\..\modules\Elsa.Secrets.Api\Elsa.Secrets.Api.csproj" />
@ -19,48 +19,53 @@
<ProjectReference Include="..\..\modules\Elsa.Secrets.Persistence.EntityFrameworkCore.Sqlite\Elsa.Secrets.Persistence.EntityFrameworkCore.Sqlite.csproj" />
<ProjectReference Include="..\..\modules\Elsa.Secrets.Persistence.EntityFrameworkCore.SqlServer\Elsa.Secrets.Persistence.EntityFrameworkCore.SqlServer.csproj" />
<ProjectReference Include="..\..\modules\Elsa.Secrets.Scripting\Elsa.Secrets.Scripting.csproj" />
<ProjectReference Include="..\..\modules\Elsa.Sql.MySql\Elsa.Sql.MySql.csproj" />
<ProjectReference Include="..\..\modules\Elsa.Sql.PostgreSql\Elsa.Sql.PostgreSql.csproj" />
<ProjectReference Include="..\..\modules\Elsa.Sql.Sqlite\Elsa.Sql.Sqlite.csproj" />
<ProjectReference Include="..\..\modules\Elsa.Sql.SqlServer\Elsa.Sql.SqlServer.csproj" />
<ProjectReference Include="..\..\modules\Elsa.Sql\Elsa.Sql.csproj" />
<ProjectReference Include="..\..\modules\Elsa.Tenants.AspNetCore\Elsa.Tenants.AspNetCore.csproj" />
<ProjectReference Include="..\..\modules\Elsa\Elsa.csproj"/>
<ProjectReference Include="..\..\common\Elsa.DropIns\Elsa.DropIns.csproj"/>
<ProjectReference Include="..\..\modules\Elsa.Alterations.MassTransit\Elsa.Alterations.MassTransit.csproj"/>
<ProjectReference Include="..\..\modules\Elsa.Alterations\Elsa.Alterations.csproj"/>
<ProjectReference Include="..\..\modules\Elsa.CSharp\Elsa.CSharp.csproj"/>
<ProjectReference Include="..\..\modules\Elsa.EntityFrameworkCore.Sqlite\Elsa.EntityFrameworkCore.Sqlite.csproj"/>
<ProjectReference Include="..\..\modules\Elsa.EntityFrameworkCore.SqlServer\Elsa.EntityFrameworkCore.SqlServer.csproj"/>
<ProjectReference Include="..\..\modules\Elsa.MassTransit.RabbitMq\Elsa.MassTransit.RabbitMq.csproj"/>
<ProjectReference Include="..\..\modules\Elsa.Python\Elsa.Python.csproj"/>
<ProjectReference Include="..\..\modules\Elsa.Quartz.EntityFrameworkCore.Sqlite\Elsa.Quartz.EntityFrameworkCore.Sqlite.csproj"/>
<ProjectReference Include="..\..\modules\Elsa.FileStorage\Elsa.FileStorage.csproj"/>
<ProjectReference Include="..\..\modules\Elsa.Dapper.Migrations\Elsa.Dapper.Migrations.csproj"/>
<ProjectReference Include="..\..\modules\Elsa.Dapper\Elsa.Dapper.csproj"/>
<ProjectReference Include="..\..\modules\Elsa.Elasticsearch\Elsa.Elasticsearch.csproj"/>
<ProjectReference Include="..\..\modules\Elsa.Email\Elsa.Email.csproj"/>
<ProjectReference Include="..\..\modules\Elsa.EntityFrameworkCore\Elsa.EntityFrameworkCore.csproj"/>
<ProjectReference Include="..\..\modules\Elsa.Environments\Elsa.Environments.csproj"/>
<ProjectReference Include="..\..\modules\Elsa.MassTransit\Elsa.MassTransit.csproj"/>
<ProjectReference Include="..\..\modules\Elsa.MongoDb\Elsa.MongoDb.csproj"/>
<ProjectReference Include="..\..\modules\Elsa\Elsa.csproj" />
<ProjectReference Include="..\..\common\Elsa.DropIns\Elsa.DropIns.csproj" />
<ProjectReference Include="..\..\modules\Elsa.Alterations.MassTransit\Elsa.Alterations.MassTransit.csproj" />
<ProjectReference Include="..\..\modules\Elsa.Alterations\Elsa.Alterations.csproj" />
<ProjectReference Include="..\..\modules\Elsa.CSharp\Elsa.CSharp.csproj" />
<ProjectReference Include="..\..\modules\Elsa.EntityFrameworkCore.Sqlite\Elsa.EntityFrameworkCore.Sqlite.csproj" />
<ProjectReference Include="..\..\modules\Elsa.EntityFrameworkCore.SqlServer\Elsa.EntityFrameworkCore.SqlServer.csproj" />
<ProjectReference Include="..\..\modules\Elsa.MassTransit.RabbitMq\Elsa.MassTransit.RabbitMq.csproj" />
<ProjectReference Include="..\..\modules\Elsa.Python\Elsa.Python.csproj" />
<ProjectReference Include="..\..\modules\Elsa.Quartz.EntityFrameworkCore.Sqlite\Elsa.Quartz.EntityFrameworkCore.Sqlite.csproj" />
<ProjectReference Include="..\..\modules\Elsa.FileStorage\Elsa.FileStorage.csproj" />
<ProjectReference Include="..\..\modules\Elsa.Dapper.Migrations\Elsa.Dapper.Migrations.csproj" />
<ProjectReference Include="..\..\modules\Elsa.Dapper\Elsa.Dapper.csproj" />
<ProjectReference Include="..\..\modules\Elsa.Elasticsearch\Elsa.Elasticsearch.csproj" />
<ProjectReference Include="..\..\modules\Elsa.Email\Elsa.Email.csproj" />
<ProjectReference Include="..\..\modules\Elsa.EntityFrameworkCore\Elsa.EntityFrameworkCore.csproj" />
<ProjectReference Include="..\..\modules\Elsa.Environments\Elsa.Environments.csproj" />
<ProjectReference Include="..\..\modules\Elsa.MassTransit\Elsa.MassTransit.csproj" />
<ProjectReference Include="..\..\modules\Elsa.MongoDb\Elsa.MongoDb.csproj" />
<ProjectReference Include="..\..\modules\Elsa.Workflows.Runtime.ProtoActor\Elsa.Workflows.Runtime.ProtoActor.csproj" />
<ProjectReference Include="..\..\modules\Elsa.Identity\Elsa.Identity.csproj"/>
<ProjectReference Include="..\..\modules\Elsa.WorkflowProviders.BlobStorage\Elsa.WorkflowProviders.BlobStorage.csproj"/>
<ProjectReference Include="..\..\modules\Elsa.Hangfire\Elsa.Hangfire.csproj"/>
<ProjectReference Include="..\..\modules\Elsa.Http\Elsa.Http.csproj"/>
<ProjectReference Include="..\..\modules\Elsa.Labels\Elsa.Labels.csproj"/>
<ProjectReference Include="..\..\modules\Elsa.Liquid\Elsa.Liquid.csproj"/>
<ProjectReference Include="..\..\modules\Elsa.Quartz\Elsa.Quartz.csproj"/>
<ProjectReference Include="..\..\modules\Elsa.WorkflowContexts\Elsa.WorkflowContexts.csproj"/>
<ProjectReference Include="..\..\modules\Elsa.Workflows.Api\Elsa.Workflows.Api.csproj"/>
<ProjectReference Include="..\..\modules\Elsa.Identity\Elsa.Identity.csproj" />
<ProjectReference Include="..\..\modules\Elsa.WorkflowProviders.BlobStorage\Elsa.WorkflowProviders.BlobStorage.csproj" />
<ProjectReference Include="..\..\modules\Elsa.Hangfire\Elsa.Hangfire.csproj" />
<ProjectReference Include="..\..\modules\Elsa.Http\Elsa.Http.csproj" />
<ProjectReference Include="..\..\modules\Elsa.Labels\Elsa.Labels.csproj" />
<ProjectReference Include="..\..\modules\Elsa.Liquid\Elsa.Liquid.csproj" />
<ProjectReference Include="..\..\modules\Elsa.Quartz\Elsa.Quartz.csproj" />
<ProjectReference Include="..\..\modules\Elsa.WorkflowContexts\Elsa.WorkflowContexts.csproj" />
<ProjectReference Include="..\..\modules\Elsa.Workflows.Api\Elsa.Workflows.Api.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Azure.Identity"/>
<PackageReference Include="Bogus"/>
<PackageReference Include="DistributedLock.Postgres"/>
<PackageReference Include="DistributedLock.Redis"/>
<PackageReference Include="FluentStorage.Azure.Blobs"/>
<PackageReference Include="Azure.Identity" />
<PackageReference Include="Bogus" />
<PackageReference Include="DistributedLock.Postgres" />
<PackageReference Include="DistributedLock.Redis" />
<PackageReference Include="FluentStorage.Azure.Blobs" />
<PackageReference Include="Proto.Cluster.Kubernetes" />
<PackageReference Include="Grpc.Net.Client" />
<PackageReference Include="Proto.Persistence.Sqlite"/>
<PackageReference Include="Proto.Persistence.SqlServer"/>
<PackageReference Include="Proto.Persistence.Sqlite" />
<PackageReference Include="Proto.Persistence.SqlServer" />
</ItemGroup>
</Project>

View file

@ -34,6 +34,11 @@ using Elsa.Server.Web;
using Elsa.Server.Web.Extensions;
using Elsa.Server.Web.Filters;
using Elsa.Server.Web.Messages;
using Elsa.Sql.Extensions;
using Elsa.Sql.MySql;
using Elsa.Sql.PostgreSql;
using Elsa.Sql.Sqlite;
using Elsa.Sql.SqlServer;
using Elsa.Tenants.AspNetCore;
using Elsa.Tenants.Extensions;
using Elsa.Workflows.Api;
@ -340,6 +345,16 @@ services
if (useCaching)
http.UseCache();
})
.UseSql(options =>
{
options.Clients = client =>
{
client.Register<MySqlClient>("MySql");
client.Register<PostgreSqlClient>("PostgreSql");
client.Register<SqliteClient>("Sqlite");
client.Register<SqlServerClient>("Sql Server");
};
})
.UseEmail(email => email.ConfigureOptions = options => configuration.GetSection("Smtp").Bind(options))
.UseAlterations(alterations =>
{

View file

@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Description>
Provides client implementations for interacting with MySql databases.
</Description>
<PackageTags>elsa module activities sql mysql</PackageTags>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="MySql.Data" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Elsa.Sql\Elsa.Sql.csproj" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,3 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<ConfigureAwait />
</Weavers>

View file

@ -0,0 +1,55 @@
using MySql.Data.MySqlClient;
using Elsa.Sql.Client;
using System.Data;
namespace Elsa.Sql.MySql;
public class MySqlClient : BaseSqlClient, ISqlClient
{
private string? _connectionString;
/// <summary>
/// MySql client implimentation.
/// </summary>
/// <param name="connectionString"></param>
public MySqlClient(string? connectionString) => _connectionString = connectionString;
/// <summary>
/// <inheritdoc/>
/// </summary>
public async Task<int?> ExecuteCommandAsync(string sqlCommand)
{
using var connection = new MySqlConnection(_connectionString);
connection.Open();
var command = new MySqlCommand(sqlCommand, connection);
var result = await command.ExecuteNonQueryAsync();
return result;
}
/// <summary>
/// <inheritdoc/>
/// </summary>
public async Task<object?> ExecuteScalarAsync(string sqlQuery)
{
using var connection = new MySqlConnection(_connectionString);
connection.Open();
var command = new MySqlCommand(sqlQuery, connection);
var result = await command.ExecuteScalarAsync();
return result;
}
/// <summary>
/// <inheritdoc/>
/// </summary>
public async Task<DataSet?> ExecuteQueryAsync(string sqlQuery)
{
using var connection = new MySqlConnection(_connectionString);
connection.Open();
var command = new MySqlCommand(sqlQuery, connection);
using var reader = await command.ExecuteReaderAsync();
return await Task.FromResult(ReadAsDataSet(reader));
}
}

View file

@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Description>
Provides client implementations for interacting with PostgreSql databases.
</Description>
<PackageTags>elsa module activities sql postgresql</PackageTags>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Npgsql" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Elsa.Sql\Elsa.Sql.csproj" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,3 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<ConfigureAwait />
</Weavers>

View file

@ -0,0 +1,55 @@
using Npgsql;
using Elsa.Sql.Client;
using System.Data;
namespace Elsa.Sql.PostgreSql;
public class PostgreSqlClient : BaseSqlClient, ISqlClient
{
private string? _connectionString;
/// <summary>
/// PostgreSQL client implimentation.
/// </summary>
/// <param name="connectionString"></param>
public PostgreSqlClient(string? connectionString) => _connectionString = connectionString;
/// <summary>
/// <inheritdoc/>
/// </summary>
public async Task<int?> ExecuteCommandAsync(string sqlCommand)
{
using var connection = new NpgsqlConnection(_connectionString);
connection.Open();
var command = new NpgsqlCommand(sqlCommand, connection);
var result = await command.ExecuteNonQueryAsync();
return result;
}
/// <summary>
/// <inheritdoc/>
/// </summary>
public async Task<object?> ExecuteScalarAsync(string sqlQuery)
{
using var connection = new NpgsqlConnection(_connectionString);
connection.Open();
var command = new NpgsqlCommand(sqlQuery, connection);
var result = await command.ExecuteScalarAsync();
return result;
}
/// <summary>
/// <inheritdoc/>
/// </summary>
public async Task<DataSet?> ExecuteQueryAsync(string sqlQuery)
{
using var connection = new NpgsqlConnection(_connectionString);
connection.Open();
var command = new NpgsqlCommand(sqlQuery, connection);
using var reader = await command.ExecuteReaderAsync();
return await Task.FromResult(ReadAsDataSet(reader));
}
}

View file

@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Description>
Provides client implementations for interacting with Microsoft SQL Server databases.
</Description>
<PackageTags>elsa module activities sql mssqlserver sqlserver</PackageTags>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Data.SqlClient" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Elsa.Sql\Elsa.Sql.csproj" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,3 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<ConfigureAwait />
</Weavers>

View file

@ -0,0 +1,55 @@
using System.Data;
using Elsa.Sql.Client;
using Microsoft.Data.SqlClient;
namespace Elsa.Sql.SqlServer;
public class SqlServerClient : BaseSqlClient, ISqlClient
{
private string? _connectionString;
/// <summary>
/// Microsoft SQL server client implimentation.
/// </summary>
/// <param name="connectionString"></param>
public SqlServerClient(string? connectionString) => _connectionString = connectionString;
/// <summary>
/// <inheritdoc/>
/// </summary>
public async Task<int?> ExecuteCommandAsync(string sqlCommand)
{
using var connection = new SqlConnection(_connectionString);
connection.Open();
var command = new SqlCommand(sqlCommand, connection);
var result = await command.ExecuteNonQueryAsync();
return result;
}
/// <summary>
/// <inheritdoc/>
/// </summary>
public async Task<object?> ExecuteScalarAsync(string sqlQuery)
{
using var connection = new SqlConnection(_connectionString);
connection.Open();
var command = new SqlCommand(sqlQuery, connection);
var result = await command.ExecuteScalarAsync();
return result;
}
/// <summary>
/// <inheritdoc/>
/// </summary>
public async Task<DataSet?> ExecuteQueryAsync(string sqlQuery)
{
using var connection = new SqlConnection(_connectionString);
connection.Open();
var command = new SqlCommand(sqlQuery, connection);
using var reader = await command.ExecuteReaderAsync();
return await Task.FromResult(ReadAsDataSet(reader));
}
}

View file

@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Description>
Provides client implementations for interacting with Sqlite databases.
</Description>
<PackageTags>elsa module activities sql sqlite</PackageTags>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Data.Sqlite" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Elsa.Sql\Elsa.Sql.csproj" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,3 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<ConfigureAwait />
</Weavers>

View file

@ -0,0 +1,55 @@
using System.Data;
using Elsa.Sql.Client;
using Microsoft.Data.Sqlite;
namespace Elsa.Sql.Sqlite;
public class SqliteClient : BaseSqlClient, ISqlClient
{
private string? _connectionString;
/// <summary>
/// Sqlite client implimentation.
/// </summary>
/// <param name="connectionString"></param>
public SqliteClient(string? connectionString) => _connectionString = connectionString;
/// <summary>
/// <inheritdoc/>
/// </summary>
public async Task<int?> ExecuteCommandAsync(string sqlCommand)
{
using var connection = new SqliteConnection(_connectionString);
connection.Open();
var command = new SqliteCommand(sqlCommand, connection);
var result = await command.ExecuteNonQueryAsync();
return result;
}
/// <summary>
/// <inheritdoc/>
/// </summary>
public async Task<object?> ExecuteScalarAsync(string sqlQuery)
{
using var connection = new SqliteConnection(_connectionString);
connection.Open();
var command = new SqliteCommand(sqlQuery, connection);
var result = await command.ExecuteScalarAsync();
return result;
}
/// <summary>
/// <inheritdoc/>
/// </summary>
public async Task<DataSet?> ExecuteQueryAsync(string sqlQuery)
{
using var connection = new SqliteConnection(_connectionString);
connection.Open();
var command = new SqliteCommand(sqlQuery, connection);
using var reader = await command.ExecuteReaderAsync();
return await Task.FromResult(ReadAsDataSet(reader));
}
}

View file

@ -0,0 +1,71 @@
using System.Runtime.CompilerServices;
using Elsa.Extensions;
using Elsa.Sql.Contracts;
using Elsa.Sql.UIHints;
using Elsa.Workflows;
using Elsa.Workflows.Attributes;
using Elsa.Workflows.Models;
using Elsa.Workflows.UIHints;
namespace Elsa.Sql.Activities;
/// <summary>
/// Execute given SQL command and returns the number of rows affected.
/// </summary>
[Activity("Elsa", "SQL", "Execute given SQL command and returns the number of rows affected.", DisplayName = "SQL Command", Kind = ActivityKind.Task)]
public class SqlCommand : Activity
{
/// <summary>
/// <inheritdoc/>
/// </summary>
public SqlCommand([CallerFilePath] string? source = default, [CallerLineNumber] int? line = default) : base (source, line)
{
}
/// <summary>
/// Database client to connect with.
/// </summary>
[Input(
Description = "Database client.",
UIHint = InputUIHints.DropDown,
UIHandler = typeof(SqlClientsDropDownProvider))]
public Input<string?> Client { get; set; } = default!;
/// <summary>
/// Connection string.
/// </summary>
[Input(
Description = "Connection string.",
CanContainSecrets = true)]
public Input<string?> ConnectionString { get; set; } = default!;
/// <summary>
/// Command to run against the database.
/// </summary>
[Input(
Description = "Command to run against the database.",
UIHint = InputUIHints.SqlEditor)]
public Input<string?> Command { get; set; } = default!;
/// <summary>
/// The number of affected rows.
/// </summary>
[Output(
Description = "The number of rows affected.")]
public Output<int?> Result { get; set; } = default!;
/// <summary>
/// <inheritdoc/>
/// </summary>
protected override async ValueTask ExecuteAsync(ActivityExecutionContext context)
{
var factory = context.GetRequiredService<ISqlClientFactory>();
var client = factory.CreateClient(Client.GetOrDefault(context), ConnectionString.GetOrDefault(context));
var result = await client.ExecuteCommandAsync(Command.GetOrDefault(context));
context.Set(Result, result);
await CompleteAsync(context);
}
}

View file

@ -0,0 +1,72 @@
using System.Data;
using System.Runtime.CompilerServices;
using Elsa.Extensions;
using Elsa.Sql.Contracts;
using Elsa.Sql.UIHints;
using Elsa.Workflows;
using Elsa.Workflows.Attributes;
using Elsa.Workflows.Models;
using Elsa.Workflows.UIHints;
namespace Elsa.Sql.Activities;
/// <summary>
/// Execute given SQL query and return the resulting data.
/// </summary>
[Activity("Elsa", "SQL", "Execute given SQL query and return the resulting data.", DisplayName = "SQL Query", Kind = ActivityKind.Task)]
public class SqlQuery : Activity
{
/// <summary>
/// <inheritdoc/>
/// </summary>
public SqlQuery([CallerFilePath] string? source = default, [CallerLineNumber] int? line = default) : base(source, line)
{
}
/// <summary>
/// Database client to connect with.
/// </summary>
[Input(
Description = "Database client.",
UIHint = InputUIHints.DropDown,
UIHandler = typeof(SqlClientsDropDownProvider))]
public Input<string?> Client { get; set; } = default!;
/// <summary>
/// Connection string.
/// </summary>
[Input(
Description = "Connection string.",
CanContainSecrets = true)]
public Input<string?> ConnectionString { get; set; } = default!;
/// <summary>
/// Query to run against the database.
/// </summary>
[Input(
Description = "Query to run against the database.",
UIHint = InputUIHints.SqlEditor)]
public Input<string?> Query { get; set; } = default!;
/// <summary>
/// <see cref="DataSet"/> of queried results.
/// </summary>
[Output(
Description = "DataSet of queried results.")]
public Output<DataSet?> Results { get; set; } = default!;
/// <summary>
/// <inheritdoc/>
/// </summary>
protected override async ValueTask ExecuteAsync(ActivityExecutionContext context)
{
var factory = context.GetRequiredService<ISqlClientFactory>();
var client = factory.CreateClient(Client.GetOrDefault(context), ConnectionString.GetOrDefault(context));
var results = await client.ExecuteQueryAsync(Query.GetOrDefault(context));
context.Set(Results, results);
await CompleteAsync(context);
}
}

View file

@ -0,0 +1,71 @@
using System.Runtime.CompilerServices;
using Elsa.Extensions;
using Elsa.Sql.Contracts;
using Elsa.Sql.UIHints;
using Elsa.Workflows;
using Elsa.Workflows.Attributes;
using Elsa.Workflows.Models;
using Elsa.Workflows.UIHints;
namespace Elsa.Sql.Activities;
/// <summary>
/// Execute given SQL command and return a single result.
/// </summary>
[Activity("Elsa", "SQL", "Execute given SQL command and return a single result.", DisplayName = "SQL Single Value", Kind = ActivityKind.Task)]
public class SqlSingleValue : Activity
{
/// <summary>
/// <inheritdoc/>
/// </summary>
public SqlSingleValue([CallerFilePath] string? source = default, [CallerLineNumber] int? line = default) : base(source, line)
{
}
/// <summary>
/// Database client to connect with.
/// </summary>
[Input(
Description = "Database client.",
UIHint = InputUIHints.DropDown,
UIHandler = typeof(SqlClientsDropDownProvider))]
public Input<string?> Client { get; set; } = default!;
/// <summary>
/// Connection string.
/// </summary>
[Input(
Description = "Connection string.",
CanContainSecrets = true)]
public Input<string?> ConnectionString { get; set; } = default!;
/// <summary>
/// Query to run against the database.
/// </summary>
[Input(
Description = "Query to run against the database.",
UIHint = InputUIHints.SqlEditor)]
public Input<string?> Query { get; set; } = default!;
/// <summary>
/// Command result.
/// </summary>
[Output(
Description = "Command result.")]
public Output<object?> Result { get; set; } = default!;
/// <summary>
/// <inheritdoc/>
/// </summary>
protected override async ValueTask ExecuteAsync(ActivityExecutionContext context)
{
var factory = context.GetRequiredService<ISqlClientFactory>();
var client = factory.CreateClient(Client.GetOrDefault(context), ConnectionString.GetOrDefault(context));
var result = await client.ExecuteScalarAsync(Query.GetOrDefault(context));
context.Set(Result, result);
await CompleteAsync(context);
}
}

View file

@ -0,0 +1,50 @@
using System.Data;
namespace Elsa.Sql.Client;
public abstract class BaseSqlClient
{
/// <summary>
/// Returns <see cref="IDataReader"/> data as a <see cref="DataSet"/>.
/// </summary>
/// <param name="reader">Reader to return data from.</param>
/// <returns><see cref="DataSet"/> of data.</returns>
protected static DataSet ReadAsDataSet(IDataReader reader)
{
var dataSet = new DataSet("dataset");
var schematable = reader.GetSchemaTable();
var data = new DataSet();
dataSet.Tables.Add(ReadAsDataTable(reader));
return dataSet;
}
/// <summary>
/// Returns <see cref="IDataReader"/> data as a <see cref="DataTable"/>.
/// </summary>
/// <param name="reader">Reader to return data from.</param>
/// <returns><see cref="DataTable"/> of data.</returns>
protected static DataTable ReadAsDataTable(IDataReader reader)
{
var data = new DataTable();
var schemaTable =reader.GetSchemaTable();
foreach (DataRow row in schemaTable.Rows)
{
string colName = row.Field<string>("ColumnName");
Type t = row.Field<Type>("DataType");
data.Columns.Add(colName, t);
}
while (reader.Read())
{
var newRow = data.Rows.Add();
foreach (DataColumn col in data.Columns)
{
newRow[col.ColumnName] = reader[col.ColumnName];
}
}
return data;
}
}

View file

@ -0,0 +1,27 @@
using System.Data;
namespace Elsa.Sql.Client;
public interface ISqlClient
{
/// <summary>
/// Asyncronously executes a Transact-SQL statement against the connection and returns the number of rows affected.
/// </summary>
/// <param name="sqlCommand">The command to execute</param>
/// <returns>The number of rows affected.</returns>
public Task<int?> ExecuteCommandAsync(string sqlCommand);
/// <summary>
/// Asyncronously executes the query, and returns the first column of the first row in the result set returned by the query. Additional columns or rows are ignored.
/// </summary>
/// <param name="sqlQuery">The query to execute</param>
/// <returns>The first column of the first row in the result set, or a null reference if the result set is empty. Returns a maximum of 2033 characters.</returns>
public Task<object?> ExecuteScalarAsync(string sqlQuery);
/// <summary>
/// Asyncronously executes the query, and returns a dataset of data returned by the query.
/// </summary>
/// <param name="sqlQuery">Query to execute</param>
/// <returns>DataSet of the quiried data</returns>
public Task<DataSet?> ExecuteQueryAsync(string sqlQuery);
}

View file

@ -0,0 +1,14 @@
using Elsa.Sql.Client;
namespace Elsa.Sql.Contracts;
public interface ISqlClientFactory
{
/// <summary>
/// Create an instance of the registered client.
/// </summary>
/// <param name="clientName">The name of the registered client to create. This can either be clientName used during registration or the default nameof(client) itself.</param>
/// <param name="connectionString">Connection string.</param>
/// <returns></returns>
public ISqlClient CreateClient(string clientName, string connectionString);
}

View file

@ -0,0 +1,11 @@
namespace Elsa.Sql.Contracts;
public interface ISqlClientNamesProvider
{
/// <summary>
/// Returns a dictionary of registered clients.
/// </summary>
/// <param name="cancellationToken">A token to monitor cancellation requests.</param>
/// <returns>A <see cref="Dictionary{TKey, TValue}"/> of registered client names their <see cref="Type"/>.</returns>
Task<IReadOnlyDictionary<string, Type>> GetRegisteredSqlClientNamesAsync(CancellationToken cancellationToken);
}

View file

@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Description>
Provides activities to interact with sql databases.
</Description>
<PackageTags>elsa module activities sql</PackageTags>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\common\Elsa.Features\Elsa.Features.csproj" />
<ProjectReference Include="..\Elsa.Workflows.Api\Elsa.Workflows.Api.csproj" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,22 @@
using Elsa.Features.Services;
using Elsa.Sql.Features;
namespace Elsa.Sql.Extensions;
/// <summary>
/// Provides methods to install and configure SQL client features.
/// </summary>
public static class ModuleExtensions
{
/// <summary>
/// Adds the <see cref="SqlFeature"/> feature to the system.
/// </summary>
/// <param name="configuration"></param>
/// <param name="configure"></param>
/// <returns></returns>
public static IModule UseSql(this IModule configuration, Action<SqlFeature>? configure= default)
{
configuration.Configure(configure);
return configuration;
}
}

View file

@ -0,0 +1,43 @@
using Elsa.Sql.Client;
using Elsa.Sql.Contracts;
using Elsa.Sql.Services;
using Microsoft.Extensions.DependencyInjection;
namespace Elsa.Sql.Factory;
/// <summary>
/// SQL client factory
/// </summary>
public class SqlClientFactory : ISqlClientFactory
{
private readonly IServiceProvider _serviceProvider;
public SqlClientFactory(IServiceProvider serviceProvider) => _serviceProvider = serviceProvider;
/// <summary>
/// <inheritdoc/>
/// </summary>
public ISqlClient CreateClient(string clientName, string connectionString)
{
if (string.IsNullOrEmpty(clientName))
{
throw new ArgumentException($"Client name can not be empty or null.", nameof(clientName));
}
if (string.IsNullOrEmpty(connectionString))
{
throw new ArgumentException($"Connection string can not be empty or null.", nameof(connectionString));
}
if (_serviceProvider.GetRequiredService<ClientStore>().Clients.TryGetValue(clientName, out var clientType))
{
try
{
return ActivatorUtilities.CreateInstance(_serviceProvider, clientType, connectionString) as ISqlClient;
}
catch (Exception ex)
{
throw new InvalidOperationException($"Unable to create instance of '{clientName}' of type '{clientType}'.", ex);
}
}
throw new ArgumentException($"No registered SQL client provider for '{clientName}'.");
}
}

View file

@ -0,0 +1,57 @@
using Elsa.Extensions;
using Elsa.Features.Abstractions;
using Elsa.Features.Services;
using Elsa.Sql.Contracts;
using Elsa.Sql.Factory;
using Elsa.Sql.Implimentations;
using Elsa.Sql.Services;
using Elsa.Sql.UIHints;
using Elsa.Workflows;
using Microsoft.Extensions.DependencyInjection;
namespace Elsa.Sql.Features;
/// <summary>
/// Setup SQL client features
/// </summary>
public class SqlFeature : FeatureBase
{
/// <summary>
/// Set a callback to configure <see cref="ClientStore"/>.
/// </summary>
public Action<ClientStore> Clients { get; set; } = _ => { };
/// <summary>
/// <inheritdoc/>
/// </summary>
/// <param name="module"></param>
public SqlFeature(IModule module) : base(module)
{
}
/// <summary>
/// <inheritdoc/>
/// </summary>
public override void Configure()
{
Module.AddActivitiesFrom<SqlFeature>();
}
/// <summary>
/// <inheritdoc/>
/// </summary>
public override void Apply()
{
Services
.AddSingleton(provider =>
{
ClientStore clientRegistry = new();
Clients.Invoke(clientRegistry);
return clientRegistry;
})
.AddSingleton<ISqlClientFactory, SqlClientFactory>()
.AddScoped<IPropertyUIHandler, SqlClientsDropDownProvider>()
.AddScoped<ISqlClientNamesProvider, SqlClientNamesProvider>();
}
}

View file

@ -0,0 +1,3 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<ConfigureAwait />
</Weavers>

View file

@ -0,0 +1,23 @@
using Elsa.Sql.Contracts;
using Elsa.Sql.Services;
using Microsoft.Extensions.DependencyInjection;
namespace Elsa.Sql.Implimentations;
/// <summary>
/// Returns registered client names
/// </summary>
public class SqlClientNamesProvider : ISqlClientNamesProvider
{
private readonly IServiceProvider _serviceProvider;
public SqlClientNamesProvider(IServiceProvider serviceProvider) => _serviceProvider = serviceProvider;
/// <summary>
/// <inheritdoc/>
/// </summary>
public Task<IReadOnlyDictionary<string, Type>> GetRegisteredSqlClientNamesAsync(CancellationToken cancellationToken)
{
return Task.FromResult(_serviceProvider.GetRequiredService<ClientStore>().Clients);
}
}

View file

@ -0,0 +1,36 @@
using Elsa.Sql.Client;
namespace Elsa.Sql.Services;
public class ClientStore
{
private readonly Dictionary<string, Type> clients = new();
/// <summary>
/// Dictionary of registered clients and their type.
/// </summary>
public IReadOnlyDictionary<string, Type> Clients => clients;
/// <summary>
/// Registers the specified client type <typeparamref name="TClient"/> with the store.
/// The client type must inherit from <see cref="ISqlClient"/>.
/// </summary>
/// <typeparam name="TClient">
/// The type of the client to be registered. The client must be a class that implements the <see cref="ISqlClient"/> interface.
/// </typeparam>
/// <param name="name">
/// The name of the client to register. If not provided, the name defaults to <c>nameof(TClient)</c>.
/// This value is used as a key to identify the client in the store.
/// </param>
/// <exception cref="InvalidOperationException">
/// Thrown when a client with the same name is already registered in the store.
/// </exception>
/// <remarks>
/// This method registers a client type to the store using a unique key. The key is either the provided <paramref name="name"/> or the default name derived from <typeparamref name="TClient"/>.
/// </remarks>
public void Register<TClient>(string? name) where TClient : class, ISqlClient
{
var key = string.IsNullOrEmpty(name) ? nameof(TClient) : name;
if (clients.ContainsKey(key)) { throw new InvalidOperationException($"Client with key '{name}' is already registered."); }
clients.Add(key, typeof(TClient));
}
}

View file

@ -0,0 +1,18 @@
using System.Reflection;
using Elsa.Sql.Contracts;
using Elsa.Workflows.UIHints.Dropdown;
namespace Elsa.Sql.UIHints;
/// <summary>
/// Provides registered clients for the Client input field.
/// </summary>
/// <param name="sqlClientNamesProvider"></param>
public class SqlClientsDropDownProvider(ISqlClientNamesProvider sqlClientNamesProvider) : DropDownOptionsProviderBase
{
protected override async ValueTask<ICollection<SelectListItem>> GetItemsAsync(PropertyInfo propertyInfo, object? context, CancellationToken cancellationToken)
{
var clients = await sqlClientNamesProvider.GetRegisteredSqlClientNamesAsync(cancellationToken);
return clients.Select(x => new SelectListItem(x.Key, x.Key)).ToList();
}
}