use async db connection

This commit is contained in:
Akulij 2025-04-03 03:24:00 +09:00
parent 51bc75c8a0
commit 66ac460d80
4 changed files with 89 additions and 24 deletions

48
Cargo.lock generated
View File

@ -84,6 +84,18 @@ version = "0.22.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
[[package]]
name = "bb8"
version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d89aabfae550a5c44b43ab941844ffcd2e993cb6900b342debf59e9ea74acdb8"
dependencies = [
"async-trait",
"futures-util",
"parking_lot",
"tokio",
]
[[package]]
name = "bitflags"
version = "2.9.0"
@ -221,6 +233,23 @@ dependencies = [
"syn",
]
[[package]]
name = "deadpool"
version = "0.12.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ed5957ff93768adf7a65ab167a17835c3d2c3c50d084fe305174c112f468e2f"
dependencies = [
"deadpool-runtime",
"num_cpus",
"tokio",
]
[[package]]
name = "deadpool-runtime"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "092966b41edc516079bdf31ec78a2e0588d1d0c08f78b91d8307215928642b2b"
[[package]]
name = "deranged"
version = "0.4.1"
@ -273,6 +302,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51a307ac00f7c23f526a04a77761a0519b9f0eb2838ebf5b905a58580095bdcb"
dependencies = [
"async-trait",
"bb8",
"deadpool",
"diesel",
"futures-util",
"scoped-futures",
@ -594,6 +625,12 @@ version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
name = "hermit-abi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024"
[[package]]
name = "hex"
version = "0.4.3"
@ -1062,6 +1099,16 @@ dependencies = [
"autocfg",
]
[[package]]
name = "num_cpus"
version = "1.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43"
dependencies = [
"hermit-abi",
"libc",
]
[[package]]
name = "object"
version = "0.36.7"
@ -1889,6 +1936,7 @@ dependencies = [
"bytes",
"libc",
"mio",
"parking_lot",
"pin-project-lite",
"signal-hook-registry",
"socket2",

View File

@ -7,7 +7,7 @@ edition = "2021"
[dependencies]
diesel = { version = "2.2.8", features = ["postgres", "r2d2"] }
diesel-async = { version = "0.5.2", features = ["postgres"] }
diesel-async = { version = "0.5.2", features = ["bb8", "deadpool", "postgres", "r2d2"] }
dotenvy = "0.15.7"
envconfig = "0.11.0"
teloxide = { version = "0.14.0", features = ["macros"] }

View File

@ -4,43 +4,60 @@ use crate::Config;
use self::models::*;
use diesel::{prelude::*, r2d2::{ConnectionManager, Pool}};
pub fn establish_connection(cfg: Config) -> PgConnection {
PgConnection::establish(&cfg.db_url)
.unwrap_or_else(|_| panic!("Error connecting to {}", cfg.db_url))
}
use diesel::prelude::*;
//use diesel::query_dsl::methods::FilterDsl;
//use diesel::{prelude::*, r2d2::{ConnectionManager, Pool}};
use diesel_async::AsyncPgConnection;
use diesel_async::pooled_connection::AsyncDieselConnectionManager;
use diesel_async::pooled_connection::bb8::Pool;
use diesel_async::RunQueryDsl;
#[derive(Clone)]
pub struct DB {
pool: Pool<ConnectionManager<PgConnection>>
//pool: Pool<ConnectionManager<AsyncPgConnection>>
pool: diesel_async::pooled_connection::bb8::Pool<AsyncPgConnection>
}
impl DB {
pub fn new<S: Into<String>>(db_url: S) -> Self{
let mg = diesel::r2d2::ConnectionManager::new(db_url);
let pool = diesel::r2d2::Pool::builder()
.max_size(15)
.build(mg)
.unwrap();
pub async fn new<S: Into<String>>(db_url: S) -> Self {
let config = AsyncDieselConnectionManager::<diesel_async::AsyncPgConnection>::new(db_url);
let pool = Pool::builder().build(config).await.unwrap();
//let mg = diesel::r2d2::ConnectionManager::new(db_url);
//let pool = diesel::r2d2::Pool::builder()
// .max_size(15)
// .build(mg)
// .unwrap();
DB { pool }
}
pub fn make_admin(&mut self, userid: i64) {
pub async fn get_users(&mut self) -> Vec<User> {
use self::schema::users::dsl::*;
let connection = &mut self.pool.get().unwrap();
diesel::update(users).filter(id.eq(userid)).set(is_admin.eq(true)).execute(connection);
let mut conn = self.pool.get().await.unwrap();
//let mut conn = AsyncPgConnection::establish(&std::env::var("DATABASE_URL").unwrap()).await.unwrap();
users.filter(id.gt(0)).load::<User>(&mut conn).await.unwrap()
}
pub fn get_or_init_user(&mut self, userid: i64) -> User {
pub async fn make_admin(&mut self, userid: i64) {
use self::schema::users::dsl::*;
let connection = &mut self.pool.get().unwrap();
let connection = &mut self.pool.get().await.unwrap();
//diesel::update(users).filter(id.eq(userid)).set(is_admin.eq(true)).execute(connection);
//diesel::update(users).filter(id.eq(userid)).set(is_admin.eq(true)).load(connection).await.unwrap();
diesel::update(users)
.filter(id.eq(userid))
.set(is_admin.eq(true))
.execute(connection).await.unwrap();
}
let user = users.filter(id.eq(userid)).first::<User>(connection).optional().unwrap();
pub async fn get_or_init_user(&mut self, userid: i64) -> User {
use self::schema::users::dsl::*;
let connection = &mut self.pool.get().await.unwrap();
let user = users.filter(id.eq(userid)).first::<User>(connection).await.optional().unwrap();
match user {
Some(existing_user) => existing_user,
None => {
diesel::insert_into(users).values((id.eq(userid as i64), is_admin.eq(false))).get_result(connection).unwrap()
diesel::insert_into(users).values((id.eq(userid as i64), is_admin.eq(false))).get_result(connection).await.unwrap()
}
}
}

View File

@ -34,7 +34,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>>{
let config = Config::init_from_env()?;
let bot = Bot::new(&config.bot_token);
let db = DB::new(&config.db_url);
let db = DB::new(&config.db_url).await;
let handler = dptree::entry()
.inspect(|u: Update| {
@ -46,8 +46,8 @@ async fn main() -> Result<(), Box<dyn std::error::Error>>{
dptree::entry().filter_command::<UserCommands>().endpoint(user_command_handler)
)
.branch(
dptree::entry().filter(|msg: Message, mut db: DB| {
let user = db.get_or_init_user(msg.from.unwrap().id.0 as i64);
dptree::entry().filter_async(async |msg: Message, mut db: DB| {
let user = db.get_or_init_user(msg.from.unwrap().id.0 as i64).await;
user.is_admin
}).filter_command::<AdminCommands>().endpoint(admin_command_handler)
)