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"
version = "0.1.0"
dependencies = [
"async-trait",
"bb8",
"chrono",
"chrono-tz",
"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
[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"] }

View File

@ -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

View File

@ -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<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::*;
let mut conn = self.pool.get().await.unwrap();
let mut conn = self.get_pool().await;
users
.filter(id.gt(0))
.load::<User>(&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::<User>(connection)
.first::<User>(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<Option<Message>, Box<dyn std::error::Error>> {
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<dyn std::error::Error>> {
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<Option<Literal>, Box<dyn std::error::Error>> {
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<Option<String>, Box<dyn std::error::Error>> {
@ -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<dyn std::error::Error>> {
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<Event> {
async fn get_all_events(&mut self) -> Vec<Event> {
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::<Event>(&mut conn)
@ -201,12 +220,12 @@ impl DB {
.unwrap()
}
pub async fn create_event(
async fn create_event(
&mut self,
event_datetime: chrono::DateTime<Utc>,
) -> Result<Event, Box<dyn std::error::Error>> {
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<Vec<Media>, Box<dyn std::error::Error>> {
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?;
Ok(media_items)
}
pub async fn is_media_group_exists(
async fn is_media_group_exists(
&mut self,
media_group: &str,
) -> Result<bool, Box<dyn std::error::Error>> {
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<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::*;
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<usize, Box<dyn std::error::Error>> {
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<Media, Box<dyn std::error::Error>> {
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((

View File

@ -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;