use super::rand_string;
use crate::db::DBConnection;
use crate::prelude::*;
use crate::user::roles::Roles;
impl Users {
#[cfg(feature = "sqlx-sqlite")]
pub async fn open_sqlite(path: &str) -> Result<Self> {
let conn = sqlx::SqlitePool::connect(path).await?;
let users: Users = conn.into();
users.create_table().await?;
Ok(users)
}
pub async fn create_table(&self) -> Result<(), Error> {
self.conn.init().await
}
#[cfg(feature = "redis")]
pub fn open_redis(&mut self, path: impl redis::IntoConnectionInfo) -> Result<(), Error> {
let client = redis::Client::open(path)?;
self.sess = Box::new(client);
Ok(())
}
#[cfg(feature = "rusqlite")]
pub fn open_rusqlite(path: impl AsRef<std::path::Path>) -> Result<Self, Error> {
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())?;
Ok(users)
}
#[cfg(feature = "sqlx-postgres")]
pub async fn open_postgres(path: &str) -> Result<Self, Error> {
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()),
};
Ok(users)
}
#[cfg(feature = "sqlx-mysql")]
pub async fn open_mysql(path: &str) -> Result<Self, Error> {
let conn = sqlx::MySqlPool::connect(path).await?;
let users: Users = conn.into();
users.create_table().await?;
Ok(users)
}
#[cfg(feature = "sled")]
pub fn open_sled(path: impl AsRef<std::path::Path>) -> Result<Self, Error> {
let db = sled::open(path)?;
Ok(db.into())
}
pub async fn get_by_email(&self, email: &str) -> Result<User, Error> {
self.conn.get_user_by_email(email).await
}
pub async fn get_by_id(&self, user_id: i32) -> Result<User, Error> {
self.conn.get_user_by_id(user_id).await
}
pub async fn create_user(
&self,
email: &str,
password: &str,
roles: &Roles,
) -> Result<(), Error> {
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, roles).await?;
Ok(())
}
pub async fn get_all(&self) -> Result<Vec<i32>> {
self.conn.get_all_ids().await
}
pub async fn delete(&self, id: i32) -> Result<()> {
self.sess.remove(id)?;
self.conn.delete_user_by_id(id).await
}
pub async fn modify(&self, user: &User) -> Result<()> {
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),
}
}
}