using HermesSocketServer; using Npgsql; namespace HermesSocketLibrary.db { public class Database { private readonly NpgsqlDataSource _source; public NpgsqlDataSource DataSource { get => _source; } public Database(ServerConfiguration configuration) { NpgsqlDataSourceBuilder builder = new NpgsqlDataSourceBuilder(configuration.Database.ConnectionString); _source = builder.Build(); } public async Task Execute(string sql, IDictionary? values, Action reading) { await using var connection = await _source.OpenConnectionAsync(); await using var command = new NpgsqlCommand(sql, connection); if (values != null) { foreach (var entry in values) command.Parameters.AddWithValue(entry.Key, entry.Value); } await command.PrepareAsync(); await using var reader = await command.ExecuteReaderAsync(); while (await reader.ReadAsync()) { reading(reader); } } public async Task Execute(string sql, Action action, Action reading) { await using var connection = await _source.OpenConnectionAsync(); await using var command = new NpgsqlCommand(sql, connection); action(command); await command.PrepareAsync(); await using var reader = await command.ExecuteReaderAsync(); while (await reader.ReadAsync()) { reading(reader); } } public async Task Execute(string sql, IDictionary? values) { await using var connection = await _source.OpenConnectionAsync(); await using var command = new NpgsqlCommand(sql, connection); if (values != null) { foreach (var entry in values) command.Parameters.AddWithValue(entry.Key, entry.Value); } await command.PrepareAsync(); return await command.ExecuteNonQueryAsync(); } public async Task Execute(string sql, Action prepare) { await using var connection = await _source.OpenConnectionAsync(); await using var command = new NpgsqlCommand(sql, connection); prepare(command); await command.PrepareAsync(); return await command.ExecuteNonQueryAsync(); } public async Task ExecuteTransaction(string sql, Action prepare) { await using var connection = await _source.OpenConnectionAsync(); await using var transaction = await connection.BeginTransactionAsync(); await using var command = new NpgsqlCommand(sql, connection, transaction); prepare(command); await command.PrepareAsync(); var results = await command.ExecuteNonQueryAsync(); await transaction.CommitAsync(); return results; } public async Task ExecuteScalar(string sql, IDictionary? values = null) { await using var connection = await _source.OpenConnectionAsync(); await using var command = new NpgsqlCommand(sql, connection); if (values != null) { foreach (var entry in values) command.Parameters.AddWithValue(entry.Key, entry.Value); } await command.PrepareAsync(); return await command.ExecuteScalarAsync(); } public async Task ExecuteScalarTransaction(string sql, IDictionary? values = null) { await using var connection = await _source.OpenConnectionAsync(); await using var transaction = await connection.BeginTransactionAsync(); await using var command = new NpgsqlCommand(sql, connection, transaction); if (values != null) { foreach (var entry in values) command.Parameters.AddWithValue(entry.Key, entry.Value); } await command.PrepareAsync(); var results = await command.ExecuteScalarAsync(); await transaction.CommitAsync(); return results; } public async Task ExecuteScalar(string sql, Action action) { await using var connection = await _source.OpenConnectionAsync(); await using var command = new NpgsqlCommand(sql, connection); action(command); await command.PrepareAsync(); return await command.ExecuteScalarAsync(); } } }