move towards generefication of DB implementation

This commit is contained in:
Akulij 2025-04-22 22:51:54 +03:00
parent b6ae5170a4
commit a940ef5e83
5 changed files with 59 additions and 36 deletions

2
Cargo.lock generated
View File

@ -764,6 +764,8 @@ checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
name = "gongbotrs" name = "gongbotrs"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"async-trait",
"bb8",
"chrono", "chrono",
"chrono-tz", "chrono-tz",
"diesel", "diesel",

View File

@ -6,6 +6,8 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
async-trait = "0.1.88"
bb8 = "0.8.6"
chrono = "0.4.40" chrono = "0.4.40"
chrono-tz = "0.10.3" chrono-tz = "0.10.3"
diesel = { version = "2.2.8", features = ["postgres", "chrono"] } diesel = { version = "2.2.8", features = ["postgres", "chrono"] }

View File

@ -3,7 +3,7 @@ use teloxide::{
utils::{command::BotCommands, render::RenderMessageTextHelper}, utils::{command::BotCommands, render::RenderMessageTextHelper},
}; };
use crate::db::DB; use crate::db::{DB, CallDB};
use crate::LogMsg; use crate::LogMsg;
// These are should not appear in /help // These are should not appear in /help

View File

@ -1,15 +1,22 @@
pub mod models; pub mod models;
pub mod schema; pub mod schema;
use std::os::unix::process::CommandExt;
use self::models::*; use self::models::*;
use chrono::Utc; use chrono::Utc;
use diesel::prelude::*; use diesel::prelude::*;
use diesel::query_builder::NoFromClause;
use diesel::query_builder::SelectStatement;
use diesel_async::pooled_connection::bb8::Pool; use diesel_async::pooled_connection::bb8::Pool;
use bb8::PooledConnection;
use diesel_async::pooled_connection::AsyncDieselConnectionManager; use diesel_async::pooled_connection::AsyncDieselConnectionManager;
use diesel_async::AsyncConnection;
use diesel_async::AsyncPgConnection; use diesel_async::AsyncPgConnection;
use diesel_async::RunQueryDsl; use diesel_async::RunQueryDsl;
use enum_stringify::EnumStringify; use enum_stringify::EnumStringify;
use async_trait::async_trait;
#[derive(EnumStringify)] #[derive(EnumStringify)]
#[enum_stringify(case = "flat")] #[enum_stringify(case = "flat")]
@ -39,10 +46,23 @@ impl DB {
let pool = Pool::builder().build(config).await.unwrap(); let pool = Pool::builder().build(config).await.unwrap();
DB { pool } DB { pool }
} }
}
pub async fn get_users(&mut self) -> Vec<User> { #[async_trait]
impl CallDB for DB {
async fn get_pool(&mut self) -> PooledConnection<'_, AsyncDieselConnectionManager<AsyncPgConnection>> {
self.pool.get().await.unwrap()
}
}
#[async_trait]
pub trait CallDB {
//type C;
async fn get_pool(&mut self) -> PooledConnection<'_, AsyncDieselConnectionManager<AsyncPgConnection>>;
//async fn get_pool(&mut self) -> PooledConnection<'_, AsyncDieselConnectionManager<C>>;
async fn get_users(&mut self) -> Vec<User> {
use self::schema::users::dsl::*; use self::schema::users::dsl::*;
let mut conn = self.pool.get().await.unwrap(); let mut conn = self.get_pool().await;
users users
.filter(id.gt(0)) .filter(id.gt(0))
.load::<User>(&mut conn) .load::<User>(&mut conn)
@ -50,24 +70,24 @@ impl DB {
.unwrap() .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::*; use self::schema::users::dsl::*;
let connection = &mut self.pool.get().await.unwrap(); let mut conn = self.get_pool().await;
diesel::update(users) diesel::update(users)
.filter(id.eq(userid)) .filter(id.eq(userid))
.set(is_admin.eq(isadmin)) .set(is_admin.eq(isadmin))
.execute(connection) .execute(&mut conn)
.await .await
.unwrap(); .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::*; use self::schema::users::dsl::*;
let connection = &mut self.pool.get().await.unwrap(); let conn = &mut self.get_pool().await;
let user = users let user = users
.filter(id.eq(userid)) .filter(id.eq(userid))
.first::<User>(connection) .first::<User>(conn)
.await .await
.optional() .optional()
.unwrap(); .unwrap();
@ -80,19 +100,19 @@ impl DB {
is_admin.eq(false), is_admin.eq(false),
first_name.eq(firstname), first_name.eq(firstname),
)) ))
.get_result(connection) .get_result(conn)
.await .await
.unwrap(), .unwrap(),
} }
} }
pub async fn get_message( async fn get_message(
&mut self, &mut self,
chatid: i64, chatid: i64,
messageid: i32, messageid: i32,
) -> Result<Option<Message>, Box<dyn std::error::Error>> { ) -> Result<Option<Message>, Box<dyn std::error::Error>> {
use self::schema::messages::dsl::*; use self::schema::messages::dsl::*;
let conn = &mut self.pool.get().await.unwrap(); let conn = &mut self.get_pool().await;
let msg = messages let msg = messages
.filter(chat_id.eq(chatid)) .filter(chat_id.eq(chatid))
@ -104,7 +124,7 @@ impl DB {
Ok(msg) Ok(msg)
} }
pub async fn get_message_literal( async fn get_message_literal(
&mut self, &mut self,
chatid: i64, chatid: i64,
messageid: i32, messageid: i32,
@ -113,16 +133,15 @@ impl DB {
Ok(msg.map(|m| m.token)) Ok(msg.map(|m| m.token))
} }
pub async fn set_message_literal( async fn set_message_literal(
&mut self, &mut self,
chatid: i64, chatid: i64,
messageid: i32, messageid: i32,
literal: &str, literal: &str,
) -> Result<(), Box<dyn std::error::Error>> { ) -> Result<(), Box<dyn std::error::Error>> {
use self::schema::messages::dsl::*; use self::schema::messages::dsl::*;
let conn = &mut self.pool.get().await?; let msg = self.get_message(chatid, messageid).await?;
let conn = &mut self.get_pool().await;
let msg = self.clone().get_message(chatid, messageid).await?;
match msg { match msg {
Some(msg) => { Some(msg) => {
@ -152,7 +171,7 @@ impl DB {
literal: &str, literal: &str,
) -> Result<Option<Literal>, Box<dyn std::error::Error>> { ) -> Result<Option<Literal>, Box<dyn std::error::Error>> {
use self::schema::literals::dsl::*; use self::schema::literals::dsl::*;
let conn = &mut self.pool.get().await.unwrap(); let conn = &mut self.get_pool().await;
let literal = literals let literal = literals
.filter(token.eq(literal)) .filter(token.eq(literal))
@ -163,7 +182,7 @@ impl DB {
Ok(literal) Ok(literal)
} }
pub async fn get_literal_value( async fn get_literal_value(
&mut self, &mut self,
literal: &str, literal: &str,
) -> Result<Option<String>, Box<dyn std::error::Error>> { ) -> Result<Option<String>, Box<dyn std::error::Error>> {
@ -172,13 +191,13 @@ impl DB {
Ok(literal.map(|l| l.value)) Ok(literal.map(|l| l.value))
} }
pub async fn set_literal( async fn set_literal(
&mut self, &mut self,
literal: &str, literal: &str,
valuestr: &str, valuestr: &str,
) -> Result<(), Box<dyn std::error::Error>> { ) -> Result<(), Box<dyn std::error::Error>> {
use self::schema::literals::dsl::*; use self::schema::literals::dsl::*;
let conn = &mut self.pool.get().await.unwrap(); let conn = &mut self.get_pool().await;
diesel::insert_into(literals) diesel::insert_into(literals)
.values((token.eq(literal), value.eq(valuestr))) .values((token.eq(literal), value.eq(valuestr)))
@ -191,9 +210,9 @@ impl DB {
Ok(()) Ok(())
} }
pub async fn get_all_events(&mut self) -> Vec<Event> { async fn get_all_events(&mut self) -> Vec<Event> {
use self::schema::events::dsl::*; use self::schema::events::dsl::*;
let mut conn = self.pool.get().await.unwrap(); let mut conn = self.get_pool().await;
events events
.filter(id.gt(0)) .filter(id.gt(0))
.load::<Event>(&mut conn) .load::<Event>(&mut conn)
@ -201,12 +220,12 @@ impl DB {
.unwrap() .unwrap()
} }
pub async fn create_event( async fn create_event(
&mut self, &mut self,
event_datetime: chrono::DateTime<Utc>, event_datetime: chrono::DateTime<Utc>,
) -> Result<Event, Box<dyn std::error::Error>> { ) -> Result<Event, Box<dyn std::error::Error>> {
use self::schema::events::dsl::*; 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) let new_event = diesel::insert_into(events)
.values((time.eq(event_datetime),)) .values((time.eq(event_datetime),))
@ -216,24 +235,24 @@ impl DB {
Ok(new_event) Ok(new_event)
} }
pub async fn get_media( async fn get_media(
&mut self, &mut self,
literal: &str, literal: &str,
) -> Result<Vec<Media>, Box<dyn std::error::Error>> { ) -> Result<Vec<Media>, Box<dyn std::error::Error>> {
use self::schema::media::dsl::*; 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::<Media>(conn).await?; let media_items = media.filter(token.eq(literal)).load::<Media>(conn).await?;
Ok(media_items) Ok(media_items)
} }
pub async fn is_media_group_exists( async fn is_media_group_exists(
&mut self, &mut self,
media_group: &str, media_group: &str,
) -> Result<bool, Box<dyn std::error::Error>> { ) -> Result<bool, Box<dyn std::error::Error>> {
use self::schema::media::dsl::*; use self::schema::media::dsl::*;
let conn = &mut self.pool.get().await.unwrap(); let conn = &mut self.get_pool().await;
let is_exists = media let is_exists = media
.filter(media_group_id.eq(media_group)) .filter(media_group_id.eq(media_group))
@ -245,9 +264,9 @@ impl DB {
Ok(is_exists) Ok(is_exists)
} }
pub async fn drop_media(&mut self, literal: &str) -> Result<usize, Box<dyn std::error::Error>> { async fn drop_media(&mut self, literal: &str) -> Result<usize, Box<dyn std::error::Error>> {
use self::schema::media::dsl::*; 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))) let deleted_count = diesel::delete(media.filter(token.eq(literal)))
.execute(conn) .execute(conn)
@ -256,13 +275,13 @@ impl DB {
Ok(deleted_count) Ok(deleted_count)
} }
pub async fn drop_media_except( async fn drop_media_except(
&mut self, &mut self,
literal: &str, literal: &str,
except_group: &str, except_group: &str,
) -> Result<usize, Box<dyn std::error::Error>> { ) -> Result<usize, Box<dyn std::error::Error>> {
use self::schema::media::dsl::*; 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( let deleted_count = diesel::delete(
media.filter( media.filter(
@ -277,7 +296,7 @@ impl DB {
Ok(deleted_count) Ok(deleted_count)
} }
pub async fn add_media( async fn add_media(
&mut self, &mut self,
literal: &str, literal: &str,
mediatype: &str, mediatype: &str,
@ -285,7 +304,7 @@ impl DB {
media_group: Option<&str>, media_group: Option<&str>,
) -> Result<Media, Box<dyn std::error::Error>> { ) -> Result<Media, Box<dyn std::error::Error>> {
use self::schema::media::dsl::*; 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) let new_media = diesel::insert_into(media)
.values(( .values((

View File

@ -5,7 +5,7 @@ use std::time::Duration;
use crate::admin::{admin_command_handler, AdminCommands}; use crate::admin::{admin_command_handler, AdminCommands};
use crate::admin::{secret_command_handler, SecretCommands}; use crate::admin::{secret_command_handler, SecretCommands};
use crate::db::DB; use crate::db::{DB, CallDB};
use chrono::{DateTime, Utc}; use chrono::{DateTime, Utc};
use chrono_tz::Asia; use chrono_tz::Asia;