ServerDatabase/Database/CommandHandler.cs

408 lines
16 KiB
C#
Raw Permalink Normal View History

2024-03-22 12:11:19 -04:00
using Npgsql;
using ServerDatabase.Utils;
namespace ServerDatabase;
2024-03-29 11:11:14 -04:00
public class CommandHandler<TClass> : ICommandHandler where TClass : class, new()
2024-03-22 12:11:19 -04:00
{
2024-03-29 11:11:14 -04:00
internal List<IBetterTable> Tables = new();
internal List<IBetterParameter> _Parameters = new();
internal List<IBetterParameter> _Values = new();
internal List<Parameter> _ValuesOld = new();
internal List<Parameter> _ParametersOld = new();
public IReadOnlyList<IBetterParameter> Parameters
{
get => _Parameters.AsReadOnly();
}
public IReadOnlyList<IBetterParameter> Values
{
get => _Values.AsReadOnly();
}
private Order? Order = null;
2024-03-22 12:11:19 -04:00
private IBetterTable _betterTable;
2024-03-29 11:11:14 -04:00
private string? ctc = null;
private char table_as = 'A';
private ICommandHandler? _CommandHandlerParent = null;
private ICommandHandler? _Child = null;
public char TableAsLetter { get => table_as; }
public string? CTC { get => ctc; }
public ICommandHandler? CommandHandlerParent { get => _CommandHandlerParent; }
public ICommandHandler? Child { get => _Child; }
public IBetterTable BetterTable { get => _betterTable; }
2024-03-22 12:11:19 -04:00
internal CommandHandler(IBetterTable betterTable)
{
this._betterTable = betterTable;
}
2024-03-29 11:11:14 -04:00
private CommandHandler(IBetterTable betterTable, char TableAs, ICommandHandler ch)
{
this._betterTable = betterTable;
this._CommandHandlerParent = ch;
this.table_as = TableAs;
}
internal CommandHandler<TClass> WithFilter(IBetterParameter p)
2024-03-22 12:11:19 -04:00
{
2024-03-29 11:11:14 -04:00
_Parameters.Add(p);
2024-03-22 12:11:19 -04:00
return this;
}
2024-03-29 11:11:14 -04:00
internal CommandHandler<TClass> WithValue(IBetterParameter p)
2024-03-22 12:11:19 -04:00
{
2024-03-29 11:11:14 -04:00
_Values.Add(p);
2024-03-22 12:11:19 -04:00
return this;
}
2024-03-29 11:11:14 -04:00
internal CommandHandler<TClass> WithValue(Parameter p)
2024-03-22 12:11:19 -04:00
{
2024-03-29 11:11:14 -04:00
_ValuesOld.Add(p);
return this;
2024-03-22 12:11:19 -04:00
}
2024-03-29 11:11:14 -04:00
public CommandHandler<TClass> WithFilter<T>(TableColumn<TClass, T> column, T value, string sign = "=") where T : notnull
2024-03-22 12:11:19 -04:00
{
2024-03-29 11:11:14 -04:00
return WithFilter(new BetterParameter<T>()
{
Column = column.Name,
Sign = sign,
Value = value,
});
2024-03-22 12:11:19 -04:00
}
2024-03-29 11:11:14 -04:00
public CommandHandler<TClass> WithValue<T>(TableColumn<TClass, T> column, T value) where T : notnull
{
return WithValue(new BetterParameter<T>()
{
Column = column.Name,
Sign = "=",
Value = value,
});
}
public CommandHandler<TClass> AscendBy<T>(TableColumn<TClass, T> column) where T : notnull
2024-03-22 12:11:19 -04:00
{
Order = column.GetAssendingOrder();
return this;
}
2024-03-29 11:11:14 -04:00
public CommandHandler<TClass> DescendBy<T>(TableColumn<TClass, T> column) where T : notnull
2024-03-22 12:11:19 -04:00
{
Order = column.GetDecendingOrder();
return this;
}
2024-03-29 11:11:14 -04:00
public CommandHandler<TCol> WithCrossTableCheck<TCol, T>(TableColumn<TClass, T> column1, Table<TCol> Table, TableColumn<TCol, T> column2) where TCol : class, new() where T : notnull
{
return WithCrossTableCheck(column1, "=", Table,column2);
}
public CommandHandler<TCol> WithCrossTableCheck<TCol, T>(TableColumn<TClass, T> column1, string sign, Table<TCol> Table, TableColumn<TCol, T> column2) where TCol : class, new() where T : notnull
{
ctc = $"{table_as}.{column1.Name} {sign} {(char)(table_as + 1)}.{column2.Name}";
CommandHandler<TCol> child = new CommandHandler<TCol>(Table, (char)(table_as + 1), this);
_Child = child;
return child;
}
public T Read<T>(TableColumn<TClass, T> column) where T : notnull
{
string command = $"SELECT {TableAsLetter}.{column.Name} FROM {_betterTable.Name} AS {TableAsLetter}";
ICommandHandler? pc = this;
ICommandHandler? c = this.CommandHandlerParent;
while (c is not null)
{
command += $", {c.BetterTable.Name} AS {c.TableAsLetter}";
pc = c;
c = c.CommandHandlerParent;
}
command += " WHERE";
if (string.IsNullOrEmpty(_betterTable.DatabaseHandler.DB) || string.IsNullOrEmpty(_betterTable.DatabaseHandler.IP) || string.IsNullOrEmpty(_betterTable.DatabaseHandler.Uname) || string.IsNullOrEmpty(_betterTable.DatabaseHandler.PW)) throw new Exception("Database conection not fully defined");
using NpgsqlConnection con = new(_betterTable.DatabaseHandler.ConectionString);
con.Open();
using NpgsqlCommand cmd = new();
cmd.Connection = con;
char col_char = 'A';
string vals = "";
while (pc is not null)
{
foreach (IBetterParameter param in pc.Parameters)
{
vals += $"{pc.TableAsLetter}.{param.Column} {param.Sign} @{col_char} AND ";
cmd.Parameters.Add(param.CreateParameter(col_char.ToString()));
col_char++;
}
if (pc.CTC is not null) vals += pc.CTC + " AND ";
pc = pc.Child;
}
if (!string.IsNullOrWhiteSpace(vals)) vals = vals.Remove(vals.Length - 5, 5);
if (!string.IsNullOrWhiteSpace(vals) && command.EndsWith("WHERE")) command += $" {vals}";
command += ";";
cmd.CommandText = command;
object? temp = cmd.ExecuteScalar();
con.Close();
if (temp is DBNull || temp is null) return default!;
if (typeof(T).IsEnum) return (T?)Enum.Parse(typeof(T), temp.ToString()!)!;
if (typeof(T).IsNullableEnum()) return (T?)Enum.Parse(Nullable.GetUnderlyingType(typeof(T))!, temp.ToString()!)!;
return (T?)temp!;
}
2024-03-22 12:11:19 -04:00
2024-03-29 11:11:14 -04:00
public (T, T2) Read<T, T2>(TableColumn<TClass, T> column, TableColumn<TClass, T2> column2) where T : notnull where T2 : notnull
2024-03-22 12:11:19 -04:00
{
2024-03-29 11:11:14 -04:00
string command = $"SELECT {TableAsLetter}.{column.Name}, {TableAsLetter}.{column2.Name} FROM {_betterTable.Name} AS {TableAsLetter}";
ICommandHandler? pc = this;
ICommandHandler? c = this.CommandHandlerParent;
while (c is not null)
{
command += $", {c.BetterTable.Name} AS {c.TableAsLetter}";
pc = c;
c = c.CommandHandlerParent;
}
command += " WHERE";
if (string.IsNullOrEmpty(_betterTable.DatabaseHandler.DB) || string.IsNullOrEmpty(_betterTable.DatabaseHandler.IP) || string.IsNullOrEmpty(_betterTable.DatabaseHandler.Uname) || string.IsNullOrEmpty(_betterTable.DatabaseHandler.PW)) throw new Exception("Database conection not fully defined");
using NpgsqlConnection con = new(_betterTable.DatabaseHandler.ConectionString);
con.Open();
using NpgsqlCommand cmd = new();
cmd.Connection = con;
char col_char = 'A';
string vals = "";
while (pc is not null)
{
foreach (IBetterParameter param in pc.Parameters)
{
vals += $"{pc.TableAsLetter}.{param.Column} {param.Sign} @{col_char} AND ";
cmd.Parameters.Add(param.CreateParameter(col_char.ToString()));
col_char++;
}
if (pc.CTC is not null) vals += pc.CTC + " AND ";
pc = pc.Child;
}
if (!string.IsNullOrWhiteSpace(vals)) vals = vals.Remove(vals.Length - 5, 5);
if (!string.IsNullOrWhiteSpace(vals) && command.EndsWith("WHERE")) command += $" {vals}";
command += ";";
cmd.CommandText = command;
NpgsqlDataReader reader = cmd.ExecuteReader();
reader.Read();
object?[] temp = new object[reader.FieldCount];
for (int i = 0; i < reader.FieldCount; i++)
{
string colname = reader.GetName(i);
object val = reader.GetValue(i);
if (i == 0)
{
if (typeof(T).IsEnum) temp[i] = (T?)Enum.Parse(typeof(T), val.ToString()!)!;
if (typeof(T).IsNullableEnum()) temp[i] = (T?)Enum.Parse(Nullable.GetUnderlyingType(typeof(T))!, val.ToString()!)!;
}
else if (i == 1)
{
if (typeof(T2).IsEnum) temp[i] = (T2?)Enum.Parse(typeof(T2), val.ToString()!)!;
if (typeof(T2).IsNullableEnum()) temp[i] = (T2?)Enum.Parse(Nullable.GetUnderlyingType(typeof(T2))!, val.ToString()!)!;
}
if (temp[i] is null) temp[i] = val;
}
con.Close();
return ((T)temp[0]!, (T2)temp[1]!);
2024-03-22 12:11:19 -04:00
}
2024-03-29 11:11:14 -04:00
public (T, T2, T3) Read<T, T2, T3>(TableColumn<TClass, T> column, TableColumn<TClass, T2> column2, TableColumn<TClass, T3> column3) where T : notnull where T2 : notnull where T3 : notnull
{
string command = $"SELECT {TableAsLetter}.{column.Name}, {TableAsLetter}.{column2.Name}, {TableAsLetter}.{column3.Name} FROM {_betterTable.Name} AS {TableAsLetter}";
ICommandHandler? pc = this;
ICommandHandler? c = this.CommandHandlerParent;
while (c is not null)
{
command += $", {c.BetterTable.Name} AS {c.TableAsLetter}";
pc = c;
c = c.CommandHandlerParent;
}
command += " WHERE";
if (string.IsNullOrEmpty(_betterTable.DatabaseHandler.DB) || string.IsNullOrEmpty(_betterTable.DatabaseHandler.IP) || string.IsNullOrEmpty(_betterTable.DatabaseHandler.Uname) || string.IsNullOrEmpty(_betterTable.DatabaseHandler.PW)) throw new Exception("Database conection not fully defined");
using NpgsqlConnection con = new(_betterTable.DatabaseHandler.ConectionString);
con.Open();
using NpgsqlCommand cmd = new();
cmd.Connection = con;
char col_char = 'A';
string vals = "";
while (pc is not null)
{
foreach (IBetterParameter param in pc.Parameters)
{
vals += $"{pc.TableAsLetter}.{param.Column} {param.Sign} @{col_char} AND ";
cmd.Parameters.Add(param.CreateParameter(col_char.ToString()));
col_char++;
}
2024-03-22 12:11:19 -04:00
2024-03-29 11:11:14 -04:00
if (pc.CTC is not null) vals += pc.CTC + " AND ";
pc = pc.Child;
}
if (!string.IsNullOrWhiteSpace(vals)) vals = vals.Remove(vals.Length - 5, 5);
if (!string.IsNullOrWhiteSpace(vals) && command.EndsWith("WHERE")) command += $" {vals}";
command += ";";
cmd.CommandText = command;
NpgsqlDataReader reader = cmd.ExecuteReader();
reader.Read();
object?[] temp = new object[reader.FieldCount];
for (int i = 0; i < reader.FieldCount; i++)
{
string colname = reader.GetName(i);
object val = reader.GetValue(i);
if (i == 0)
{
if (typeof(T).IsEnum) temp[i] = (T?)Enum.Parse(typeof(T), val.ToString()!)!;
if (typeof(T).IsNullableEnum()) temp[i] = (T?)Enum.Parse(Nullable.GetUnderlyingType(typeof(T))!, val.ToString()!)!;
}
else if (i == 1)
{
if (typeof(T2).IsEnum) temp[i] = (T2?)Enum.Parse(typeof(T2), val.ToString()!)!;
if (typeof(T2).IsNullableEnum()) temp[i] = (T2?)Enum.Parse(Nullable.GetUnderlyingType(typeof(T2))!, val.ToString()!)!;
}
else if (i == 2)
{
if (typeof(T3).IsEnum) temp[i] = (T3?)Enum.Parse(typeof(T3), val.ToString()!)!;
if (typeof(T3).IsNullableEnum()) temp[i] = (T3?)Enum.Parse(Nullable.GetUnderlyingType(typeof(T3))!, val.ToString()!)!;
}
if (temp[i] is null) temp[i] = val;
}
con.Close();
return ((T)temp[0]!, (T2)temp[1]!, (T3)temp[2]!);
}
public (T, T2, T3)[] ReadColumns<T, T2, T3>(TableColumn<TClass, T> column, TableColumn<TClass, T2> column2, TableColumn<TClass, T3> column3) where T : notnull where T2 : notnull where T3 : notnull
2024-03-22 12:11:19 -04:00
{
2024-03-29 11:11:14 -04:00
string command = $"SELECT {TableAsLetter}.{column.Name}, {TableAsLetter}.{column2.Name}, {TableAsLetter}.{column3.Name} FROM {_betterTable.Name} AS {TableAsLetter}";
ICommandHandler? pc = this;
ICommandHandler? c = this.CommandHandlerParent;
while (c is not null)
{
command += $", {c.BetterTable.Name} AS {c.TableAsLetter}";
pc = c;
c = c.CommandHandlerParent;
}
command += " WHERE";
if (string.IsNullOrEmpty(_betterTable.DatabaseHandler.DB) || string.IsNullOrEmpty(_betterTable.DatabaseHandler.IP) || string.IsNullOrEmpty(_betterTable.DatabaseHandler.Uname) || string.IsNullOrEmpty(_betterTable.DatabaseHandler.PW)) throw new Exception("Database conection not fully defined");
using NpgsqlConnection con = new(_betterTable.DatabaseHandler.ConectionString);
con.Open();
using NpgsqlCommand cmd = new();
cmd.Connection = con;
char col_char = 'A';
string vals = "";
while (pc is not null)
{
foreach (IBetterParameter param in pc.Parameters)
{
vals += $"{pc.TableAsLetter}.{param.Column} {param.Sign} @{col_char} AND ";
cmd.Parameters.Add(param.CreateParameter(col_char.ToString()));
col_char++;
}
if (pc.CTC is not null) vals += pc.CTC + " AND ";
pc = pc.Child;
}
if (!string.IsNullOrWhiteSpace(vals)) vals = vals.Remove(vals.Length - 5, 5);
if (!string.IsNullOrWhiteSpace(vals) && command.EndsWith("WHERE")) command += $" {vals}";
command += ";";
cmd.CommandText = command;
NpgsqlDataReader reader = cmd.ExecuteReader();
List<(T, T2, T3)> l = new();
while (reader.Read())
{
object?[] temp = new object[reader.FieldCount];
for (int i = 0; i < reader.FieldCount; i++)
{
object val = reader.GetValue(i);
if (i == 0)
{
if (typeof(T).IsEnum) temp[i] = (T?)Enum.Parse(typeof(T), val.ToString()!)!;
if (typeof(T).IsNullableEnum()) temp[i] = (T?)Enum.Parse(Nullable.GetUnderlyingType(typeof(T))!, val.ToString()!)!;
}
else if (i == 1)
{
if (typeof(T2).IsEnum) temp[i] = (T2?)Enum.Parse(typeof(T2), val.ToString()!)!;
if (typeof(T2).IsNullableEnum()) temp[i] = (T2?)Enum.Parse(Nullable.GetUnderlyingType(typeof(T2))!, val.ToString()!)!;
}
else if (i == 2)
{
if (typeof(T3).IsEnum) temp[i] = (T3?)Enum.Parse(typeof(T3), val.ToString()!)!;
if (typeof(T3).IsNullableEnum()) temp[i] = (T3?)Enum.Parse(Nullable.GetUnderlyingType(typeof(T3))!, val.ToString()!)!;
}
if (temp[i] is null) temp[i] = val;
}
l.Add(new((T)temp[0]!, (T2)temp[1]!, (T3)temp[2]!));
}
con.Close();
return l.ToArray();
2024-03-22 12:11:19 -04:00
}
2024-03-29 11:11:14 -04:00
2024-03-22 12:11:19 -04:00
public void Update()
{
2024-03-31 23:53:51 -04:00
string command = $"UPDATE {BetterTable.Name} AS {TableAsLetter} SET ";
ICommandHandler? pc = this;
ICommandHandler? c = this.CommandHandlerParent;
2024-03-22 12:11:19 -04:00
using NpgsqlConnection con = new(_betterTable.DatabaseHandler.ConectionString);
con.Open();
using NpgsqlCommand cmd = new();
cmd.Connection = con;
2024-03-31 23:53:51 -04:00
string vals = "";
char col_char = 'A';
foreach (IBetterParameter param in Values)
2024-03-22 12:11:19 -04:00
{
2024-03-31 23:53:51 -04:00
vals += $"{param.Column} = @{col_char}, ";
cmd.Parameters.Add(param.CreateParameter(col_char.ToString()));
col_char++;
2024-03-22 12:11:19 -04:00
}
2024-03-31 23:53:51 -04:00
command += vals.Remove(vals.Length - 2, 2) + " ";
string from = "";
if (c is not null) from += "FROM ";
while (c is not null)
2024-03-22 12:11:19 -04:00
{
2024-03-31 23:53:51 -04:00
from += $"{c.BetterTable.Name} AS {c.TableAsLetter}, ";
pc = c;
c = c.CommandHandlerParent;
2024-03-22 12:11:19 -04:00
}
2024-03-31 23:53:51 -04:00
if (from.Length > 0) command += from.Remove(from.Length - 2, 2);
vals = "";
while (pc is not null)
{
foreach (IBetterParameter param in pc.Parameters)
{
vals += $"{pc.TableAsLetter}.{param.Column} {param.Sign} @{col_char} AND ";
cmd.Parameters.Add(param.CreateParameter(col_char.ToString()));
col_char++;
}
if (pc.CTC is not null) vals += pc.CTC + " AND ";
pc = pc.Child;
}
if (!string.IsNullOrWhiteSpace(vals))
{
vals = vals.Remove(vals.Length - 4, 4);
command += "WHERE " + vals;
}
command = command.Remove(command.Length - 1, 1) + ";";
cmd.CommandText = command;
2024-03-22 12:11:19 -04:00
cmd.Prepare();
cmd.ExecuteNonQuery();
con.Close();
}
}