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 DB { 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(); } }