using Npgsql; using Npgsql.FSharp; using ThrowawayDb.Postgres; namespace BitBadger.Documents.Tests; /// /// A throwaway SQLite database file, which will be deleted when it goes out of scope /// public class ThrowawayPostgresDb : IDisposable, IAsyncDisposable { private readonly ThrowawayDatabase _db; /// /// The connection string for the throwaway database /// public string ConnectionString => _db.ConnectionString; /// /// Constructor /// /// The throwaway database which this instance will wrap public ThrowawayPostgresDb(ThrowawayDatabase db) { _db = db; } public void Dispose() { _db.Dispose(); GC.SuppressFinalize(this); } public ValueTask DisposeAsync() { _db.Dispose(); GC.SuppressFinalize(this); return ValueTask.CompletedTask; } } /// /// Database helpers for PostgreSQL integration tests /// public static class PostgresDb { /// /// The name of the table used for testing /// public const string TableName = "test_table"; /// /// The host for the database /// private static readonly Lazy DbHost = new(() => { return Environment.GetEnvironmentVariable("BitBadger.Documents.Postgres.DbHost") switch { null => "localhost", var host when host.Trim() == "" => "localhost", var host => host }; }); /// /// The port for the database /// private static readonly Lazy DbPort = new(() => { return Environment.GetEnvironmentVariable("BitBadger.Documents.Postgres.DbPort") switch { null => 5432, var port when port.Trim() == "" => 5432, var port => int.Parse(port) }; }); /// /// The database itself /// private static readonly Lazy DbDatabase = new(() => { return Environment.GetEnvironmentVariable("BitBadger.Documents.Postres.DbDatabase") switch { null => "postgres", var db when db.Trim() == "" => "postgres", var db => db }; }); /// /// The user to use in connecting to the database /// private static readonly Lazy DbUser = new(() => { return Environment.GetEnvironmentVariable("BitBadger.Documents.Postgres.DbUser") switch { null => "postgres", var user when user.Trim() == "" => "postgres", var user => user }; }); /// /// The password to use for the database /// private static readonly Lazy DbPassword = new(() => { return Environment.GetEnvironmentVariable("BitBadger.Documents.Postrgres.DbPwd") switch { null => "postgres", var pwd when pwd.Trim() == "" => "postgres", var pwd => pwd }; }); /// /// The overall connection string /// public static readonly Lazy ConnStr = new(() => Sql.formatConnectionString( Sql.password(DbPassword.Value, Sql.username(DbUser.Value, Sql.database(DbDatabase.Value, Sql.port(DbPort.Value, Sql.host(DbHost.Value))))))); /// /// Create a data source using the derived connection string /// public static NpgsqlDataSource MkDataSource(string cStr) => new NpgsqlDataSourceBuilder(cStr).Build(); /// /// Build the throwaway database /// public static ThrowawayPostgresDb BuildDb() { var database = ThrowawayDatabase.Create(ConnStr.Value); var sqlProps = Sql.connect(database.ConnectionString); Sql.executeNonQuery(Sql.query(Postgres.Query.Definition.EnsureTable(TableName), sqlProps)); Sql.executeNonQuery(Sql.query(Query.Definition.EnsureKey(TableName), sqlProps)); Postgres.Configuration.UseDataSource(MkDataSource(database.ConnectionString)); return new ThrowawayPostgresDb(database); } }