Files
ActivityPubD/source/db/db.d
2024-02-23 13:24:03 -03:00

135 lines
2.8 KiB
D

module db.db;
import std.json;
import slf4d;
import ddbc.core;
import hibernated.core;
import db.types;
enum DBConnector {
Mysql,
Postgres,
Sqlite,
}
struct DBSettings {
DBConnector connector;
string host;
ushort port;
string username;
string password;
string dbname;
static DBSettings fromJson(JSONValue cfg) {
DBSettings settings;
with (settings) {
dbname = cfg["dbName"].str;
switch (cfg["connector"].str) {
case "postgresql":
connector = DBConnector.Postgres;
break;
case "sqlite":
connector = DBConnector.Sqlite;
break;
default:
throw new Exception("Database connector `" ~ cfg["connector"].str ~ "` not supported");
}
if ("host" in cfg)
host = cfg["host"].str;
if ("port" in cfg)
port = cast(ushort) cfg["port"].integer;
if ("username" in cfg)
username = cfg["username"].str;
if ("password" in cfg)
username = cfg["password"].str;
}
return settings;
}
}
class Database {
protected DBSettings m_settings;
protected EntityMetaData m_schema;
protected DataSource m_ds;
protected SessionFactory m_factory;
protected Session m_session;
this(DBSettings settings) {
this.m_settings = settings;
this.m_schema = new SchemaInfoImpl!(User);
}
void connect() {
Driver driver;
string url;
string[string] params;
Dialect dialect;
switch (this.m_settings.connector) {
case DBConnector.Postgres:
debugF!"Using PGSQL driver";
import ddbc.drivers.pgsqlddbc;
driver = new PGSQLDriver();
with (this.m_settings) {
url = PGSQLDriver.generateUrl(host, port, dbname);
params = PGSQLDriver.setUserAndPassword(username, password);
}
dialect = new PGSQLDialect();
break;
case DBConnector.Sqlite:
debugF!"Using SQLite driver";
import ddbc.drivers.sqliteddbc;
driver = new SQLITEDriver();
url = this.m_settings.dbname;
static import std.file;
if (std.file.exists(url))
std.file.remove(url);
dialect = new SQLiteDialect();
break;
default:
throw new Exception("Database connector not supported (yet)");
}
debugF!"Connecting to DB with URL: %s"(url);
this.m_ds = new ConnectionPoolDataSourceImpl(driver, url, params);
this.m_factory = new SessionFactoryImpl(this.m_schema, dialect, this.m_ds);
{ // Create schema if necessary
Connection conn = this.m_ds.getConnection();
scope (exit)
conn.close();
this.m_factory.getDBMetaData().updateDBSchema(conn, false, true);
}
}
void close() {
if (this.m_session && this.m_session.isOpen())
this.m_session.close();
if (this.m_factory && this.m_factory.isClosed() == false)
this.m_factory.close();
}
}