From efc04fa8e565132aec3a3f1aa9ee5c4fc79eb5b1 Mon Sep 17 00:00:00 2001 From: Matthew Gordon Date: Mon, 12 Feb 2024 19:56:56 -0400 Subject: [PATCH] Replace ORM with plain SQL Also move DB stuff into module. --- Cargo.toml | 6 ++- diesel.toml | 9 ---- .../down.sql | 6 --- .../up.sql | 36 -------------- .../2024-02-11-020849_create_users/down.sql | 1 - .../2024-02-11-020849_create_users/up.sql | 8 ---- src/db.rs | 47 +++++++++++++++++++ src/main.rs | 19 ++------ src/models.rs | 13 ----- src/schema.rs | 12 ----- 10 files changed, 56 insertions(+), 101 deletions(-) delete mode 100644 diesel.toml delete mode 100644 migrations/00000000000000_diesel_initial_setup/down.sql delete mode 100644 migrations/00000000000000_diesel_initial_setup/up.sql delete mode 100644 migrations/2024-02-11-020849_create_users/down.sql delete mode 100644 migrations/2024-02-11-020849_create_users/up.sql create mode 100644 src/db.rs delete mode 100644 src/models.rs delete mode 100644 src/schema.rs diff --git a/Cargo.toml b/Cargo.toml index adcd8e3..122a2c0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,5 +11,7 @@ axum = "0.7" askama = "0.12" askama_axum = "0.4" tower-http = { version = "0.5", features = ["fs"] } -diesel = { version = "2.1", features = ["postgres", "chrono"] } -deadpool-diesel = {version = "0.5", features = ["postgres"]} +r2d2_postgres = "0.18" +deadpool-r2d2 = {version = "0.3", features = ["rt_tokio_1"]} +deadpool = "0.10" +thiserror = "1.0" \ No newline at end of file diff --git a/diesel.toml b/diesel.toml deleted file mode 100644 index c028f4a..0000000 --- a/diesel.toml +++ /dev/null @@ -1,9 +0,0 @@ -# For documentation on how to configure this file, -# see https://diesel.rs/guides/configuring-diesel-cli - -[print_schema] -file = "src/schema.rs" -custom_type_derives = ["diesel::query_builder::QueryId"] - -[migrations_directory] -dir = "migrations" diff --git a/migrations/00000000000000_diesel_initial_setup/down.sql b/migrations/00000000000000_diesel_initial_setup/down.sql deleted file mode 100644 index a9f5260..0000000 --- a/migrations/00000000000000_diesel_initial_setup/down.sql +++ /dev/null @@ -1,6 +0,0 @@ --- This file was automatically created by Diesel to setup helper functions --- and other internal bookkeeping. This file is safe to edit, any future --- changes will be added to existing projects as new migrations. - -DROP FUNCTION IF EXISTS diesel_manage_updated_at(_tbl regclass); -DROP FUNCTION IF EXISTS diesel_set_updated_at(); diff --git a/migrations/00000000000000_diesel_initial_setup/up.sql b/migrations/00000000000000_diesel_initial_setup/up.sql deleted file mode 100644 index d68895b..0000000 --- a/migrations/00000000000000_diesel_initial_setup/up.sql +++ /dev/null @@ -1,36 +0,0 @@ --- This file was automatically created by Diesel to setup helper functions --- and other internal bookkeeping. This file is safe to edit, any future --- changes will be added to existing projects as new migrations. - - - - --- Sets up a trigger for the given table to automatically set a column called --- `updated_at` whenever the row is modified (unless `updated_at` was included --- in the modified columns) --- --- # Example --- --- ```sql --- CREATE TABLE users (id SERIAL PRIMARY KEY, updated_at TIMESTAMP NOT NULL DEFAULT NOW()); --- --- SELECT diesel_manage_updated_at('users'); --- ``` -CREATE OR REPLACE FUNCTION diesel_manage_updated_at(_tbl regclass) RETURNS VOID AS $$ -BEGIN - EXECUTE format('CREATE TRIGGER set_updated_at BEFORE UPDATE ON %s - FOR EACH ROW EXECUTE PROCEDURE diesel_set_updated_at()', _tbl); -END; -$$ LANGUAGE plpgsql; - -CREATE OR REPLACE FUNCTION diesel_set_updated_at() RETURNS trigger AS $$ -BEGIN - IF ( - NEW IS DISTINCT FROM OLD AND - NEW.updated_at IS NOT DISTINCT FROM OLD.updated_at - ) THEN - NEW.updated_at := current_timestamp; - END IF; - RETURN NEW; -END; -$$ LANGUAGE plpgsql; diff --git a/migrations/2024-02-11-020849_create_users/down.sql b/migrations/2024-02-11-020849_create_users/down.sql deleted file mode 100644 index cc1f647..0000000 --- a/migrations/2024-02-11-020849_create_users/down.sql +++ /dev/null @@ -1 +0,0 @@ -DROP TABLE users; diff --git a/migrations/2024-02-11-020849_create_users/up.sql b/migrations/2024-02-11-020849_create_users/up.sql deleted file mode 100644 index 9647fe6..0000000 --- a/migrations/2024-02-11-020849_create_users/up.sql +++ /dev/null @@ -1,8 +0,0 @@ -CREATE TABLE users ( - id SERIAL PRIMARY KEY, - username VARCHAR NOT NULL, - real_name VARCHAR NOT NULL, - email VARCHAR NOT NULL, - password_hash VARCHAR NOT NULL, - password_salt VARCHAR NOT NULL -); diff --git a/src/db.rs b/src/db.rs new file mode 100644 index 0000000..e802078 --- /dev/null +++ b/src/db.rs @@ -0,0 +1,47 @@ +use { + deadpool, deadpool_r2d2::Runtime, thiserror::Error, +}; + +type PgManager = deadpool_r2d2::Manager< + r2d2_postgres::PostgresConnectionManager, +>; +type PgPool = deadpool_r2d2::Pool; + +#[derive(Error, Debug)] +pub enum Error { + #[error("Could not initialize DB connection pool.")] + ConnectionPoolError(#[from] deadpool::managed::BuildError), + #[error("Error with Postgres database")] + PostrgesError(#[from] r2d2_postgres::postgres::Error) +} + +#[derive(Clone)] +pub struct Database { + pg_pool: PgPool, +} + +impl Database { + pub fn create_pool(connection_url: &str, max_size: usize) -> Result { + let pg_config: r2d2_postgres::postgres::Config = connection_url.parse()?; + let r2d2_manager = r2d2_postgres::PostgresConnectionManager::new( + pg_config, + r2d2_postgres::postgres::NoTls, + ); + let manager = PgManager::new(r2d2_manager, Runtime::Tokio1); + let pg_pool = PgPool::builder(manager).max_size(max_size).build()?; + Ok(Database { pg_pool }) + } + + pub async fn log_num_users(&self) -> usize { + self.pg_pool + .get() + .await + .unwrap() + .interact(|conn| { + let results = conn.query("SELECT * FROM users;", &[]).unwrap(); + results.len() + }) + .await + .unwrap() + } +} diff --git a/src/main.rs b/src/main.rs index b3b2561..c725408 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,19 +1,16 @@ use { askama::Template, axum::{extract::State, routing::get, Router}, - deadpool_diesel::postgres::{Manager, Pool, Runtime}, std::env, tower_http::services::ServeDir, }; -mod models; -mod schema; - +mod db; +use db::Database; #[tokio::main] async fn main() -> Result<(), Box> { - let db_pool_manager = Manager::new(env::var("LOCALHUB_DATABASE_URL")?, Runtime::Tokio1); - let db_pool = Pool::builder(db_pool_manager).max_size(8).build()?; + let db_pool = Database::create_pool(&env::var("LOCALHUB_DATABASE_URL")?, 2)?; let app = Router::new() .route("/", get(root)) @@ -34,13 +31,7 @@ struct IndexTemplate<'a> { title: &'a str, } -async fn root<'a>(State(db_pool): State) -> IndexTemplate<'a> { - use self::models::*; - use diesel::prelude::*; - let db_conn = db_pool.get().await.unwrap(); - db_conn.interact(|conn| { - let results = schema::users::table.select(User::as_select()).load(conn).unwrap(); - println!("Found {} users", results.len()); - }).await.unwrap(); +async fn root<'a>(State(database): State) -> IndexTemplate<'a> { + println!("Found {} users", database.log_num_users().await); IndexTemplate { title: "LocalHub" } } diff --git a/src/models.rs b/src/models.rs deleted file mode 100644 index 33673d3..0000000 --- a/src/models.rs +++ /dev/null @@ -1,13 +0,0 @@ -use diesel::prelude::*; - -#[derive(Queryable, Selectable)] -#[diesel(table_name = crate::schema::users)] -#[diesel(check_for_backend(diesel::pg::Pg))] -pub struct User { - pub id: i32, - pub username: String, - pub real_name: String, - pub email: String, - pub password_hash: String, - pub password_salt: String, -} diff --git a/src/schema.rs b/src/schema.rs deleted file mode 100644 index ab1af24..0000000 --- a/src/schema.rs +++ /dev/null @@ -1,12 +0,0 @@ -// @generated automatically by Diesel CLI. - -diesel::table! { - users (id) { - id -> Int4, - username -> Varchar, - real_name -> Varchar, - email -> Varchar, - password_hash -> Varchar, - password_salt -> Varchar, - } -}