185 lines
5.6 KiB
Rust
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>>()
|
|
}
|
|
}
|