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);
}
}