664 lines
27 KiB
C#
664 lines
27 KiB
C#
using System.Data;
|
|
using System.Diagnostics.CodeAnalysis;
|
|
using System.Reflection;
|
|
using Npgsql;
|
|
using ServerDatabase.Utils;
|
|
using ServerDatabase.Utils.Enums;
|
|
|
|
namespace ServerDatabase;
|
|
|
|
public class Table<TRow> : IBetterTable where TRow : class, new()
|
|
{
|
|
public Table(string Name, Database DB)
|
|
{
|
|
if (Name == "table_versions") throw new ArgumentException("The table name 'table_versions' is not allowed", nameof(Name));
|
|
this.Name = Name;
|
|
DatabaseHandler = DB;
|
|
}
|
|
|
|
internal Table(Database DB)
|
|
{
|
|
this.Name = "table_versions";
|
|
DatabaseHandler = DB;
|
|
}
|
|
|
|
public CommandHandler<TRow> CreateCommand()
|
|
{
|
|
return new CommandHandler<TRow>(this);
|
|
}
|
|
|
|
public Table<TRow> WithColumn(ITableColumn Column, string name)
|
|
{
|
|
Colums_.Add(Column);
|
|
colnamesraw.Add(Column.Name, name);
|
|
return this;
|
|
}
|
|
|
|
public void AddColumn(ITableColumn Column, string name)
|
|
{
|
|
colnamesraw.Add(Column.Name, name);
|
|
Colums_.Add(Column);
|
|
}
|
|
|
|
public IReadOnlyList<ITableColumn> GetMissingColumns(out IReadOnlyList<ITableColumn> UpdatedColumns, out string[] ExtraColumns)
|
|
{
|
|
List<ITableColumn> coll = new(Colums_);
|
|
List<ITableColumn> col = new(Colums_);
|
|
List<string> co = new();
|
|
foreach (DataRow row in DatabaseHandler.CreateConnection().GetSchema("Columns", new[] { DatabaseHandler.DB, null, Name }).Rows)
|
|
{
|
|
string name = row.Field<string>("COLUMN_NAME")!,
|
|
ty = row.Field<string>("DATA_TYPE")!;
|
|
IEnumerable<ITableColumn> t = Colums_.Where(s => s.Name == name);
|
|
if (t.Any())
|
|
{
|
|
col.Remove(t.First());
|
|
if (t.First()!.GetDatabaseTypeStr() == ty) coll.Remove(t.First());
|
|
}
|
|
else
|
|
{
|
|
co.Add(name);
|
|
}
|
|
}
|
|
|
|
UpdatedColumns = coll;
|
|
ExtraColumns = co.ToArray();
|
|
return col.AsReadOnly();
|
|
}
|
|
|
|
public void UpdateTable()
|
|
{
|
|
Console.WriteLine("Verifying Table: {0}", Name);
|
|
bool i = true;
|
|
IReadOnlyList<ITableColumn> m = GetMissingColumns(out IReadOnlyList<ITableColumn> n, out string[] o);
|
|
if (m.Any())
|
|
{
|
|
if (i)
|
|
{
|
|
i = false;
|
|
Console.WriteLine("Fixing Table: {0}", Name);
|
|
}
|
|
if (DatabaseHandler.Read<long>(
|
|
$"SELECT COUNT(table_name) FROM information_schema.tables WHERE table_schema LIKE 'public' AND table_type LIKE 'BASE TABLE' AND table_name = '{Name}';") ==
|
|
0)
|
|
{
|
|
Create();
|
|
}
|
|
else
|
|
{
|
|
foreach (ITableColumn col in m)
|
|
{
|
|
try
|
|
{
|
|
if (col.IsPrimaryKey) throw new Exception($"DELETE THE TABLE '{Name}' TO FIX TABLE GENERATION");
|
|
string sql = $"ALTER TABLE IF EXISTS public.{Name} ADD COLUMN {col.Name} {col.GetDatabaseTypeStr()}";
|
|
sql += " NOT NULL";
|
|
if (col.GetDefaultStr() is not null) sql += $" DEFAULT {col.GetDefaultStr()}";
|
|
sql += ";";
|
|
DatabaseHandler.ExecuteNonQuery(sql);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Console.WriteLine("Posible fail to set default for public.{0}.{1}", Name, col.Name);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (n.Any())
|
|
{
|
|
if (i)
|
|
{
|
|
i = false;
|
|
Console.WriteLine("Fixing Table: {0}", Name);
|
|
}
|
|
foreach (ITableColumn col in n)
|
|
{
|
|
string sql = $"ALTER TABLE public.{Name} ALTER COLUMN {col.Name} TYPE {col.GetDatabaseTypeStr()};";
|
|
|
|
DatabaseHandler.ExecuteNonQuery(sql);
|
|
if (col.GetDefaultStr() is not null)
|
|
{
|
|
try
|
|
{
|
|
sql = $"ALTER TABLE IF EXISTS public.{Name} ALTER COLUMN {col.Name} SET DEFAULT {col.GetDefaultStr()};";
|
|
DatabaseHandler.ExecuteNonQuery(sql);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Console.WriteLine("Failed to set default for public.{0}.{1}\nSQL: {2}", Name, col.Name, sql);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (o.Any())
|
|
{
|
|
if (i)
|
|
{
|
|
i = false;
|
|
Console.WriteLine("Fixing Table: {0}", Name);
|
|
}
|
|
foreach (string c in o)
|
|
{
|
|
DatabaseHandler.ExecuteNonQuery($"ALTER TABLE IF EXISTS {Name} DROP COLUMN IF EXISTS {c};");
|
|
}
|
|
}
|
|
}
|
|
|
|
public Table<TRow> DropColumn<TType>(TableColumn<TRow, TType> Column) where TType : notnull
|
|
{
|
|
Colums_.Remove(Column);
|
|
return this;
|
|
}
|
|
|
|
private Dictionary<string, string> colnamesraw = new();
|
|
|
|
private List<ITableColumn> Colums_ { get; set; } = new();
|
|
|
|
public IReadOnlyList<ITableColumn> Colums => Colums_.AsReadOnly();
|
|
|
|
public string Name { get; set; } = default!;
|
|
|
|
public Database DatabaseHandler { get; set; } = default!;
|
|
|
|
public void Insert(params Parameter[] Parameters)
|
|
{
|
|
if (string.IsNullOrEmpty(DatabaseHandler.DB) || string.IsNullOrEmpty(DatabaseHandler.IP) || string.IsNullOrEmpty(DatabaseHandler.Uname) || string.IsNullOrEmpty(DatabaseHandler.PW)) throw new Exception("Database conection not fully defined");
|
|
using NpgsqlConnection con = new(DatabaseHandler.ConectionString);
|
|
con.Open();
|
|
using NpgsqlCommand cmd = new();
|
|
cmd.Connection = con;
|
|
string vals = "";
|
|
List<ITableColumn> l = new List<ITableColumn>(Colums_);
|
|
foreach (Parameter param in Parameters)
|
|
{
|
|
l.Remove(l.Where(s => s.Name == param.PGParameter.ParameterName).First());
|
|
vals += "@" + param.PGParameter.ParameterName + ", ";
|
|
cmd.Parameters.Add(param.PGParameter);
|
|
}
|
|
|
|
foreach (ITableColumn cop in l)
|
|
{
|
|
var param = cop.CreateDefaultParameter();
|
|
vals += "@" + param.PGParameter.ParameterName + ", ";
|
|
cmd.Parameters.Add(param.PGParameter);
|
|
}
|
|
vals = vals.Remove(vals.Length - 2, 2);
|
|
cmd.CommandText = $"INSERT INTO {Name} ({vals.Replace("@", "")}) VALUES({vals})";
|
|
cmd.Prepare();
|
|
cmd.ExecuteNonQuery();
|
|
con.Close();
|
|
}
|
|
|
|
public void DeleteRow(Parameter Parameter)
|
|
{
|
|
if (string.IsNullOrEmpty(DatabaseHandler.DB) || string.IsNullOrEmpty(DatabaseHandler.IP) || string.IsNullOrEmpty(DatabaseHandler.Uname) || string.IsNullOrEmpty(DatabaseHandler.PW)) throw new Exception("Database conection not fully defined");
|
|
using NpgsqlConnection con = new(DatabaseHandler.ConectionString);
|
|
con.Open();
|
|
using NpgsqlCommand cmd = new();
|
|
cmd.Connection = con;
|
|
cmd.Parameters.Add(Parameter.PGParameter);
|
|
cmd.CommandText = $"DELETE FROM {Name} WHERE {Parameter.PGParameter.ParameterName} IN (@{Parameter.PGParameter.ParameterName});";
|
|
cmd.Prepare();
|
|
cmd.ExecuteNonQuery();
|
|
con.Close();
|
|
}
|
|
|
|
public void DeleteRows()
|
|
{
|
|
if (string.IsNullOrEmpty(DatabaseHandler.DB) || string.IsNullOrEmpty(DatabaseHandler.IP) || string.IsNullOrEmpty(DatabaseHandler.Uname) || string.IsNullOrEmpty(DatabaseHandler.PW)) throw new Exception("Database conection not fully defined");
|
|
using NpgsqlConnection con = new(DatabaseHandler.ConectionString);
|
|
con.Open();
|
|
using NpgsqlCommand cmd = new();
|
|
cmd.Connection = con;
|
|
cmd.CommandText = $"DELETE FROM {Name};";
|
|
cmd.Prepare();
|
|
cmd.ExecuteNonQuery();
|
|
con.Close();
|
|
}
|
|
|
|
public void Create()
|
|
{
|
|
Console.WriteLine("Making Table: {0}", Name);
|
|
if (string.IsNullOrEmpty(DatabaseHandler.DB) || string.IsNullOrEmpty(DatabaseHandler.IP) || string.IsNullOrEmpty(DatabaseHandler.Uname) || string.IsNullOrEmpty(DatabaseHandler.PW)) throw new Exception("Database conection not fully defined");
|
|
using NpgsqlConnection con = new(DatabaseHandler.ConectionString);
|
|
con.Open();
|
|
using NpgsqlCommand cmd = new();
|
|
cmd.Connection = con;
|
|
string command = $"CREATE TABLE IF NOT EXISTS public.{Name}(";
|
|
List<string> Keys = new();
|
|
|
|
List<Tuple<ITableColumn, IForeignKey>> FKeys = new();
|
|
foreach (ITableColumn column in Colums_)
|
|
{
|
|
command += $"{column.Name} {column.GetDatabaseTypeStr()}";
|
|
if (column.IsPrimaryKey) Keys.Add(column.Name);
|
|
command += " NOT NULL, ";
|
|
if (column.ForeignKeys.Length > 0)
|
|
{
|
|
foreach (IForeignKey Fkey in column.ForeignKeys)
|
|
{
|
|
FKeys.Add(new(column, Fkey));
|
|
}
|
|
}
|
|
}
|
|
|
|
if (Keys.Count > 0)
|
|
{
|
|
string key = $"CONSTRAINT {Name}_pkey PRIMARY KEY (";
|
|
foreach (var Key in Keys)
|
|
{
|
|
key += Key + ", ";
|
|
}
|
|
|
|
key = key.Remove(key.Length - 2, 2);
|
|
key += "), ";
|
|
command += key;
|
|
}
|
|
|
|
if (FKeys.Count > 0)
|
|
{
|
|
foreach (Tuple<ITableColumn, IForeignKey> K in FKeys)
|
|
{
|
|
string key = $"CONSTRAINT {Name}_{K.Item1.Name}_{K.Item2.Table.Name}_{K.Item2.Column.Name}_fkey FOREIGN KEY ({K.Item1.Name}) REFERENCES public.{K.Item2.Table.Name} ({K.Item2.Column.Name}) MATCH ";
|
|
if (K.Item2.MatchType == KeyMatchType.Full) key += "FULL ON UPDATE ";
|
|
else key += "SIMPLE ON UPDATE ";
|
|
switch (K.Item2.OnUpdate)
|
|
{
|
|
case ConstraintAction.None:
|
|
key += "NO ACTION ON DELETE ";
|
|
break;
|
|
case ConstraintAction.Cascade:
|
|
key += "CASCADE ON DELETE ";
|
|
break;
|
|
case ConstraintAction.Restrict:
|
|
key += "RESTRICT ON DELETE ";
|
|
break;
|
|
case ConstraintAction.SetDefault:
|
|
key += "SET DEFAULT ON DELETE ";
|
|
break;
|
|
}
|
|
switch (K.Item2.OnDelete)
|
|
{
|
|
case ConstraintAction.None:
|
|
key += "NO ACTION ";
|
|
break;
|
|
case ConstraintAction.Cascade:
|
|
key += "CASCADE ";
|
|
break;
|
|
case ConstraintAction.Restrict:
|
|
key += "RESTRICT ";
|
|
break;
|
|
case ConstraintAction.SetDefault:
|
|
key += "SET DEFAULT ";
|
|
break;
|
|
}
|
|
|
|
if (K.Item2.Deferrable) key += "DEFERRABLE ";
|
|
if (K.Item2.Deferred) key += "INITIALLY DEFERRED ";
|
|
if (!K.Item2.Validated) key += "NOT VALID ";
|
|
key = key.Remove(key.Length - 1, 1) + ", ";
|
|
command += key;
|
|
}
|
|
}
|
|
|
|
command = command.Remove(command.Length - 2, 2);
|
|
|
|
command += ");";
|
|
cmd.CommandText = command;
|
|
cmd.Prepare();
|
|
cmd.ExecuteNonQuery();
|
|
con.Close();
|
|
DatabaseHandler.ExecuteNonQuery($"ALTER TABLE IF EXISTS public.{Name} OWNER to \"{DatabaseHandler.Uname}\";");
|
|
}
|
|
|
|
public bool TryRead<T>(TableColumn<TRow, T> column, Order order, [NotNullWhen(true)]out T? result, params Parameter[] Parameters) where T : notnull
|
|
{
|
|
if (string.IsNullOrEmpty(DatabaseHandler.DB) || string.IsNullOrEmpty(DatabaseHandler.IP) || string.IsNullOrEmpty(DatabaseHandler.Uname) || string.IsNullOrEmpty(DatabaseHandler.PW)) throw new Exception("Database conection not fully defined");
|
|
using NpgsqlConnection con = new(DatabaseHandler.ConectionString);
|
|
con.Open();
|
|
using NpgsqlCommand cmd = new();
|
|
cmd.Connection = con;
|
|
string vals = "";
|
|
string command = $"SELECT {column.Name} FROM {Name} WHERE";
|
|
foreach (Parameter param in Parameters)
|
|
{
|
|
vals += $"{param.PGParameter.ParameterName} {param.Sign} @{param.PGParameter.ParameterName} AND ";
|
|
cmd.Parameters.Add(param.PGParameter);
|
|
}
|
|
if (command.EndsWith(";")) command = command.Remove(command.Length - 1, 1);
|
|
if (!string.IsNullOrWhiteSpace(vals)) vals = vals.Remove(vals.Length - 5, 5);
|
|
if (!string.IsNullOrWhiteSpace(vals) && command.EndsWith("WHERE")) command += $" {vals}";
|
|
if (order is not null) command += $" ORDER BY {order.Type} ";
|
|
if (order is not null && order.Assending) command += "ASC";
|
|
else { if (order is not null) command += "DESC"; }
|
|
command += ";";
|
|
cmd.CommandText = command;
|
|
//object? temp = cmd.ExecuteScalar();
|
|
object? temp = null;
|
|
try
|
|
{
|
|
temp = cmd.ExecuteScalar();
|
|
}
|
|
catch
|
|
{
|
|
result = default(T);
|
|
return false;
|
|
}
|
|
con.Close();
|
|
if (temp is DBNull || temp is null)
|
|
{
|
|
result = default(T);
|
|
return false;
|
|
}
|
|
|
|
if (typeof(T).IsEnum)
|
|
{
|
|
result = (T)Enum.Parse(typeof(T), temp.ToString()!)!;
|
|
return true;
|
|
}
|
|
/*
|
|
if (typeof(T).IsNullableEnum())
|
|
{
|
|
result = (T?)Enum.Parse(Nullable.GetUnderlyingType(typeof(T))!, temp.ToString()!)!;
|
|
return true;
|
|
}
|
|
*/
|
|
result = (T)temp!;
|
|
return true;
|
|
}
|
|
|
|
public bool TryReadRow(out TRow row, params Parameter[] Parameters) => TryReadRow(null, out row, Parameters);
|
|
|
|
public bool TryReadRow(Order order, out TRow row, params Parameter[] Parameters)
|
|
{
|
|
if (string.IsNullOrEmpty(DatabaseHandler.DB) || string.IsNullOrEmpty(DatabaseHandler.IP) || string.IsNullOrEmpty(DatabaseHandler.Uname) || string.IsNullOrEmpty(DatabaseHandler.PW)) throw new Exception("Database conection not fully defined");
|
|
using NpgsqlConnection con = new(DatabaseHandler.ConectionString);
|
|
string command = $"SELECT * FROM {Name} WHERE";
|
|
con.Open();
|
|
using NpgsqlCommand cmd = new();
|
|
cmd.Connection = con;
|
|
string vals = "";
|
|
foreach (Parameter param in Parameters)
|
|
{
|
|
vals += $"{param.PGParameter.ParameterName} {param.Sign} @{param.PGParameter.ParameterName} AND ";
|
|
cmd.Parameters.Add(param.PGParameter);
|
|
}
|
|
if (command.EndsWith(";")) command = command.Remove(command.Length - 1, 1);
|
|
if (!string.IsNullOrWhiteSpace(vals)) vals = vals.Remove(vals.Length - 5, 5);
|
|
if (!string.IsNullOrWhiteSpace(vals) && command.EndsWith("WHERE")) command += $" {vals}";
|
|
if (order is not null) command += $" ORDER BY {order.Type} ";
|
|
if (order is not null && order.Assending) command += "ASC";
|
|
else { if (order is not null) command += "DESC"; }
|
|
command += ";";
|
|
cmd.CommandText = command;
|
|
NpgsqlDataReader reader = cmd.ExecuteReader();
|
|
TRow Row = new();
|
|
reader.Read();
|
|
bool r = false;
|
|
for (int i = 0; i < reader.FieldCount; i++)
|
|
{
|
|
r = true;
|
|
string colname = reader.GetName(i);
|
|
object? val = null;
|
|
try
|
|
{
|
|
val = reader.GetValue(i);
|
|
}
|
|
catch
|
|
{
|
|
row = default(TRow);
|
|
return false;
|
|
}
|
|
|
|
if (colnamesraw.ContainsKey(colname))
|
|
{
|
|
if (val is DBNull || val is null)
|
|
{
|
|
row = default(TRow);
|
|
return false;
|
|
}
|
|
PropertyInfo? pi = Row.GetType()
|
|
.GetProperty(colnamesraw[colname]);
|
|
if (pi is null)
|
|
{
|
|
Console.WriteLine("Could not find row {0}", colnamesraw[colname]);
|
|
continue;
|
|
}
|
|
pi.SetValue(Row, val, null);
|
|
}
|
|
}
|
|
|
|
row = Row;
|
|
return r;
|
|
}
|
|
|
|
public bool TryReadRows([NotNullWhen(true)]out TRow[]? rows, params Parameter[] Parameters) => TryReadRows(null!, out rows, Parameters);
|
|
|
|
public bool TryReadRows(Order order, [NotNullWhen(true)]out TRow[]? rows, params Parameter[] Parameters)
|
|
{
|
|
if (string.IsNullOrEmpty(DatabaseHandler.DB) || string.IsNullOrEmpty(DatabaseHandler.IP) || string.IsNullOrEmpty(DatabaseHandler.Uname) || string.IsNullOrEmpty(DatabaseHandler.PW)) throw new Exception("Database conection not fully defined");
|
|
using NpgsqlConnection con = new(DatabaseHandler.ConectionString);
|
|
string command = $"SELECT * FROM {Name} WHERE";
|
|
con.Open();
|
|
using NpgsqlCommand cmd = new();
|
|
cmd.Connection = con;
|
|
string vals = "";
|
|
foreach (Parameter param in Parameters)
|
|
{
|
|
vals += $"{param.PGParameter.ParameterName} {param.Sign} @{param.PGParameter.ParameterName} AND ";
|
|
cmd.Parameters.Add(param.PGParameter);
|
|
}
|
|
if (command.EndsWith(";")) command = command.Remove(command.Length - 1, 1);
|
|
if (!string.IsNullOrWhiteSpace(vals)) vals = vals.Remove(vals.Length - 5, 5);
|
|
if (!string.IsNullOrWhiteSpace(vals) && command.EndsWith("WHERE")) command += $" {vals}";
|
|
if (order is not null) command += $" ORDER BY {order.Type} ";
|
|
if (order is not null && order.Assending) command += "ASC";
|
|
else { if (order is not null) command += "DESC"; }
|
|
command += ";";
|
|
cmd.CommandText = command;
|
|
NpgsqlDataReader reader = cmd.ExecuteReader();
|
|
List<TRow> Rows = new();
|
|
while (reader.Read())
|
|
{
|
|
TRow Row = new();
|
|
for (int i = 0; i < reader.FieldCount; i++)
|
|
{
|
|
string colname = reader.GetName(i);
|
|
object? val = reader.GetValue(i);
|
|
if (colnamesraw.ContainsKey(colname))
|
|
{
|
|
PropertyInfo? pi = Row.GetType()
|
|
.GetProperty(colnamesraw[colname]);
|
|
if (pi is null)
|
|
{
|
|
Console.WriteLine("Could not find row {0}", colnamesraw[colname]);
|
|
continue;
|
|
}
|
|
pi.SetValue(Row, val, null);
|
|
}
|
|
}
|
|
Rows.Add(Row);
|
|
}
|
|
|
|
rows = Rows.ToArray();
|
|
return Rows.Any();
|
|
}
|
|
|
|
public bool TryRead<T>(TableColumn<TRow, T> column, [NotNullWhen(true)]out T? result, params Parameter[] Parameters) where T : notnull
|
|
{
|
|
return TryRead(column, null!, out result, Parameters);
|
|
}
|
|
|
|
public void Update<Ttype>(TableColumn<TRow, Ttype> condiction_column, Ttype condiction_value, params Parameter[] Parameters) where Ttype : notnull
|
|
{
|
|
Update(condiction_column, condiction_value, "=", Parameters);
|
|
}
|
|
|
|
public void Update<Ttype>(TableColumn<TRow, Ttype> condiction_column, Ttype condiction_value, string Sign, params Parameter[] Parameters) where Ttype : notnull
|
|
{
|
|
CommandHandler<TRow> tableCommand = CreateCommand().WithFilter(condiction_column, condiction_value, Sign);
|
|
foreach (var Parameter in Parameters)
|
|
{
|
|
tableCommand.WithValue(Parameter);
|
|
}
|
|
tableCommand.Update();
|
|
}
|
|
|
|
public TRow ReadRow(params Parameter[] Parameters) => ReadRow(null, Parameters);
|
|
|
|
public TRow ReadRow(Order order, params Parameter[] Parameters)
|
|
{
|
|
if (string.IsNullOrEmpty(DatabaseHandler.DB) || string.IsNullOrEmpty(DatabaseHandler.IP) || string.IsNullOrEmpty(DatabaseHandler.Uname) || string.IsNullOrEmpty(DatabaseHandler.PW)) throw new Exception("Database conection not fully defined");
|
|
using NpgsqlConnection con = new(DatabaseHandler.ConectionString);
|
|
string command = $"SELECT * FROM {Name} WHERE";
|
|
con.Open();
|
|
using NpgsqlCommand cmd = new();
|
|
cmd.Connection = con;
|
|
string vals = "";
|
|
foreach (Parameter param in Parameters)
|
|
{
|
|
vals += $"{param.PGParameter.ParameterName} {param.Sign} @{param.PGParameter.ParameterName} AND ";
|
|
cmd.Parameters.Add(param.PGParameter);
|
|
}
|
|
if (command.EndsWith(";")) command = command.Remove(command.Length - 1, 1);
|
|
if (!string.IsNullOrWhiteSpace(vals)) vals = vals.Remove(vals.Length - 5, 5);
|
|
if (!string.IsNullOrWhiteSpace(vals) && command.EndsWith("WHERE")) command += $" {vals}";
|
|
if (order is not null) command += $" ORDER BY {order.Type} ";
|
|
if (order is not null && order.Assending) command += "ASC";
|
|
else { if (order is not null) command += "DESC"; }
|
|
command += ";";
|
|
cmd.CommandText = command;
|
|
NpgsqlDataReader reader = cmd.ExecuteReader();
|
|
TRow Row = new();
|
|
reader.Read();
|
|
for (int i = 0; i < reader.FieldCount; i++)
|
|
{
|
|
string colname = reader.GetName(i);
|
|
object? val = reader.GetValue(i);
|
|
if (colnamesraw.ContainsKey(colname))
|
|
{
|
|
PropertyInfo? pi = Row.GetType()
|
|
.GetProperty(colnamesraw[colname]);
|
|
if (pi is null)
|
|
{
|
|
Console.WriteLine("Could not find row {0}", colnamesraw[colname]);
|
|
continue;
|
|
}
|
|
pi.SetValue(Row, val, null);
|
|
}
|
|
}
|
|
|
|
return Row;
|
|
}
|
|
|
|
public TColumn[] ReadColumn<TColumn>(TableColumn<TRow, TColumn> column, params Parameter[] Parameters) where TColumn : notnull => ReadColumn(column, uint.MaxValue, null, Parameters);
|
|
|
|
public TColumn[] ReadColumn<TColumn>(TableColumn<TRow, TColumn> column, uint NumRows, params Parameter[] Parameters) where TColumn : notnull => ReadColumn(column, NumRows, null, Parameters);
|
|
|
|
public TColumn[] ReadColumn<TColumn>(TableColumn<TRow, TColumn> column, Order? Order, params Parameter[] Parameters) where TColumn : notnull => ReadColumn(column, uint.MaxValue, Order, Parameters);
|
|
|
|
public TColumn[] ReadColumn<TColumn>(TableColumn<TRow, TColumn> column, uint NumRows, Order? order, params Parameter[] Parameters) where TColumn : notnull
|
|
{
|
|
if (string.IsNullOrEmpty(DatabaseHandler.DB) || string.IsNullOrEmpty(DatabaseHandler.IP) || string.IsNullOrEmpty(DatabaseHandler.Uname) || string.IsNullOrEmpty(DatabaseHandler.PW)) throw new Exception("Database conection not fully defined");
|
|
using NpgsqlConnection con = new(DatabaseHandler.ConectionString);
|
|
string command = $"SELECT {column.Name} FROM {Name} WHERE";
|
|
con.Open();
|
|
using NpgsqlCommand cmd = new();
|
|
cmd.Connection = con;
|
|
string vals = "";
|
|
foreach (Parameter param in Parameters)
|
|
{
|
|
vals += $"{param.PGParameter.ParameterName} {param.Sign} @{param.PGParameter.ParameterName} AND ";
|
|
cmd.Parameters.Add(param.PGParameter);
|
|
}
|
|
if (command.EndsWith(";")) command = command.Remove(command.Length - 1, 1);
|
|
if (!string.IsNullOrWhiteSpace(vals)) vals = vals.Remove(vals.Length - 5, 5);
|
|
if (!string.IsNullOrWhiteSpace(vals) && command.EndsWith("WHERE")) command += $" {vals}";
|
|
if (command.EndsWith("WHERE")) command = command.Remove(command.Length - 6, 6);
|
|
if (order is not null) command += $" ORDER BY {order.Type} ";
|
|
if (order is not null && order.Assending) command += "ASC";
|
|
else { if (order is not null) command += "DESC"; }
|
|
command += $" LIMIT {NumRows};";
|
|
cmd.CommandText = command;
|
|
NpgsqlDataReader reader = cmd.ExecuteReader();
|
|
List<TColumn> Rows = new();
|
|
for (int j = 0; j < NumRows; j++)
|
|
{
|
|
if (!reader.Read()) break;
|
|
Rows.Add((TColumn)reader.GetValue(0));
|
|
}
|
|
|
|
return Rows.ToArray();
|
|
}
|
|
|
|
public TRow[] ReadRows(params Parameter[] Parameters) => ReadRows(uint.MaxValue, null, Parameters);
|
|
|
|
public TRow[] ReadRows(uint NumRows, params Parameter[] Parameters) => ReadRows(NumRows, null, Parameters);
|
|
|
|
public TRow[] ReadRows(Order? Order, params Parameter[] Parameters) => ReadRows(uint.MaxValue, Order, Parameters);
|
|
|
|
public TRow[] ReadRows(uint NumRows, Order? order, params Parameter[] Parameters)
|
|
{
|
|
if (string.IsNullOrEmpty(DatabaseHandler.DB) || string.IsNullOrEmpty(DatabaseHandler.IP) || string.IsNullOrEmpty(DatabaseHandler.Uname) || string.IsNullOrEmpty(DatabaseHandler.PW)) throw new Exception("Database conection not fully defined");
|
|
using NpgsqlConnection con = new(DatabaseHandler.ConectionString);
|
|
string command = $"SELECT * FROM {Name} WHERE";
|
|
con.Open();
|
|
using NpgsqlCommand cmd = new();
|
|
cmd.Connection = con;
|
|
string vals = "";
|
|
foreach (Parameter param in Parameters)
|
|
{
|
|
vals += $"{param.PGParameter.ParameterName} {param.Sign} @{param.PGParameter.ParameterName} AND ";
|
|
cmd.Parameters.Add(param.PGParameter);
|
|
}
|
|
if (command.EndsWith(";")) command = command.Remove(command.Length - 1, 1);
|
|
if (!string.IsNullOrWhiteSpace(vals)) vals = vals.Remove(vals.Length - 5, 5);
|
|
if (!string.IsNullOrWhiteSpace(vals) && command.EndsWith("WHERE")) command += $" {vals}";
|
|
if (command.EndsWith("WHERE")) command = command.Remove(command.Length - 6, 6);
|
|
if (order is not null) command += $" ORDER BY {order.Type} ";
|
|
if (order is not null && order.Assending) command += "ASC";
|
|
else { if (order is not null) command += "DESC"; }
|
|
command += $" LIMIT {NumRows};";
|
|
cmd.CommandText = command;
|
|
NpgsqlDataReader reader = cmd.ExecuteReader();
|
|
List<TRow> Rows = new();
|
|
for (int j = 0; j < NumRows; j++)
|
|
{
|
|
if (!reader.Read()) break;
|
|
TRow Row = new();
|
|
for (int i = 0; i < reader.FieldCount; i++)
|
|
{
|
|
string colname = reader.GetName(i);
|
|
object? val = reader.GetValue(i);
|
|
if (colnamesraw.ContainsKey(colname))
|
|
{
|
|
PropertyInfo? pi = Row.GetType()
|
|
.GetProperty(colnamesraw[colname]);
|
|
if (pi is null)
|
|
{
|
|
Console.WriteLine("Could not find row {0}", colnamesraw[colname]);
|
|
continue;
|
|
}
|
|
pi.SetValue(Row, val, null);
|
|
}
|
|
}
|
|
Rows.Add(Row);
|
|
}
|
|
|
|
return Rows.ToArray();
|
|
}
|
|
|
|
public T Read<T>(TableColumn<TRow, T> column, params Parameter[] Parameters) where T : notnull
|
|
{
|
|
if (Parameters is null) throw new ArgumentNullException(nameof(Parameters));
|
|
return DatabaseHandler.Read<T>($"SELECT {column.Name} FROM {Name} WHERE", (Order?)null, Parameters);
|
|
}
|
|
|
|
public T Read<T>(TableColumn<TRow, T> column, Order order, params Parameter[] Parameters) where T : notnull
|
|
{
|
|
if (Parameters is null) throw new ArgumentNullException(nameof(Parameters));
|
|
return DatabaseHandler.Read<T>($"SELECT {column.Name} FROM {Name} WHERE", order, Parameters);
|
|
}
|
|
} |