move database utils to Database/Utils, create DatabaseMigrator
This commit is contained in:
@@ -1,18 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Data.Common;
|
||||
|
||||
using Dapper;
|
||||
|
||||
namespace PluralKit.Core {
|
||||
public static class ConnectionUtils
|
||||
{
|
||||
public static async IAsyncEnumerable<T> QueryStreamAsync<T>(this IPKConnection conn, string sql, object param)
|
||||
{
|
||||
await using var reader = (DbDataReader) await conn.ExecuteReaderAsync(sql, param);
|
||||
var parser = reader.GetRowParser<T>();
|
||||
|
||||
while (await reader.ReadAsync())
|
||||
yield return parser(reader);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,20 +0,0 @@
|
||||
using System.Threading;
|
||||
|
||||
namespace PluralKit.Core
|
||||
{
|
||||
public class DbConnectionCountHolder
|
||||
{
|
||||
private int _connectionCount;
|
||||
public int ConnectionCount => _connectionCount;
|
||||
|
||||
public void Increment()
|
||||
{
|
||||
Interlocked.Increment(ref _connectionCount);
|
||||
}
|
||||
|
||||
public void Decrement()
|
||||
{
|
||||
Interlocked.Decrement(ref _connectionCount);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,88 +0,0 @@
|
||||
#nullable enable
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace PluralKit.Core
|
||||
{
|
||||
public class QueryBuilder
|
||||
{
|
||||
private readonly string? _conflictField;
|
||||
private readonly string? _condition;
|
||||
private readonly StringBuilder _insertFragment = new StringBuilder();
|
||||
private readonly StringBuilder _valuesFragment = new StringBuilder();
|
||||
private readonly StringBuilder _updateFragment = new StringBuilder();
|
||||
private bool _firstInsert = true;
|
||||
private bool _firstUpdate = true;
|
||||
public QueryType Type { get; }
|
||||
public string Table { get; }
|
||||
|
||||
private QueryBuilder(QueryType type, string table, string? conflictField, string? condition)
|
||||
{
|
||||
Type = type;
|
||||
Table = table;
|
||||
_conflictField = conflictField;
|
||||
_condition = condition;
|
||||
}
|
||||
|
||||
public static QueryBuilder Insert(string table) => new QueryBuilder(QueryType.Insert, table, null, null);
|
||||
public static QueryBuilder Update(string table, string condition) => new QueryBuilder(QueryType.Update, table, null, condition);
|
||||
public static QueryBuilder Upsert(string table, string conflictField) => new QueryBuilder(QueryType.Upsert, table, conflictField, null);
|
||||
|
||||
public QueryBuilder Constant(string fieldName, string paramName)
|
||||
{
|
||||
if (_firstInsert) _firstInsert = false;
|
||||
else
|
||||
{
|
||||
_insertFragment.Append(", ");
|
||||
_valuesFragment.Append(", ");
|
||||
}
|
||||
|
||||
_insertFragment.Append(fieldName);
|
||||
_valuesFragment.Append(paramName);
|
||||
return this;
|
||||
}
|
||||
|
||||
public QueryBuilder Variable(string fieldName, string paramName)
|
||||
{
|
||||
Constant(fieldName, paramName);
|
||||
|
||||
if (_firstUpdate) _firstUpdate = false;
|
||||
else _updateFragment.Append(", ");
|
||||
|
||||
_updateFragment.Append(fieldName);
|
||||
_updateFragment.Append(" = ");
|
||||
_updateFragment.Append(paramName);
|
||||
return this;
|
||||
}
|
||||
|
||||
public string Build(string? suffix = null)
|
||||
{
|
||||
if (_firstInsert)
|
||||
throw new ArgumentException("No fields have been added to the query.");
|
||||
|
||||
StringBuilder query = new StringBuilder(Type switch
|
||||
{
|
||||
QueryType.Insert => $"insert into {Table} ({_insertFragment}) values ({_valuesFragment})",
|
||||
QueryType.Upsert => $"insert into {Table} ({_insertFragment}) values ({_valuesFragment}) on conflict ({_conflictField}) do update set {_updateFragment}",
|
||||
QueryType.Update => $"update {Table} set {_updateFragment}",
|
||||
_ => throw new ArgumentOutOfRangeException($"Unknown query type {Type}")
|
||||
});
|
||||
|
||||
if (Type == QueryType.Update && _condition != null)
|
||||
query.Append($" where {_condition}");
|
||||
|
||||
if (!string.IsNullOrEmpty(suffix))
|
||||
query.Append($" {suffix}");
|
||||
query.Append(";");
|
||||
|
||||
return query.ToString();
|
||||
}
|
||||
|
||||
public enum QueryType
|
||||
{
|
||||
Insert,
|
||||
Update,
|
||||
Upsert
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,45 +0,0 @@
|
||||
using System.Text;
|
||||
|
||||
using Dapper;
|
||||
|
||||
namespace PluralKit.Core
|
||||
{
|
||||
public class UpdateQueryBuilder
|
||||
{
|
||||
private readonly QueryBuilder _qb;
|
||||
private readonly DynamicParameters _params = new DynamicParameters();
|
||||
|
||||
private UpdateQueryBuilder(QueryBuilder qb)
|
||||
{
|
||||
_qb = qb;
|
||||
}
|
||||
|
||||
public static UpdateQueryBuilder Insert(string table) => new UpdateQueryBuilder(QueryBuilder.Insert(table));
|
||||
public static UpdateQueryBuilder Update(string table, string condition) => new UpdateQueryBuilder(QueryBuilder.Update(table, condition));
|
||||
public static UpdateQueryBuilder Upsert(string table, string conflictField) => new UpdateQueryBuilder(QueryBuilder.Upsert(table, conflictField));
|
||||
|
||||
public UpdateQueryBuilder WithConstant<T>(string name, T value)
|
||||
{
|
||||
_params.Add(name, value);
|
||||
_qb.Constant(name, $"@{name}");
|
||||
return this;
|
||||
}
|
||||
|
||||
public UpdateQueryBuilder With<T>(string columnName, T value)
|
||||
{
|
||||
_params.Add(columnName, value);
|
||||
_qb.Variable(columnName, $"@{columnName}");
|
||||
return this;
|
||||
}
|
||||
|
||||
public UpdateQueryBuilder With<T>(string columnName, Partial<T> partialValue)
|
||||
{
|
||||
return partialValue.IsPresent ? With(columnName, partialValue.Value) : this;
|
||||
}
|
||||
|
||||
public (string Query, DynamicParameters Parameters) Build(string suffix = "")
|
||||
{
|
||||
return (_qb.Build(suffix), _params);
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user