Foxnouns.NET/Foxnouns.DataMigrator/GoDatabase.cs

72 lines
2.4 KiB
C#
Raw Permalink Normal View History

2024-12-16 21:38:38 +01:00
using System.Data;
using Dapper;
using Foxnouns.DataMigrator.Models;
using Newtonsoft.Json;
using Npgsql;
namespace Foxnouns.DataMigrator;
public static class GoDatabase
{
private static NpgsqlDataSource? _dataSource;
public static async Task<NpgsqlConnection> GetConnectionAsync()
{
if (_dataSource != null)
return await _dataSource.OpenConnectionAsync();
DefaultTypeMap.MatchNamesWithUnderscores = true;
SqlMapper.RemoveTypeMap(typeof(ulong));
SqlMapper.AddTypeHandler(new UlongEncodeAsLongHandler());
SqlMapper.AddTypeHandler(new JsonTypeHandler<GoFieldEntry[]>());
SqlMapper.AddTypeHandler(new JsonTypeHandler<Dictionary<string, GoCustomPreference>>());
SqlMapper.AddTypeHandler(new JsonTypeHandler<GoPronounEntry[]>());
SqlMapper.AddTypeHandler(new UlongListHandler());
string dsn =
Environment.GetEnvironmentVariable("GO_DATABASE")
?? throw new Exception("$GO_DATABASE is not set");
var dataSourceBuilder = new NpgsqlDataSourceBuilder(dsn);
dataSourceBuilder.UseJsonNet();
_dataSource = dataSourceBuilder.Build();
return await _dataSource.OpenConnectionAsync();
}
// dapper why
// taken from https://codeberg.org/starshine/catalogger/src/branch/main/Catalogger.Backend/Database/DatabasePool.cs
private class UlongEncodeAsLongHandler : SqlMapper.TypeHandler<ulong>
{
public override void SetValue(IDbDataParameter parameter, ulong value) =>
parameter.Value = (long)value;
public override ulong Parse(object value) =>
// Cast to long to unbox, then to ulong (???)
(ulong)(long)value;
}
private class UlongListHandler : SqlMapper.TypeHandler<List<ulong>>
{
public override void SetValue(IDbDataParameter parameter, List<ulong>? value) =>
parameter.Value = value?.Select(i => (long)i).ToArray();
public override List<ulong>? Parse(object value) =>
((long[])value).Select(i => (ulong)i).ToList();
}
private class JsonTypeHandler<T> : SqlMapper.TypeHandler<T>
{
public override void SetValue(IDbDataParameter parameter, T? value) =>
parameter.Value = JsonConvert.SerializeObject(value);
public override T? Parse(object value)
{
var json = (string)value;
return JsonConvert.DeserializeObject<T>(json) ?? default;
}
}
}