use tokio_rusqlite::{named_params, Connection, Row}; use crate::db::utils; use crate::model::user::User; fn row_to_user(row: &Row) -> Result { Ok(User { id: row.get(0)?, name: row.get(1)?, email: row.get(2)?, }) } pub async fn list(conn: &Connection) -> Vec { let query = r#"SELECT id, name, email FROM users ORDER BY name"#; let res = conn .call(move |conn| { let mut stmt = conn.prepare(query)?; let users = stmt .query_map([], row_to_user)? .collect::, _>>()?; Ok(users) }) .await; match res { Ok(users) => users, Err(err) => { log::error!("Error listing users: {:?}", err); vec![] } } } pub async fn set_login_token( conn: &Connection, email: String, login_token: String, ) -> bool { let query = r#" UPDATE users SET login_token = :login_token, updated_at = datetime() WHERE email = :email "#; let res = conn .call(move |conn| { Ok(conn.execute( query, named_params![ ":login_token": login_token, ":email": email ], )?) }) .await; match res { Ok(_) => true, Err(err) => { log::error!("Error updating login token: {:?}", err); false } } } pub async fn remove_login_token(conn: &Connection, id: i64) -> bool { let query = r#" UPDATE users SET login_token = NULL, updated_at = datetime() WHERE id = :id "#; let res = conn .call(move |conn| Ok(conn.execute(query, named_params![":id": id])?)) .await; match res { Ok(_) => true, Err(err) => { log::error!("Error removing login token: {:?}", err); false } } } pub async fn get_by_login_token( conn: &Connection, login_token: String, ) -> Option { let query = r#" SELECT id, name, email FROM users WHERE login_token = :login_token "#; let res = conn .call(move |conn| { let mut stmt = conn.prepare(query)?; let mut iter = stmt.query_map( named_params![":login_token": login_token], row_to_user, )?; utils::one(&mut iter) }) .await; match res { Ok(user) => Some(user), Err(err) => { log::error!("Error getting user from login_token: {err:?}"); None } } } pub async fn get_password_hash( conn: &Connection, email: String, ) -> Option { let query = r#" SELECT password FROM users WHERE email = :email "#; let res = conn .call(move |conn| { let mut stmt = conn.prepare(query)?; let mut iter = stmt .query_map(named_params![":email": email], |row| row.get(0))?; utils::one::(&mut iter) }) .await; match res { Ok(hash) => Some(hash.clone()), Err(err) => { log::error!("Error listing users: {:?}", err); None } } }