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 ( )
{
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 connection not fully defined" ) ;
using NpgsqlConnection con = new ( _betterTable . DatabaseHandler . ConectionString ) ;
con . Open ( ) ;
using NpgsqlCommand cmd = new ( ) ;
cmd . Connection = con ;
string values = "" ;
2024-03-29 11:11:14 -04:00
foreach ( Parameter param in _ValuesOld )
2024-03-22 12:11:19 -04:00
{
values + = $"{param.PGParameter.ParameterName} {param.Sign} @{param.PGParameter.ParameterName}, " ;
cmd . Parameters . Add ( param . PGParameter ) ;
}
values = values . Remove ( values . Length - 2 , 2 ) ;
string fils = "" ;
2024-03-29 11:11:14 -04:00
foreach ( Parameter param in _ParametersOld )
2024-03-22 12:11:19 -04:00
{
fils + = $"{param.PGParameter.ParameterName} {param.Sign} @{param.PGParameter.ParameterName} AND" ;
cmd . Parameters . Add ( param . PGParameter ) ;
}
fils = fils . Remove ( fils . Length - 4 , 4 ) ;
cmd . CommandText = $"UPDATE {_betterTable.Name} SET {values} WHERE {fils};" ;
cmd . Prepare ( ) ;
cmd . ExecuteNonQuery ( ) ;
con . Close ( ) ;
}
}