From 8b8ec8094435bc5d29cfbe40ee28657ada05a674 Mon Sep 17 00:00:00 2001 From: Ske Date: Sun, 19 May 2019 22:03:28 +0200 Subject: [PATCH] Move database/mapper setup code to Core --- PluralKit.Bot/Bot.cs | 17 ++-------- PluralKit.Bot/Utils.cs | 27 ---------------- PluralKit.Core/DatabaseUtils.cs | 55 +++++++++++++++++++++++++++++++++ PluralKit.Web/Startup.cs | 8 +++-- 4 files changed, 62 insertions(+), 45 deletions(-) create mode 100644 PluralKit.Core/DatabaseUtils.cs diff --git a/PluralKit.Bot/Bot.cs b/PluralKit.Bot/Bot.cs index a84799d0..cefdf524 100644 --- a/PluralKit.Bot/Bot.cs +++ b/PluralKit.Bot/Bot.cs @@ -27,21 +27,8 @@ namespace PluralKit.Bot private async Task MainAsync() { Console.WriteLine("Starting PluralKit..."); - - // Dapper by default tries to pass ulongs to Npgsql, which rejects them since PostgreSQL technically - // doesn't support unsigned types on its own. - // Instead we add a custom mapper to encode them as signed integers instead, converting them back and forth. - SqlMapper.RemoveTypeMap(typeof(ulong)); - SqlMapper.AddTypeHandler(new UlongEncodeAsLongHandler()); - Dapper.DefaultTypeMap.MatchNamesWithUnderscores = true; - - // Also, use NodaTime. it's good. - NpgsqlConnection.GlobalTypeMapper.UseNodaTime(); - // With the thing we add above, Npgsql already handles NodaTime integration - // This makes Dapper confused since it thinks it has to convert it anyway and doesn't understand the types - // So we add a custom type handler that literally just passes the type through to Npgsql - SqlMapper.AddTypeHandler(new PassthroughTypeHandler()); - SqlMapper.AddTypeHandler(new PassthroughTypeHandler()); + + DatabaseUtils.Init(); using (var services = BuildServiceProvider()) { diff --git a/PluralKit.Bot/Utils.cs b/PluralKit.Bot/Utils.cs index 365b2ac6..68c6457c 100644 --- a/PluralKit.Bot/Utils.cs +++ b/PluralKit.Bot/Utils.cs @@ -61,33 +61,6 @@ namespace PluralKit.Bot } } - class UlongEncodeAsLongHandler : SqlMapper.TypeHandler - { - public override ulong Parse(object value) - { - // Cast to long to unbox, then to ulong (???) - return (ulong)(long)value; - } - - public override void SetValue(IDbDataParameter parameter, ulong value) - { - parameter.Value = (long)value; - } - } - - class PassthroughTypeHandler : SqlMapper.TypeHandler - { - public override void SetValue(IDbDataParameter parameter, T value) - { - parameter.Value = value; - } - - public override T Parse(object value) - { - return (T) value; - } - } - class PKSystemTypeReader : TypeReader { public override async Task ReadAsync(ICommandContext context, string input, IServiceProvider services) diff --git a/PluralKit.Core/DatabaseUtils.cs b/PluralKit.Core/DatabaseUtils.cs new file mode 100644 index 00000000..06bb76a9 --- /dev/null +++ b/PluralKit.Core/DatabaseUtils.cs @@ -0,0 +1,55 @@ +using System.Data; +using Dapper; +using NodaTime; +using Npgsql; + +namespace PluralKit +{ + public static class DatabaseUtils + { + public static void Init() + { + // Dapper by default tries to pass ulongs to Npgsql, which rejects them since PostgreSQL technically + // doesn't support unsigned types on its own. + // Instead we add a custom mapper to encode them as signed integers instead, converting them back and forth. + SqlMapper.RemoveTypeMap(typeof(ulong)); + SqlMapper.AddTypeHandler(new UlongEncodeAsLongHandler()); + Dapper.DefaultTypeMap.MatchNamesWithUnderscores = true; + + // Also, use NodaTime. it's good. + NpgsqlConnection.GlobalTypeMapper.UseNodaTime(); + // With the thing we add above, Npgsql already handles NodaTime integration + // This makes Dapper confused since it thinks it has to convert it anyway and doesn't understand the types + // So we add a custom type handler that literally just passes the type through to Npgsql + SqlMapper.AddTypeHandler(new PassthroughTypeHandler()); + SqlMapper.AddTypeHandler(new PassthroughTypeHandler()); + } + + class UlongEncodeAsLongHandler : SqlMapper.TypeHandler + { + public override ulong Parse(object value) + { + // Cast to long to unbox, then to ulong (???) + return (ulong)(long)value; + } + + public override void SetValue(IDbDataParameter parameter, ulong value) + { + parameter.Value = (long)value; + } + } + + class PassthroughTypeHandler : SqlMapper.TypeHandler + { + public override void SetValue(IDbDataParameter parameter, T value) + { + parameter.Value = value; + } + + public override T Parse(object value) + { + return (T) value; + } + } + } +} \ No newline at end of file diff --git a/PluralKit.Web/Startup.cs b/PluralKit.Web/Startup.cs index 3b201fd6..df339377 100644 --- a/PluralKit.Web/Startup.cs +++ b/PluralKit.Web/Startup.cs @@ -20,14 +20,16 @@ namespace PluralKit.Web // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { + DatabaseUtils.Init(); + var config = Configuration.GetSection("PluralKit").Get(); services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); services - .AddSingleton(_ => new NpgsqlConnection(config.Database)) - .AddSingleton() - .AddSingleton() + .AddScoped(_ => new NpgsqlConnection(config.Database)) + .AddTransient() + .AddTransient() .AddSingleton(config); }