88 lines
3.1 KiB
C#
88 lines
3.1 KiB
C#
#nullable enable
|
|
using System;
|
|
using System.Text;
|
|
|
|
namespace PluralKit.Core
|
|
{
|
|
public class QueryBuilder
|
|
{
|
|
private readonly string? _conflictField;
|
|
private readonly string? _condition;
|
|
private StringBuilder _insertFragment = new StringBuilder();
|
|
private StringBuilder _valuesFragment = new StringBuilder();
|
|
private 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 (suffix != null)
|
|
query.Append($" {suffix}");
|
|
query.Append(";");
|
|
|
|
return query.ToString();
|
|
}
|
|
|
|
public enum QueryType
|
|
{
|
|
Insert,
|
|
Update,
|
|
Upsert
|
|
}
|
|
}
|
|
} |