71 lines
2.4 KiB
C#
71 lines
2.4 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|