diff options
author | vnugent <public@vaughnnugent.com> | 2024-02-14 14:35:03 -0500 |
---|---|---|
committer | vnugent <public@vaughnnugent.com> | 2024-02-14 14:35:03 -0500 |
commit | 54760bfabb36c96f666ca7f77028d0d6a9c812fc (patch) | |
tree | cd0d010ef461ecd8a7259df0ade979471a6e527e /lib/sql-providers/sqlserver/VNLib.Plugins.Extensions.Loading.Sql.SQLServer/src | |
parent | 107f9774df2ad484f3edc5f401c738f647f00f01 (diff) |
Squashed commit of the following:
commit d72bd53e20770be4ced0d627567ecf567d1ce9f4
Author: vnugent <public@vaughnnugent.com>
Date: Mon Feb 12 18:34:52 2024 -0500
refactor: #1 convert sql libraries to assets for better code splitting
commit 736b873e32447254b3aadbb5c6252818c25e8fd4
Author: vnugent <public@vaughnnugent.com>
Date: Sun Feb 4 01:30:25 2024 -0500
submit pending changes
Diffstat (limited to 'lib/sql-providers/sqlserver/VNLib.Plugins.Extensions.Loading.Sql.SQLServer/src')
2 files changed, 208 insertions, 0 deletions
diff --git a/lib/sql-providers/sqlserver/VNLib.Plugins.Extensions.Loading.Sql.SQLServer/src/SqlServerExport.cs b/lib/sql-providers/sqlserver/VNLib.Plugins.Extensions.Loading.Sql.SQLServer/src/SqlServerExport.cs new file mode 100644 index 0000000..71f16bf --- /dev/null +++ b/lib/sql-providers/sqlserver/VNLib.Plugins.Extensions.Loading.Sql.SQLServer/src/SqlServerExport.cs @@ -0,0 +1,149 @@ +/* +* Copyright (c) 2024 Vaughn Nugent +* +* Library: VNLib +* Package: VNLib.Plugins.Extensions.Loading.Sql.SQLServer +* File: SQLServerExport.cs +* +* SQLServerExport.cs is part of VNLib.Plugins.Extensions.Loading.Sql.SQLServer which +* is part of the larger VNLib collection of libraries and utilities. +* +* VNLib.Plugins.Extensions.Loading.Sql is free software: you can redistribute it and/or modify +* it under the terms of the GNU Affero General Public License as +* published by the Free Software Foundation, either version 3 of the +* License, or (at your option) any later version. +* +* VNLib.Plugins.Extensions.Loading.Sql is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Affero General Public License for more details. +* +* You should have received a copy of the GNU Affero General Public License +* along with this program. If not, see https://www.gnu.org/licenses/. +*/ + +using System; +using System.Text.Json; +using System.Data.Common; +using System.Threading.Tasks; + +using Microsoft.Data.SqlClient; + +using Microsoft.EntityFrameworkCore; + +using VNLib.Utils.Logging; +using VNLib.Plugins.Extensions.Loading; + +namespace VNLib.Plugins.Extensions.Sql +{ + + [ServiceExport] + [ConfigurationName("sql", Required = true)] + public sealed class SqlServerExport(PluginBase plugin, IConfigScope config) + { + private async Task<string> BuildConnStringAsync() + { + //See if the user suggested a raw connection string + if (config.TryGetProperty("connection_string", ps => ps.GetString(), out string? conString)) + { + return conString!; + } + else if (config.TryGetValue("json", out JsonElement value)) + { + JsonSerializerOptions opt = new(JsonSerializerDefaults.General) + { + AllowTrailingCommas = true, + IgnoreReadOnlyFields = true, + DictionaryKeyPolicy = JsonNamingPolicy.SnakeCaseLower, + }; + + SqlConnectionStringBuilder b = value.Deserialize<SqlConnectionStringBuilder>(opt)!; + + //Get the password from the secret manager + using ISecretResult? secret = await plugin.TryGetSecretAsync("db_password"); + + b.Password = secret?.Result.ToString(); + return b.ConnectionString; + } + else + { + //Get the password from the secret manager + using ISecretResult? secret = await plugin.TryGetSecretAsync("db_password"); + + // Build connection string + return new SqlConnectionStringBuilder() + { + DataSource = config["hostname"].GetString(), + InitialCatalog = config["catalog"].GetString(), + UserID = config["username"].GetString(), + Pooling = true, + + + ApplicationName = config.GetValueOrDefault("application_name", p => p.GetString(), string.Empty), + HostNameInCertificate = config.GetValueOrDefault("hostname_in_certificate", p => p.GetString(), string.Empty), + PacketSize = config.GetValueOrDefault("packet_size", p => p.GetInt32(), 8000), + Encrypt = config.GetValueOrDefault("encrypted", p => p.GetBoolean(), false), + IntegratedSecurity = config.GetValueOrDefault("integrated_security", p => p.GetBoolean(), false), + MultipleActiveResultSets = config.GetValueOrDefault("multiple_active_result_sets", p => p.GetBoolean(), false), + ConnectTimeout = config.GetValueOrDefault("connect_timeout", p => p.GetInt32(), 15), + LoadBalanceTimeout = config.GetValueOrDefault("load_balance_timeout", p => p.GetInt32(), 0), + MaxPoolSize = config.GetValueOrDefault("max_pool_size", p => p.GetInt32(), 100), + MinPoolSize = config.GetValueOrDefault("min_pool_size", p => p.GetInt32(), 0), + TransactionBinding = config.GetValueOrDefault("transaction_binding", p => p.GetString(), "Implicit Unbind"), + TypeSystemVersion = config.GetValueOrDefault("type_system_version", p => p.GetString(), "Latest"), + WorkstationID = config.GetValueOrDefault("workstation_id", p => p.GetString(), string.Empty), + CurrentLanguage = config.GetValueOrDefault("current_language", p => p.GetString(), "us_english"), + PersistSecurityInfo = config.GetValueOrDefault("persist_security_info", p => p.GetBoolean(), false), + Replication = config.GetValueOrDefault("replication", p => p.GetBoolean(), false), + TrustServerCertificate = config.GetValueOrDefault("trust_server_certificate", p => p.GetBoolean(), false), + UserInstance = config.GetValueOrDefault("user_instance", p => p.GetBoolean(), false), + + Password = secret?.Result.ToString(), + } + .ConnectionString; + } + } + + /* + * NOTICE: + * Function names must be public and must match the SqlConnectionLoader delegate names. + * + * GetDbConnection - A sync or async function that takes a configuration scope and + * returns a DbConnection factory + * + * GetDbOptions - A sync or async function that takes a configuration scope and + * returns a DbConnectionOptions instance + * + * GetProviderName - Returns a string that is the provider name for the connection + */ + + public string GetProviderName() => "sqlserver"; + + public async Task<Func<DbConnection>> GetDbConnectionAsync(IConfigScope sqlConfig) + { + //Store local copy of the connection string, probably not the best idea because of the password, but best for now + string connString = await BuildConnStringAsync(); + + return () => new SqlConnection(connString); + } + + public async Task<DbContextOptions> GetDbOptionsAsync(IConfigScope sqlConfig) + { + //Get the connection string from the configuration + string connString = await BuildConnStringAsync(); + + //Build the options using the mysql extension method + DbContextOptionsBuilder b = new(); + b.UseSqlServer(connString); + + //Write debug loggin to the debug log if the user has it enabled or the plugin is in debug mode + if (sqlConfig.GetValueOrDefault("debug", p => p.GetBoolean(), false) || plugin.IsDebug()) + { + //Write the SQL to the debug log + b.LogTo((v) => plugin.Log.Debug("SqlServer: {v}", v)); + } + + return b.Options; + } + } +} diff --git a/lib/sql-providers/sqlserver/VNLib.Plugins.Extensions.Loading.Sql.SQLServer/src/VNLib.Plugins.Extensions.Loading.Sql.SQLServer.csproj b/lib/sql-providers/sqlserver/VNLib.Plugins.Extensions.Loading.Sql.SQLServer/src/VNLib.Plugins.Extensions.Loading.Sql.SQLServer.csproj new file mode 100644 index 0000000..fea8eee --- /dev/null +++ b/lib/sql-providers/sqlserver/VNLib.Plugins.Extensions.Loading.Sql.SQLServer/src/VNLib.Plugins.Extensions.Loading.Sql.SQLServer.csproj @@ -0,0 +1,59 @@ +<Project Sdk="Microsoft.NET.Sdk"> + + <PropertyGroup> + <TargetFramework>net8.0</TargetFramework> + <AssemblyName>VNLib.Plugins.Extensions.Sql.SqlServer</AssemblyName> + <RootNamespace>VNLib.Plugins.Extensions.Sql</RootNamespace> + <Nullable>enable</Nullable> + <ImplicitUsings>disable</ImplicitUsings> + <GenerateDocumentationFile>True</GenerateDocumentationFile> + <!--Enable dynamic loading--> + <EnableDynamicLoading>true</EnableDynamicLoading> + </PropertyGroup> + + <PropertyGroup> + <PackageId>VNLib.Plugins.Extensions.Sql.SqlServer</PackageId> + <Authors>Vaughn Nugent</Authors> + <Company>Vaughn Nugent</Company> + <Product>VNLib.Plugins.Extensions.Sql.SqlServer</Product> + <Copyright>Copyright © 2024 Vaughn Nugent</Copyright> + <PackageProjectUrl>https://www.vaughnnugent.com/resources/software/modules/VNLib.Plugins.Extensions</PackageProjectUrl> + <RepositoryUrl>https://github.com/VnUgE/VNLib.Plugins.Extensions/tree/master/lib/sql-providers/VNLib.Plugins.Extensions.Sql.SqlServer</RepositoryUrl> + <Description>A runtime asset library that provides SqlServer interfaces for ADO and EFCore SQL server clients</Description> + <PackageReadmeFile>README.md</PackageReadmeFile> + <PackageLicenseFile>LICENSE</PackageLicenseFile> + </PropertyGroup> + + <ItemGroup> + <None Include="../../../../../LICENSE"> + <Pack>True</Pack> + <PackagePath>\</PackagePath> + <CopyToOutputDirectory>Always</CopyToOutputDirectory> + </None> + <None Include="..\README.md"> + <Pack>True</Pack> + <PackagePath>\</PackagePath> + </None> + </ItemGroup> + + <ItemGroup> + <PackageReference Include="ErrorProne.NET.CoreAnalyzers" Version="0.1.2"> + <PrivateAssets>all</PrivateAssets> + <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> + </PackageReference> + <PackageReference Include="ErrorProne.NET.Structs" Version="0.1.2"> + <PrivateAssets>all</PrivateAssets> + <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> + </PackageReference> + <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.1" /> + </ItemGroup> + + <ItemGroup> + <ProjectReference Include="..\..\..\..\VNLib.Plugins.Extensions.Loading\src\VNLib.Plugins.Extensions.Loading.csproj" /> + </ItemGroup> + + <Target Condition="'$(BuildingInsideVisualStudio)' == true" Name="PostBuild" AfterTargets="PostBuildEvent"> + <Exec Command="start xcopy "$(TargetDir)" "$(SolutionDir)devplugins\RuntimeAssets\$(TargetName)" /E /Y /R" /> + </Target> + +</Project> |