use super::rand_string;
use crate::db::DBConnection;
use crate::prelude::*;
#[cfg(feature = "rusqlite")]
use std::path::Path;
impl Users {
#[cfg(feature = "sqlx-sqlite")]
#[throws(Error)]
pub async fn open_sqlite(path: &str) -> Self {
let conn = sqlx::SqlitePool::connect(path).await?;
let users: Users = conn.into();
users.create_table().await?;
users
}
#[throws(Error)]
pub async fn create_table(&self) {
self.conn.init().await?
}
#[cfg(feature = "redis")]
#[throws(Error)]
pub fn open_redis(&mut self, path: impl redis::IntoConnectionInfo) {
let client = redis::Client::open(path)?;
self.sess = Box::new(client);
}
#[cfg(feature = "rusqlite")]
#[throws(Error)]
pub fn open_rusqlite(path: impl AsRef<Path>) -> Self {
use tokio::sync::Mutex;
let users = Users {
conn: Box::new(Mutex::new(rusqlite::Connection::open(path)?)),
sess: Box::new(chashmap::CHashMap::new()),
};
futures::executor::block_on(users.conn.init())?;
users
}
#[cfg(feature = "sqlx-postgres")]
#[throws(Error)]
pub async fn open_postgres(path: &str) -> Self {
use sqlx::PgPool;
let conn = PgPool::connect(path).await?;
conn.init().await?;
let users = Users {
conn: Box::new(conn),
sess: Box::new(chashmap::CHashMap::new()),
};
users
}
#[cfg(feature = "sqlx-mysql")]
#[throws(Error)]
pub async fn open_mysql(path: &str) -> Self {
let conn = sqlx::MySqlPool::connect(path).await?;
let users: Users = conn.into();
users.create_table().await?;
users
}
#[throws(Error)]
pub async fn get_by_email(&self, email: &str) -> User {
self.conn.get_user_by_email(email).await?
}
#[throws(Error)]
pub async fn get_by_id(&self, user_id: i32) -> User {
self.conn.get_user_by_id(user_id).await?
}
#[throws(Error)]
pub async fn create_user(&self, email: &str, password: &str, is_admin: bool) {
let password = password.as_bytes();
let salt = rand_string(30);
let config = argon2::Config::default();
let hash = argon2::hash_encoded(password, salt.as_bytes(), &config).unwrap();
self.conn.create_user(email, &hash, is_admin).await?;
}
#[throws(Error)]
pub async fn delete(&self, id: i32) {
self.sess.remove(id)?;
self.conn.delete_user_by_id(id).await?;
}
#[throws(Error)]
pub async fn modify(&self, user: &User) {
self.conn.update_user(user).await?;
}
}
impl<Conn: 'static + DBConnection> From<Conn> for Users {
fn from(db: Conn) -> Users {
Users {
conn: Box::from(db),
sess: Box::new(chashmap::CHashMap::new()),
}
}
}
impl<T0: 'static + DBConnection, T1: 'static + SessionManager> From<(T0, T1)> for Users {
fn from((db, ss): (T0, T1)) -> Users {
Users {
conn: Box::from(db),
sess: Box::new(ss),
}
}
}