From 27fbb6508e445b3eecd21dc9bc445b1eff72134d Mon Sep 17 00:00:00 2001 From: Radical Date: Wed, 21 May 2025 20:47:45 +0200 Subject: [PATCH 1/5] build: switch sqlx to diesel --- Cargo.toml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 33d01e7..e6dcd84 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,6 @@ regex = "1.11" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" simple_logger = "5.0.0" -sqlx = { version = "0.8", features = ["runtime-tokio", "tls-native-tls", "postgres"] } redis = { version = "0.31.0", features= ["tokio-comp"] } tokio-tungstenite = { version = "0.26", features = ["native-tls", "url"] } toml = "0.8" @@ -30,6 +29,9 @@ uuid = { version = "1.16", features = ["serde", "v7"] } random-string = "1.1" actix-ws = "0.3.0" futures-util = "0.3.31" +deadpool = "0.12" +diesel = "2.2" +diesel-async = { version = "0.5", features = ["deadpool", "postgres"] } [dependencies.tokio] version = "1.44" From b9c7bda2b15ea19754d046655fb92f5a6972f8e2 Mon Sep 17 00:00:00 2001 From: Radical Date: Wed, 21 May 2025 20:48:09 +0200 Subject: [PATCH 2/5] feat: use diesel in main fn and data struct --- src/main.rs | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/main.rs b/src/main.rs index fbad594..9036665 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,14 +3,19 @@ use actix_web::{App, HttpServer, web}; use argon2::Argon2; use clap::Parser; use simple_logger::SimpleLogger; -use sqlx::{PgPool, Pool, Postgres}; +use diesel_async::pooled_connection::AsyncDieselConnectionManager; +use diesel_async::pooled_connection::deadpool::Pool; +use diesel_async::RunQueryDsl; use std::time::SystemTime; mod config; use config::{Config, ConfigBuilder}; mod api; +type Conn = deadpool::managed::Object>; + pub mod structs; pub mod utils; +pub mod tables; type Error = Box; @@ -23,7 +28,7 @@ struct Args { #[derive(Clone)] pub struct Data { - pub pool: Pool, + pub pool: deadpool::managed::Pool, Conn>, pub cache_pool: redis::Client, pub _config: Config, pub argon2: Argon2<'static>, @@ -44,17 +49,21 @@ async fn main() -> Result<(), Error> { let web = config.web.clone(); - let pool = PgPool::connect_with(config.database.connect_options()).await?; + // create a new connection pool with the default config + let pool_config = AsyncDieselConnectionManager::::new(config.database.url()); + let pool = Pool::builder(pool_config).build()?; let cache_pool = redis::Client::open(config.cache_database.url())?; + let mut conn = pool.get().await?; + /* TODO: Figure out if a table should be used here and if not then what. Also figure out if these should be different types from what they currently are and if we should add more "constraints" TODO: References to time should be removed in favor of using the timestamp built in to UUIDv7 (apart from deleted_at in users) */ - sqlx::raw_sql( + diesel::sql_query( r#" CREATE TABLE IF NOT EXISTS users ( uuid uuid PRIMARY KEY NOT NULL, @@ -141,7 +150,7 @@ async fn main() -> Result<(), Error> { ); "#, ) - .execute(&pool) + .execute(&mut conn) .await?; /* From 746949f0e54284f907ce414392bd62dc482a453e Mon Sep 17 00:00:00 2001 From: Radical Date: Wed, 21 May 2025 20:48:43 +0200 Subject: [PATCH 3/5] feat: use url format --- src/config.rs | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/src/config.rs b/src/config.rs index 65a5965..4e8fc21 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,7 +1,6 @@ use crate::Error; use log::debug; use serde::Deserialize; -use sqlx::postgres::PgConnectOptions; use tokio::fs::read_to_string; #[derive(Debug, Deserialize)] @@ -81,13 +80,24 @@ pub struct Web { } impl Database { - pub fn connect_options(&self) -> PgConnectOptions { - PgConnectOptions::new() - .database(&self.database) - .host(&self.host) - .username(&self.username) - .password(&self.password) - .port(self.port) + pub fn url(&self) -> String { + let mut url = String::from("postgres://"); + + url += &self.username; + + url += ":"; + url += &self.password; + + url += "@"; + + url += &self.host; + url += ":"; + url += &self.port.to_string(); + + url += "/"; + url += &self.database; + + url } } From da804cd43637150379df28aabfaad2185628d66d Mon Sep 17 00:00:00 2001 From: Radical Date: Wed, 21 May 2025 20:49:13 +0200 Subject: [PATCH 4/5] feat: use diesel on Channel and ChannelPermission structs --- src/structs.rs | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/src/structs.rs b/src/structs.rs index 1b339b1..7cec7c9 100644 --- a/src/structs.rs +++ b/src/structs.rs @@ -1,14 +1,15 @@ use std::str::FromStr; use actix_web::HttpResponse; +use diesel::Selectable; use log::error; use serde::{Deserialize, Serialize}; -use sqlx::{Pool, Postgres, prelude::FromRow}; use uuid::Uuid; -use crate::Data; +use crate::{Conn, Data, tables::*}; -#[derive(Serialize, Deserialize, Clone)] +#[derive(Serialize, Deserialize, Clone, Selectable)] +#[diesel(table_name = channels)] pub struct Channel { pub uuid: Uuid, pub guild_uuid: Uuid, @@ -17,7 +18,7 @@ pub struct Channel { pub permissions: Vec, } -#[derive(Serialize, Clone, FromRow)] +#[derive(Serialize, Clone)] struct ChannelPermissionBuilder { role_uuid: String, permissions: i32, @@ -32,7 +33,8 @@ impl ChannelPermissionBuilder { } } -#[derive(Serialize, Deserialize, Clone, FromRow)] +#[derive(Serialize, Deserialize, Clone, Selectable)] +#[diesel(table_name = channel_permissions)] pub struct ChannelPermission { pub role_uuid: Uuid, pub permissions: i32, @@ -40,15 +42,10 @@ pub struct ChannelPermission { impl Channel { pub async fn fetch_all( - pool: &Pool, + conn: &mut Conn, guild_uuid: Uuid, ) -> Result, HttpResponse> { - let row = sqlx::query_as(&format!( - "SELECT CAST(uuid AS VARCHAR), name, description FROM channels WHERE guild_uuid = '{}'", - guild_uuid - )) - .fetch_all(pool) - .await; + if let Err(error) = row { error!("{}", error); From f1d5b4316eeccac7be3ceee0d5d8f2e57d2cdf9d Mon Sep 17 00:00:00 2001 From: Radical Date: Wed, 21 May 2025 20:49:20 +0200 Subject: [PATCH 5/5] feat: add tables.rs --- src/tables.rs | 109 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 src/tables.rs diff --git a/src/tables.rs b/src/tables.rs new file mode 100644 index 0000000..3dbd38b --- /dev/null +++ b/src/tables.rs @@ -0,0 +1,109 @@ +use diesel::table; + +table! { + users (uuid) { + uuid -> Uuid, + username -> VarChar, + display_name -> Nullable, + password -> VarChar, + email -> VarChar, + email_verified -> Bool, + is_deleted -> Bool, + deleted_at -> Int8, + } +} + +table! { + instance_permissions (uuid) { + uuid -> Uuid, + administrator -> Bool, + } +} + +table! { + refresh_tokens (token) { + token -> VarChar, + uuid -> Uuid, + created_at -> Int8, + device_name -> VarChar, + } +} + +table! { + access_tokens (token) { + token -> VarChar, + refresh_token -> VarChar, + uuid -> Uuid, + created_at -> Int8 + } +} + +table! { + guilds (uuid) { + uuid -> Uuid, + owner_uuid -> Uuid, + name -> VarChar, + description -> VarChar + } +} + +table! { + guild_members (uuid) { + uuid -> Uuid, + guild_uuid -> Uuid, + user_uuid -> Uuid, + nickname -> VarChar, + } +} + +table! { + roles (uuid, guild_uuid) { + uuid -> Uuid, + guild_uuid -> Uuid, + name -> VarChar, + color -> Int4, + position -> Int4, + permissions -> Int8, + } +} + +table! { + role_members (role_uuid, member_uuid) { + role_uuid -> Uuid, + member_uuid -> Uuid, + } +} + +table! { + channels (uuid) { + uuid -> Uuid, + guild_uuid -> Uuid, + name -> VarChar, + description -> VarChar, + } +} + +table! { + channel_permissions (channel_uuid, role_uuid) { + channel_uuid -> Uuid, + role_uuid -> Uuid, + permissions -> Int8, + } +} + +table! { + messages (uuid) { + uuid -> Uuid, + channel_uuid -> Uuid, + user_uuid -> Uuid, + message -> VarChar, + } +} + +table! { + invites (id) { + id -> VarChar, + guild_uuid -> Uuid, + user_uuid -> Uuid, + } +}