diff options
author | vnugent <public@vaughnnugent.com> | 2023-01-09 15:09:13 -0500 |
---|---|---|
committer | vnugent <public@vaughnnugent.com> | 2023-01-09 15:09:13 -0500 |
commit | a46c3bf452d287b50b2e7dd5a24f5995c9fd26f6 (patch) | |
tree | 3a978b2dd2887b5c0e25f595516594a647d8e880 /lib/VNLib.Plugins.Extensions.Loading.Sql/src | |
parent | 189c6714057bf45553847eaeb9ce97eb7272eb8c (diff) |
Restructure
Diffstat (limited to 'lib/VNLib.Plugins.Extensions.Loading.Sql/src')
-rw-r--r-- | lib/VNLib.Plugins.Extensions.Loading.Sql/src/SqlDbConnectionLoader.cs | 174 | ||||
-rw-r--r-- | lib/VNLib.Plugins.Extensions.Loading.Sql/src/VNLib.Plugins.Extensions.Loading.Sql.csproj | 41 |
2 files changed, 215 insertions, 0 deletions
diff --git a/lib/VNLib.Plugins.Extensions.Loading.Sql/src/SqlDbConnectionLoader.cs b/lib/VNLib.Plugins.Extensions.Loading.Sql/src/SqlDbConnectionLoader.cs new file mode 100644 index 0000000..c230cf5 --- /dev/null +++ b/lib/VNLib.Plugins.Extensions.Loading.Sql/src/SqlDbConnectionLoader.cs @@ -0,0 +1,174 @@ +/* +* Copyright (c) 2022 Vaughn Nugent +* +* Library: VNLib +* Package: VNLib.Plugins.Extensions.Loading.Sql +* File: SqlDbConnectionLoader.cs +* +* SqlDbConnectionLoader.cs is part of VNLib.Plugins.Extensions.Loading.Sql 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 General Public License as published +* by the Free Software Foundation, either version 2 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 +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with VNLib.Plugins.Extensions.Loading.Sql. If not, see http://www.gnu.org/licenses/. +*/ + +using System; +using System.Text.Json; +using System.Data.Common; + +using MySqlConnector; + +using Microsoft.Data.Sqlite; +using Microsoft.Data.SqlClient; +using Microsoft.EntityFrameworkCore; + +using VNLib.Utils.Logging; +using VNLib.Utils.Extensions; + +namespace VNLib.Plugins.Extensions.Loading.Sql +{ + /// <summary> + /// Provides common basic SQL loading extensions for plugins + /// </summary> + public static class SqlDbConnectionLoader + { + public const string SQL_CONFIG_KEY = "sql"; + public const string DB_PASSWORD_KEY = "db_password"; + + + /// <summary> + /// Gets (or loads) the ambient sql connection factory for the current plugin + /// </summary> + /// <param name="plugin"></param> + /// <returns>The ambient <see cref="DbConnection"/> factory</returns> + /// <exception cref="KeyNotFoundException"></exception> + /// <exception cref="ObjectDisposedException"></exception> + public static Func<DbConnection> GetConnectionFactory(this PluginBase plugin) + { + plugin.ThrowIfUnloaded(); + //Get or load + return LoadingExtensions.GetOrCreateSingleton(plugin, FactoryLoader); + } + + private static Func<DbConnection> FactoryLoader(PluginBase plugin) + { + IReadOnlyDictionary<string, JsonElement> sqlConf = plugin.GetConfig(SQL_CONFIG_KEY); + + //Get the db-type + string? type = sqlConf.GetPropString("db_type"); + + if ("sqlite".Equals(type, StringComparison.OrdinalIgnoreCase)) + { + //Use connection builder + DbConnectionStringBuilder sqlBuilder = new SqliteConnectionStringBuilder() + { + DataSource = sqlConf["source"].GetString(), + }; + string connectionString = sqlBuilder.ToString(); + DbConnection DbFactory() => new SqliteConnection(connectionString); + return DbFactory; + } + else if("mysql".Equals(type, StringComparison.OrdinalIgnoreCase)) + { + using SecretResult? password = plugin.TryGetSecretAsync(DB_PASSWORD_KEY).Result; + + DbConnectionStringBuilder sqlBuilder = new MySqlConnectionStringBuilder() + { + Server = sqlConf["hostname"].GetString(), + Database = sqlConf["database"].GetString(), + UserID = sqlConf["username"].GetString(), + Password = password?.Result.ToString(), + Pooling = true, + LoadBalance = MySqlLoadBalance.LeastConnections, + MinimumPoolSize = sqlConf["min_pool_size"].GetUInt32() + }; + + string connectionString = sqlBuilder.ToString(); + DbConnection DbFactory() => new MySqlConnection(connectionString); + return DbFactory; + } + //Default to mssql + else + { + using SecretResult? password = plugin.TryGetSecretAsync(DB_PASSWORD_KEY).Result; + + //Use connection builder + DbConnectionStringBuilder sqlBuilder = new SqlConnectionStringBuilder() + { + DataSource = sqlConf["hostname"].GetString(), + UserID = sqlConf["username"].GetString(), + Password = password?.Result.ToString(), + InitialCatalog = sqlConf["catalog"].GetString(), + IntegratedSecurity = sqlConf["ms_security"].GetBoolean(), + Pooling = true, + MinPoolSize = sqlConf["min_pool_size"].GetInt32(), + Replication = true + }; + string connectionString = sqlBuilder.ToString(); + DbConnection DbFactory() => new SqlConnection(connectionString); + return DbFactory; + } + } + + /// <summary> + /// Gets (or loads) the ambient <see cref="DbContextOptions"/> configured from + /// the ambient sql factory + /// </summary> + /// <param name="plugin"></param> + /// <returns>The ambient <see cref="DbContextOptions"/> for the current plugin</returns> + /// <exception cref="KeyNotFoundException"></exception> + /// <exception cref="ObjectDisposedException"></exception> + /// <remarks>If plugin is in debug mode, writes log data to the default log</remarks> + public static DbContextOptions GetContextOptions(this PluginBase plugin) + { + plugin.ThrowIfUnloaded(); + return LoadingExtensions.GetOrCreateSingleton(plugin, GetDbOptionsLoader); + } + + private static DbContextOptions GetDbOptionsLoader(PluginBase plugin) + { + //Get a db connection object + using DbConnection connection = plugin.GetConnectionFactory().Invoke(); + DbContextOptionsBuilder builder = new(); + + //Determine connection type + if(connection is SqlConnection sql) + { + //Use sql server from connection + builder.UseSqlServer(sql.ConnectionString); + } + else if(connection is SqliteConnection slc) + { + builder.UseSqlite(slc.ConnectionString); + } + else if(connection is MySqlConnection msconn) + { + //Detect version + ServerVersion version = ServerVersion.AutoDetect(msconn); + + builder.UseMySql(msconn.ConnectionString, version); + } + + //Enable logging + if(plugin.IsDebug()) + { + builder.LogTo(plugin.Log.Debug); + } + + //Get context and freez it before returning + DbContextOptions options = builder.Options; + options.Freeze(); + return options; + } + } +} diff --git a/lib/VNLib.Plugins.Extensions.Loading.Sql/src/VNLib.Plugins.Extensions.Loading.Sql.csproj b/lib/VNLib.Plugins.Extensions.Loading.Sql/src/VNLib.Plugins.Extensions.Loading.Sql.csproj new file mode 100644 index 0000000..ea876c1 --- /dev/null +++ b/lib/VNLib.Plugins.Extensions.Loading.Sql/src/VNLib.Plugins.Extensions.Loading.Sql.csproj @@ -0,0 +1,41 @@ +<Project Sdk="Microsoft.NET.Sdk"> + + <PropertyGroup> + <TargetFramework>net6.0</TargetFramework> + <ImplicitUsings>enable</ImplicitUsings> + <Nullable>enable</Nullable> + <Authors>Vaughn Nugent</Authors> + <Copyright>Copyright © 2022 Vaughn Nugent</Copyright> + <PackageProjectUrl>https://www.vaughnnugent.com/resources</PackageProjectUrl> + <Version>1.0.1.1</Version> + <GenerateDocumentationFile>True</GenerateDocumentationFile> + <SignAssembly>True</SignAssembly> + <AssemblyOriginatorKeyFile>\\vaughnnugent.com\Internal\Folder Redirection\vman\Documents\Programming\Software\StrongNameingKey.snk</AssemblyOriginatorKeyFile> + </PropertyGroup> + + <PropertyGroup> + <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies> + </PropertyGroup> + + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> + <Deterministic>False</Deterministic> + </PropertyGroup> + + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'"> + <Deterministic>False</Deterministic> + </PropertyGroup> + + <ItemGroup> + <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="6.0.11" /> + <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.11" /> + <PackageReference Include="MySqlConnector" Version="2.2.0" /> + <PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="6.0.2" /> + </ItemGroup> + + <ItemGroup> + <ProjectReference Include="..\..\..\VNLib\Utils\src\VNLib.Utils.csproj" /> + <ProjectReference Include="..\..\PluginBase\VNLib.Plugins.PluginBase.csproj" /> + <ProjectReference Include="..\VNLib.Plugins.Extensions.Loading\VNLib.Plugins.Extensions.Loading.csproj" /> + </ItemGroup> + +</Project> |