Files
lumi-re/backend/infrastructure/src/user/repository.rs
T

185 lines
5.6 KiB
Rust

use rusqlite::fallible_iterator::FallibleIterator;
use rusqlite::{Connection, Error, Row};
use std::sync::{Arc, Mutex, MutexGuard};
use log::warn;
use uuid::Uuid;
use lumiere_domain::user::model::User;
#[derive(Clone)]
pub struct UserSqliteRepository {
pub database_connection: Arc<Mutex<Connection>>,
}
impl UserSqliteRepository {
pub fn new(database_connection: Arc<Mutex<Connection>>) -> Self {
Self {
database_connection,
}
}
fn get_connection(&self) -> MutexGuard<'_, Connection> {
self.database_connection.lock().unwrap()
}
pub fn create_table(&self) -> Result<(), Error> {
let connection = self.get_connection();
connection.execute(
"CREATE TABLE IF NOT EXISTS \"user\" (
id TEXT PRIMARY KEY,
username VARCHAR NOT NULL,
encrypted_password VARCHAR NOT NULL
);",
[]
)?;
Ok(())
}
pub fn insert(&self, user: &User) -> rusqlite::Result<()> {
let database_connection = self.get_connection();
let mut prepared_statement = database_connection
.prepare(
"INSERT INTO \"user\" (
id,
username,
encrypted_password
) VALUES (?1, ?2, ?3);",
)
.expect("Unable to prepare statement for user saving…");
prepared_statement.execute(rusqlite::params![
user.id.to_string(),
user.username,
user.encrypted_password
]).expect("Unable to insert user.");
Ok(())
}
pub fn update(&self, user: &User) -> rusqlite::Result<()> {
let database_connection = self.get_connection();
let mut prepared_statement = database_connection
.prepare(
"UPDATE \"user\" SET
username = ?1,
encrypted_password = ?2
WHERE id = ?3;",
)
.expect("Unable to prepare statement for user saving…");
prepared_statement.execute(rusqlite::params![
user.username,
user.encrypted_password,
user.id.to_string()
]).expect("Unable to update user.");
Ok(())
}
pub fn delete_by_id(&self, id: &Uuid) -> rusqlite::Result<()> {
let database_connection = self.get_connection();
let mut prepared_statement = database_connection
.prepare("DELETE FROM \"user\" WHERE id = ?1;")
.expect("Unable to prepare statement for user deletion…");
prepared_statement.execute(rusqlite::params![id.to_string()])
.expect("Unable to delete the user…");
Ok(())
}
pub fn count(&self) -> rusqlite::Result<u8> {
let database_connection = self.get_connection();
let mut prepared_statement = database_connection
.prepare("SELECT COUNT(1) FROM \"user\";")
.expect("Unable to prepare statement for user counting…");
let mut rows = prepared_statement.query([])?;
if let Some(row) = rows.next()? {
Ok(row.get(0)?)
} else {
Ok(0)
}
}
pub fn get_by_id(&self, id: &Uuid) -> rusqlite::Result<Option<User>> {
let database_connection = self.get_connection();
let mut prepared_statement = database_connection.prepare(
"SELECT
id,
username,
encrypted_password
FROM \"user\"\
WHERE id = ?1;"
)?;
let mut rows = prepared_statement.query([id.to_string()])?;
if let Some(row) = rows.next()? {
Ok(Some(Self::map_to_user(&row)?))
} else {
Ok(None)
}
}
pub fn exists_by_name(&self, username: &String) -> rusqlite::Result<bool> {
let database_connection = self.get_connection();
let mut prepared_statement = database_connection.prepare(
"SELECT EXISTS(
SELECT 1
FROM \"user\"
WHERE username = ?1\
);"
)?;
let mut rows = prepared_statement.query([username])?;
if let Some(row) = rows.next()? {
Ok(row.get(0)?)
} else {
warn!("No result for exists_by_name repository function.");
Ok(false)
}
}
pub fn get_by_username(&self, username: &String) -> rusqlite::Result<Option<User>> {
let database_connection = self.get_connection();
let mut prepared_statement = database_connection.prepare(
"SELECT
id,
username,
encrypted_password
FROM \"user\"\
WHERE username = ?1;"
)?;
let mut rows = prepared_statement.query([username])?;
if let Some(row) = rows.next()? {
Ok(Some(Self::map_to_user(&row)?))
} else {
Ok(None)
}
}
fn map_to_user(row: &Row) -> Result<User, Error> {
let id_text: String = row.get(0)?;
Ok(User {
id: Uuid::parse_str(&id_text).unwrap(),
username: row.get(1)?,
encrypted_password: row.get(2)?,
})
}
pub fn get_all(&self) -> Result<Vec<User>, Error> {
let database_connection = self.get_connection();
let mut prepared_statement = database_connection.prepare(
"SELECT
id,
username,
encrypted_password
FROM \"user\"",
)?;
let rows = prepared_statement.query([])?;
rows.map(UserSqliteRepository::map_to_user).collect::<Vec<User>>()
}
}