Files
natsnet/tools/NatsNet.PortTracker/Data/Database.cs
2026-02-27 04:38:59 -05:00

98 lines
3.0 KiB
C#

using Microsoft.Data.Sqlite;
namespace NatsNet.PortTracker.Data;
public sealed class Database : IDisposable
{
private readonly SqliteConnection _connection;
public Database(string dbPath)
{
var connectionString = new SqliteConnectionStringBuilder
{
DataSource = dbPath,
Mode = SqliteOpenMode.ReadWriteCreate,
ForeignKeys = true
}.ToString();
_connection = new SqliteConnection(connectionString);
_connection.Open();
using var cmd = _connection.CreateCommand();
cmd.CommandText = "PRAGMA journal_mode=WAL;";
cmd.ExecuteNonQuery();
}
public SqliteConnection Connection => _connection;
public SqliteCommand CreateCommand(string sql)
{
var cmd = _connection.CreateCommand();
cmd.CommandText = sql;
return cmd;
}
public int Execute(string sql, params (string name, object? value)[] parameters)
{
using var cmd = CreateCommand(sql);
foreach (var (name, value) in parameters)
cmd.Parameters.AddWithValue(name, value ?? DBNull.Value);
return cmd.ExecuteNonQuery();
}
public T? ExecuteScalar<T>(string sql, params (string name, object? value)[] parameters)
{
using var cmd = CreateCommand(sql);
foreach (var (name, value) in parameters)
cmd.Parameters.AddWithValue(name, value ?? DBNull.Value);
var result = cmd.ExecuteScalar();
if (result is null or DBNull) return default;
return (T)Convert.ChangeType(result, typeof(T));
}
public List<Dictionary<string, object?>> Query(string sql, params (string name, object? value)[] parameters)
{
using var cmd = CreateCommand(sql);
foreach (var (name, value) in parameters)
cmd.Parameters.AddWithValue(name, value ?? DBNull.Value);
var results = new List<Dictionary<string, object?>>();
using var reader = cmd.ExecuteReader();
while (reader.Read())
{
var row = new Dictionary<string, object?>();
for (int i = 0; i < reader.FieldCount; i++)
{
row[reader.GetName(i)] = reader.IsDBNull(i) ? null : reader.GetValue(i);
}
results.Add(row);
}
return results;
}
public int ExecuteInTransaction(string sql, params (string name, object? value)[] parameters)
{
using var transaction = _connection.BeginTransaction();
try
{
using var cmd = CreateCommand(sql);
cmd.Transaction = transaction;
foreach (var (name, value) in parameters)
cmd.Parameters.AddWithValue(name, value ?? DBNull.Value);
var affected = cmd.ExecuteNonQuery();
transaction.Commit();
return affected;
}
catch
{
transaction.Rollback();
throw;
}
}
public void Dispose()
{
_connection.Dispose();
}
}