From e47a0b327572ad0b3b7c6c085dd73568a141f47c Mon Sep 17 00:00:00 2001 From: marisa Date: Tue, 6 Feb 2024 21:14:23 -0300 Subject: [PATCH] DB: start using ORM --- dub.sdl | 4 +- dub.selections.json | 2 +- source/db/db.d | 86 +++++++++++++--------------- source/db/migrations/m_001_initial.d | 25 -------- source/db/migrations/migration.d | 31 ---------- source/db/pgsql.d | 31 ---------- source/db/types.d | 32 ++++++----- source/main.d | 6 +- 8 files changed, 66 insertions(+), 151 deletions(-) delete mode 100644 source/db/migrations/m_001_initial.d delete mode 100644 source/db/migrations/migration.d delete mode 100644 source/db/pgsql.d diff --git a/dub.sdl b/dub.sdl index d931d62..6a487cd 100644 --- a/dub.sdl +++ b/dub.sdl @@ -5,7 +5,7 @@ copyright "Copyright © 2024, Marisa" license "MIT" dependency "slf4d" version="~>3.0.0" dependency "handy-httpd" version="~>8.2.0" +dependency "ddbc" version="~>0.5.8" dependency "requests" version="~>2.1.3" -dependency "ddbc" version="~>0.6.0" - +dependency "hibernated" version="~>0.4.0" subConfiguration "ddbc" "PGSQL" diff --git a/dub.selections.json b/dub.selections.json index 4f873f2..ef67255 100644 --- a/dub.selections.json +++ b/dub.selections.json @@ -4,7 +4,7 @@ "automem": "0.6.9", "cachetools": "0.3.1", "d-unit": "0.10.2", - "ddbc": "0.6.0", + "ddbc": "0.5.9", "derelict-pq": "2.2.0", "derelict-util": "2.0.6", "handy-httpd": "8.2.0", diff --git a/source/db/db.d b/source/db/db.d index 34028bd..6c6d0f7 100644 --- a/source/db/db.d +++ b/source/db/db.d @@ -3,6 +3,8 @@ module db.db; import slf4d; import ddbc.core; +import hibernated.core; +import db.types; enum DBConnector { DB_MYSQL, @@ -21,68 +23,60 @@ struct DBSettings { class DB { protected DBSettings m_settings; + protected EntityMetaData m_schema; protected DataSource m_ds; - protected Connection m_conn; - protected Statement m_stmt = null; + protected SessionFactory m_factory; + protected Session m_session; this(DBSettings settings) { this.m_settings = settings; + this.m_schema = new SchemaInfoImpl!(User); } - static DB getDB(DBSettings settings) { - switch (settings.connector) { - case DBConnector.DB_PGSQL: - import db.pgsql; - - debugF!"DB type is PostgreSQL"; - return new PostgresDB(settings); - - default: - throw new Exception("DB not supported"); - } - } - - protected abstract DataSource getDataSource(); - void connect() { - this.m_ds = this.getDataSource(); - this.m_conn = this.m_ds.getConnection(); - this.m_conn.setAutoCommit(false); - } + Driver driver; + string url; + string[string] params; + Dialect dialect; - int runUpdate(string statement) { - if (this.m_stmt is null) - this.m_stmt = this.m_conn.createStatement(); + switch (this.m_settings.connector) { + case DBConnector.DB_PGSQL: + debugF!"Using PGSQL driver"; - debugF!"Running update: %s"(statement); + import ddbc.drivers.pgsqlddbc; - return this.m_stmt.executeUpdate(statement); - } + driver = new PGSQLDriver(); - ResultSet runQuery(string statement) { - if (this.m_stmt is null) - this.m_stmt = this.m_conn.createStatement(); + with (this.m_settings) { + url = PGSQLDriver.generateUrl(host, port, dbname); + params = PGSQLDriver.setUserAndPassword(username, password); + } - debugF!"Running query: %s"(statement); + dialect = new PGSQLDialect(); + break; - return this.m_stmt.executeQuery(statement); - } + default: + throw new Exception("Database connector not supported (yet)"); + } - void runMigrations() { - ResultSet rs = this.runQuery( - `select * from information_schema.tables where table_name = 'migrations';`, - ); + debugF!"Connecting to DB with URL: %s"(url); - bool exists = rs.next(); - int ret = 0; + this.m_ds = new ConnectionPoolDataSourceImpl(driver, url, params); + this.m_factory = new SessionFactoryImpl(this.m_schema, dialect, this.m_ds); - if (exists == false) { - ret |= this.runUpdate( - `create table migrations( - id serial, - name character varying - )`, - ); + { // 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(); + } } diff --git a/source/db/migrations/m_001_initial.d b/source/db/migrations/m_001_initial.d deleted file mode 100644 index 365d367..0000000 --- a/source/db/migrations/m_001_initial.d +++ /dev/null @@ -1,25 +0,0 @@ -module db.migrations.m_001_initial; - -import db.migrations.migration; - -Migration Initial = Migration( - [ - `create table users( - id uuid not null, - name character varying(255), - handle character varying(255), - local boolean not null, - ap_id character varying(255) not null, - ap_privkey text, - ap_pubkey text, - ap_shared_inbox text, - ap_inbox text, - ap_outbox text, - ap_followers_addr text, - ap_following_addr text - );` -], - [ - `drop table users;` -], -); diff --git a/source/db/migrations/migration.d b/source/db/migrations/migration.d deleted file mode 100644 index 1f5bb33..0000000 --- a/source/db/migrations/migration.d +++ /dev/null @@ -1,31 +0,0 @@ -module db.migrations.migration; - -import singletons; -import db.migrations.m_001_initial; - -struct Migration { - string[] upStatements; - string[] downStatements; - - bool up() { - int result; - - foreach (string statement; upStatements) - result |= Db.runUpdate(statement); - - return result == 0; - } - - bool down() { - int result; - - foreach (string statement; downStatements) - result |= Db.runUpdate(statement); - - return result == 0; - } -} - -Migration[string] migrations = [ - "001_initial": Initial, -]; diff --git a/source/db/pgsql.d b/source/db/pgsql.d deleted file mode 100644 index 51ae23a..0000000 --- a/source/db/pgsql.d +++ /dev/null @@ -1,31 +0,0 @@ -module db.pgsql; - -import db.db; - -import ddbc.core; -import ddbc.common; - -import slf4d; - -class PostgresDB : DB { - this(Args...)(auto ref Args args) { - super(args); - } - - protected override DataSource getDataSource() { - import ddbc.drivers.pgsqlddbc; - - Driver driver = new PGSQLDriver(); - string url; - string[string] params; - - with (this.m_settings) { - url = PGSQLDriver.generateUrl(host, port, dbname); - params = PGSQLDriver.setUserAndPassword(username, password); - } - - debugF!"DB URL: %s"(url); - - return new ConnectionPoolDataSourceImpl(driver, url, params); - } -} diff --git a/source/db/types.d b/source/db/types.d index cd026d7..af60b40 100644 --- a/source/db/types.d +++ b/source/db/types.d @@ -1,17 +1,23 @@ module db.types; -class User { - string id; - string name; - string handle; - bool local; +import hibernated.core; - string ap_id; - string ap_privkey; - string ap_pubkey; - string ap_shared_inbox; - string ap_inbox; - string ap_outbox; - string ap_followers_addr; - string ap_following_addr; +@Entity +@Table("users") +class User { + @Generator(UUID_GENERATOR) + string id; + + @Column string name; + @Column string handle; + @Column bool local; + + @Column string ap_id; + @Column string ap_privkey; + @Column string ap_pubkey; + @Column string ap_shared_inbox; + @Column string ap_inbox; + @Column string ap_outbox; + @Column string ap_followers_addr; + @Column string ap_following_addr; } diff --git a/source/main.d b/source/main.d index fede4a0..deec66b 100644 --- a/source/main.d +++ b/source/main.d @@ -38,9 +38,11 @@ int main() { } } - Db = DB.getDB(dbSettings); + Db = new DB(dbSettings); Db.connect(); - Db.runMigrations(); + + scope (exit) + Db.close(); return 0; }