From a940ef5e836f4a77b009184df82abacdcdb69ae7 Mon Sep 17 00:00:00 2001 From: Akulij Date: Tue, 22 Apr 2025 22:51:54 +0300 Subject: [PATCH] move towards generefication of DB implementation --- Cargo.lock | 2 ++ Cargo.toml | 2 ++ src/admin.rs | 2 +- src/db/mod.rs | 87 +++++++++++++++++++++++++++++++-------------------- src/main.rs | 2 +- 5 files changed, 59 insertions(+), 36 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 031cfe9..54ea1f3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -764,6 +764,8 @@ checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" name = "gongbotrs" version = "0.1.0" dependencies = [ + "async-trait", + "bb8", "chrono", "chrono-tz", "diesel", diff --git a/Cargo.toml b/Cargo.toml index 17eca1e..127bc3c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,6 +6,8 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +async-trait = "0.1.88" +bb8 = "0.8.6" chrono = "0.4.40" chrono-tz = "0.10.3" diesel = { version = "2.2.8", features = ["postgres", "chrono"] } diff --git a/src/admin.rs b/src/admin.rs index 46fddb3..f8a03fd 100644 --- a/src/admin.rs +++ b/src/admin.rs @@ -3,7 +3,7 @@ use teloxide::{ utils::{command::BotCommands, render::RenderMessageTextHelper}, }; -use crate::db::DB; +use crate::db::{DB, CallDB}; use crate::LogMsg; // These are should not appear in /help diff --git a/src/db/mod.rs b/src/db/mod.rs index 318e87a..c3baa29 100644 --- a/src/db/mod.rs +++ b/src/db/mod.rs @@ -1,15 +1,22 @@ pub mod models; pub mod schema; +use std::os::unix::process::CommandExt; + use self::models::*; use chrono::Utc; use diesel::prelude::*; +use diesel::query_builder::NoFromClause; +use diesel::query_builder::SelectStatement; use diesel_async::pooled_connection::bb8::Pool; +use bb8::PooledConnection; use diesel_async::pooled_connection::AsyncDieselConnectionManager; +use diesel_async::AsyncConnection; use diesel_async::AsyncPgConnection; use diesel_async::RunQueryDsl; use enum_stringify::EnumStringify; +use async_trait::async_trait; #[derive(EnumStringify)] #[enum_stringify(case = "flat")] @@ -39,10 +46,23 @@ impl DB { let pool = Pool::builder().build(config).await.unwrap(); DB { pool } } +} - pub async fn get_users(&mut self) -> Vec { +#[async_trait] +impl CallDB for DB { + async fn get_pool(&mut self) -> PooledConnection<'_, AsyncDieselConnectionManager> { + self.pool.get().await.unwrap() + } +} + +#[async_trait] +pub trait CallDB { + //type C; + async fn get_pool(&mut self) -> PooledConnection<'_, AsyncDieselConnectionManager>; + //async fn get_pool(&mut self) -> PooledConnection<'_, AsyncDieselConnectionManager>; + async fn get_users(&mut self) -> Vec { use self::schema::users::dsl::*; - let mut conn = self.pool.get().await.unwrap(); + let mut conn = self.get_pool().await; users .filter(id.gt(0)) .load::(&mut conn) @@ -50,24 +70,24 @@ impl DB { .unwrap() } - pub async fn set_admin(&mut self, userid: i64, isadmin: bool) { + async fn set_admin(&mut self, userid: i64, isadmin: bool) { use self::schema::users::dsl::*; - let connection = &mut self.pool.get().await.unwrap(); + let mut conn = self.get_pool().await; diesel::update(users) .filter(id.eq(userid)) .set(is_admin.eq(isadmin)) - .execute(connection) + .execute(&mut conn) .await .unwrap(); } - pub async fn get_or_init_user(&mut self, userid: i64, firstname: &str) -> User { + async fn get_or_init_user(&mut self, userid: i64, firstname: &str) -> User { use self::schema::users::dsl::*; - let connection = &mut self.pool.get().await.unwrap(); + let conn = &mut self.get_pool().await; let user = users .filter(id.eq(userid)) - .first::(connection) + .first::(conn) .await .optional() .unwrap(); @@ -80,19 +100,19 @@ impl DB { is_admin.eq(false), first_name.eq(firstname), )) - .get_result(connection) + .get_result(conn) .await .unwrap(), } } - pub async fn get_message( + async fn get_message( &mut self, chatid: i64, messageid: i32, ) -> Result, Box> { use self::schema::messages::dsl::*; - let conn = &mut self.pool.get().await.unwrap(); + let conn = &mut self.get_pool().await; let msg = messages .filter(chat_id.eq(chatid)) @@ -104,7 +124,7 @@ impl DB { Ok(msg) } - pub async fn get_message_literal( + async fn get_message_literal( &mut self, chatid: i64, messageid: i32, @@ -113,16 +133,15 @@ impl DB { Ok(msg.map(|m| m.token)) } - pub async fn set_message_literal( + async fn set_message_literal( &mut self, chatid: i64, messageid: i32, literal: &str, ) -> Result<(), Box> { use self::schema::messages::dsl::*; - let conn = &mut self.pool.get().await?; - - let msg = self.clone().get_message(chatid, messageid).await?; + let msg = self.get_message(chatid, messageid).await?; + let conn = &mut self.get_pool().await; match msg { Some(msg) => { @@ -152,7 +171,7 @@ impl DB { literal: &str, ) -> Result, Box> { use self::schema::literals::dsl::*; - let conn = &mut self.pool.get().await.unwrap(); + let conn = &mut self.get_pool().await; let literal = literals .filter(token.eq(literal)) @@ -163,7 +182,7 @@ impl DB { Ok(literal) } - pub async fn get_literal_value( + async fn get_literal_value( &mut self, literal: &str, ) -> Result, Box> { @@ -172,13 +191,13 @@ impl DB { Ok(literal.map(|l| l.value)) } - pub async fn set_literal( + async fn set_literal( &mut self, literal: &str, valuestr: &str, ) -> Result<(), Box> { use self::schema::literals::dsl::*; - let conn = &mut self.pool.get().await.unwrap(); + let conn = &mut self.get_pool().await; diesel::insert_into(literals) .values((token.eq(literal), value.eq(valuestr))) @@ -191,9 +210,9 @@ impl DB { Ok(()) } - pub async fn get_all_events(&mut self) -> Vec { + async fn get_all_events(&mut self) -> Vec { use self::schema::events::dsl::*; - let mut conn = self.pool.get().await.unwrap(); + let mut conn = self.get_pool().await; events .filter(id.gt(0)) .load::(&mut conn) @@ -201,12 +220,12 @@ impl DB { .unwrap() } - pub async fn create_event( + async fn create_event( &mut self, event_datetime: chrono::DateTime, ) -> Result> { use self::schema::events::dsl::*; - let conn = &mut self.pool.get().await.unwrap(); + let conn = &mut self.get_pool().await; let new_event = diesel::insert_into(events) .values((time.eq(event_datetime),)) @@ -216,24 +235,24 @@ impl DB { Ok(new_event) } - pub async fn get_media( + async fn get_media( &mut self, literal: &str, ) -> Result, Box> { use self::schema::media::dsl::*; - let conn = &mut self.pool.get().await.unwrap(); + let conn = &mut self.get_pool().await; let media_items = media.filter(token.eq(literal)).load::(conn).await?; Ok(media_items) } - pub async fn is_media_group_exists( + async fn is_media_group_exists( &mut self, media_group: &str, ) -> Result> { use self::schema::media::dsl::*; - let conn = &mut self.pool.get().await.unwrap(); + let conn = &mut self.get_pool().await; let is_exists = media .filter(media_group_id.eq(media_group)) @@ -245,9 +264,9 @@ impl DB { Ok(is_exists) } - pub async fn drop_media(&mut self, literal: &str) -> Result> { + async fn drop_media(&mut self, literal: &str) -> Result> { use self::schema::media::dsl::*; - let conn = &mut self.pool.get().await.unwrap(); + let conn = &mut self.get_pool().await; let deleted_count = diesel::delete(media.filter(token.eq(literal))) .execute(conn) @@ -256,13 +275,13 @@ impl DB { Ok(deleted_count) } - pub async fn drop_media_except( + async fn drop_media_except( &mut self, literal: &str, except_group: &str, ) -> Result> { use self::schema::media::dsl::*; - let conn = &mut self.pool.get().await.unwrap(); + let conn = &mut self.get_pool().await; let deleted_count = diesel::delete( media.filter( @@ -277,7 +296,7 @@ impl DB { Ok(deleted_count) } - pub async fn add_media( + async fn add_media( &mut self, literal: &str, mediatype: &str, @@ -285,7 +304,7 @@ impl DB { media_group: Option<&str>, ) -> Result> { use self::schema::media::dsl::*; - let conn = &mut self.pool.get().await.unwrap(); + let conn = &mut self.get_pool().await; let new_media = diesel::insert_into(media) .values(( diff --git a/src/main.rs b/src/main.rs index 4389e83..0060772 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,7 +5,7 @@ use std::time::Duration; use crate::admin::{admin_command_handler, AdminCommands}; use crate::admin::{secret_command_handler, SecretCommands}; -use crate::db::DB; +use crate::db::{DB, CallDB}; use chrono::{DateTime, Utc}; use chrono_tz::Asia;