Initial commit.
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
use rusqlite::Connection as RusqliteConnection;
|
||||
use std::env;
|
||||
use std::path::Path;
|
||||
use diesel::{Connection, SqliteConnection};
|
||||
|
||||
pub struct DatabaseConnection {
|
||||
pub connection: RusqliteConnection,
|
||||
pub diesel_connection: SqliteConnection,
|
||||
pub database_has_been_created: bool,
|
||||
}
|
||||
|
||||
impl DatabaseConnection {
|
||||
pub fn init() -> Self {
|
||||
let sqlite_database_name = env::var("SQLITE_DATABASE_NAME").expect("SQLITE_DATABASE_NAME must be set.");
|
||||
|
||||
let database_existed_before_connection_initialisation = does_database_exist(&sqlite_database_name);
|
||||
|
||||
let connection = RusqliteConnection::open(sqlite_database_name.clone())
|
||||
.expect("Unable to connect to SQLite database…");
|
||||
|
||||
let diesel_connection = SqliteConnection::establish(&sqlite_database_name.clone())
|
||||
.unwrap_or_else(|_| panic!("Error connecting to {}", sqlite_database_name.clone()));
|
||||
|
||||
Self {
|
||||
connection,
|
||||
diesel_connection,
|
||||
database_has_been_created: !database_existed_before_connection_initialisation
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn does_database_exist(database_name: &String) -> bool {
|
||||
Path::new(database_name).exists()
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
use std::sync::{Arc, Mutex};
|
||||
use rusqlite::{Connection, Error};
|
||||
|
||||
pub fn initialise_database_tables(connection: &Arc<Mutex<Connection>>) -> Result<(), Error> {
|
||||
connection.lock()
|
||||
.unwrap()
|
||||
.execute_batch(
|
||||
"
|
||||
BEGIN;
|
||||
CREATE TABLE IF NOT EXISTS configuration (
|
||||
id TEXT PRIMARY KEY,
|
||||
initialisation_code VARCHAR
|
||||
);
|
||||
CREATE TABLE IF NOT EXISTS system_resources (
|
||||
id TEXT PRIMARY KEY,
|
||||
datetime INTEGER NOT NULL,
|
||||
cpu_usage INTEGER NOT NULL,
|
||||
total_memory INTEGER NOT NULL,
|
||||
used_memory INTEGER NOT NULL
|
||||
);
|
||||
CREATE TABLE IF NOT EXISTS \"user\" (
|
||||
id TEXT PRIMARY KEY,
|
||||
username VARCHAR NOT NULL,
|
||||
encrypted_password VARCHAR NOT NULL
|
||||
);
|
||||
COMMIT;
|
||||
"
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
pub mod database_connection;
|
||||
pub mod database_initialisation;
|
||||
@@ -0,0 +1,46 @@
|
||||
use std::io::{Error, ErrorKind};
|
||||
use surveillant_systeme_domain::configuration::port::ConfigurationPort;
|
||||
use crate::configuration::repository::ConfigurationSqliteRepository;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ConfigurationSqliteAdapter {
|
||||
repository: ConfigurationSqliteRepository
|
||||
}
|
||||
|
||||
impl ConfigurationSqliteAdapter {
|
||||
pub fn new(repository: ConfigurationSqliteRepository) -> Self {
|
||||
Self {
|
||||
repository
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ConfigurationPort for ConfigurationSqliteAdapter {
|
||||
fn get_initialisation_code(&self) -> Result<Option<String>, Error> {
|
||||
self.repository.get_initialisation_code()
|
||||
.map_err(|error| Error::new(
|
||||
ErrorKind::Other,
|
||||
format!("Unable to retrieve the initialisation code… Cause: {}", error)
|
||||
))
|
||||
}
|
||||
|
||||
fn save(&self, initialisation_code: String) -> Result<(), Error> {
|
||||
self.repository.save(initialisation_code)
|
||||
.map_err(|error| Error::new(
|
||||
ErrorKind::Other,
|
||||
format!("Unable to save the initialisation code… Cause: {}", error)
|
||||
))
|
||||
}
|
||||
|
||||
fn erase_initialisation_code(&self) -> Result<(), Error> {
|
||||
self.repository.erase_initialisation_code()
|
||||
.map_err(|error| Error::new(
|
||||
ErrorKind::Other,
|
||||
format!("Unable to erase the initialisation code… Cause: {}", error)
|
||||
))
|
||||
}
|
||||
|
||||
fn clone_box(&self) -> Box<dyn ConfigurationPort> {
|
||||
Box::new(self.clone())
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
pub mod adapter;
|
||||
pub mod repository;
|
||||
@@ -0,0 +1,75 @@
|
||||
use std::sync::{Arc, Mutex, MutexGuard};
|
||||
use rusqlite::{Connection, Error};
|
||||
|
||||
const CONFIGURATION_ID: &'static str = "1";
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ConfigurationSqliteRepository {
|
||||
pub database_connection: Arc<Mutex<Connection>>
|
||||
}
|
||||
|
||||
impl ConfigurationSqliteRepository {
|
||||
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 configuration (
|
||||
id TEXT PRIMARY KEY,
|
||||
initialisation_code VARCHAR
|
||||
);",
|
||||
[]
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn get_initialisation_code(&self) -> Result<Option<String>, Error> {
|
||||
let connection = self.get_connection();
|
||||
let mut prepared_statement = connection.prepare(
|
||||
"SELECT initialisation_code
|
||||
FROM configuration
|
||||
WHERE id = ?1;"
|
||||
).expect("Unable to prepare statement to get initialisation code…");
|
||||
|
||||
let mut rows = prepared_statement.query([CONFIGURATION_ID])
|
||||
.expect("Unable to retrieve initialisation code…");
|
||||
|
||||
if let Some(row) = rows.next()? {
|
||||
let initialisation_code = row.get(0)?;
|
||||
Ok(initialisation_code)
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn save(&self, initialisation_code: String) -> Result<(), Error> {
|
||||
let connection = self.get_connection();
|
||||
let mut prepared_statement = connection.prepare(
|
||||
"INSERT INTO configuration (
|
||||
id,
|
||||
initialisation_code
|
||||
) VALUES (?1, ?2);"
|
||||
).expect("Unable to prepare statement for configuration saving…");
|
||||
|
||||
prepared_statement.execute(rusqlite::params![
|
||||
CONFIGURATION_ID,
|
||||
initialisation_code
|
||||
]).expect("Unable to insert configuration…");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn erase_initialisation_code(&self) -> Result<(), Error> {
|
||||
let connection = self.get_connection();
|
||||
let mut prepared_statement = connection.prepare(
|
||||
"UPDATE configuration SET initialisation_code = NULL WHERE id = ?1;"
|
||||
).expect("Unable to prepare statement to erase initialisation code…");
|
||||
prepared_statement.execute(rusqlite::params![CONFIGURATION_ID]).expect("Unable to erase initialisation code…");
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
pub mod common;
|
||||
pub mod configuration;
|
||||
pub mod schema;
|
||||
pub mod user;
|
||||
@@ -0,0 +1,21 @@
|
||||
use diesel::prelude::*;
|
||||
|
||||
// Define the user table structure matching the current SQL schema
|
||||
table! {
|
||||
user (id) {
|
||||
id -> Text,
|
||||
username -> Varchar,
|
||||
encrypted_password -> Varchar,
|
||||
}
|
||||
}
|
||||
|
||||
// Add system_resources table definition
|
||||
table! {
|
||||
system_resources (id) {
|
||||
id -> Text,
|
||||
datetime -> Integer,
|
||||
cpu_usage -> Float,
|
||||
total_memory -> BigInt,
|
||||
used_memory -> BigInt,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
use std::io::{Error, ErrorKind};
|
||||
use uuid::Uuid;
|
||||
use surveillant_systeme_domain::user::model::User;
|
||||
use surveillant_systeme_domain::user::port::UserPort;
|
||||
use crate::user::repository::UserSqliteRepository;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct UserSqliteAdapter {
|
||||
pub repository: UserSqliteRepository
|
||||
}
|
||||
|
||||
impl UserSqliteAdapter {
|
||||
pub fn new(repository: UserSqliteRepository) -> Self {
|
||||
Self {
|
||||
repository
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl UserPort for UserSqliteAdapter {
|
||||
fn get_by_id(&self, id: &Uuid) -> Result<Option<User>, Error> {
|
||||
self.repository.get_by_id(id)
|
||||
.map_err(|error| Error::new(
|
||||
ErrorKind::Other,
|
||||
format!("Unable to get the user by its id… Cause: {}", error)
|
||||
))
|
||||
}
|
||||
|
||||
fn get_by_username(&self, username: &String) -> Result<Option<User>, Error> {
|
||||
self.repository.get_by_username(username)
|
||||
.map_err(|error| Error::new(
|
||||
ErrorKind::Other,
|
||||
format!("Unable to get the user by its username… Cause: {}", error)
|
||||
))
|
||||
}
|
||||
|
||||
fn get_all(&self) -> Result<Vec<User>, Error> {
|
||||
self.repository.get_all()
|
||||
.map_err(|error| Error::new(
|
||||
ErrorKind::Other,
|
||||
format!("Unable to get all users… Cause: {}", error)
|
||||
))
|
||||
}
|
||||
|
||||
fn count(&self) -> Result<u8, Error> {
|
||||
self.repository.count()
|
||||
.map_err(|error| Error::new(
|
||||
ErrorKind::Other,
|
||||
format!("Unable to count users… Cause: {}", error)
|
||||
))
|
||||
}
|
||||
|
||||
fn exists_by_name(&self, username: &String) -> Result<bool, Error> {
|
||||
self.repository.exists_by_name(username)
|
||||
.map_err(|error| Error::new(
|
||||
ErrorKind::Other,
|
||||
format!("Unable to check if a user exists by its name… Cause: {}", error)
|
||||
))
|
||||
}
|
||||
|
||||
fn insert(&self, user: &User) -> Result<(), Error> {
|
||||
self.repository.insert(user)
|
||||
.map_err(|error| Error::new(
|
||||
ErrorKind::Other,
|
||||
format!("Unable to insert the user… Cause: {}", error)
|
||||
))
|
||||
}
|
||||
|
||||
fn update(&self, user: &User) -> Result<(), Error> {
|
||||
self.repository.update(user)
|
||||
.map_err(|error| Error::new(
|
||||
ErrorKind::Other,
|
||||
format!("Unable to update the user… Cause: {}", error)
|
||||
))
|
||||
}
|
||||
|
||||
fn delete_by_id(&self, id: &Uuid) -> Result<(), Error> {
|
||||
self.repository.delete_by_id(id)
|
||||
.map_err(|error| Error::new(
|
||||
ErrorKind::Other,
|
||||
format!("Unable to delete the user by its id… Cause: {}", error)
|
||||
))
|
||||
}
|
||||
|
||||
fn clone_box(&self) -> Box<dyn UserPort> {
|
||||
Box::new(self.clone())
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
use std::io::{Error, ErrorKind};
|
||||
use uuid::Uuid;
|
||||
use surveillant_systeme_domain::user::model::User;
|
||||
use surveillant_systeme_domain::user::port::UserPort;
|
||||
use crate::user::diesel_repository::UserDieselRepository;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct UserDieselAdapter {
|
||||
pub repository: UserDieselRepository
|
||||
}
|
||||
|
||||
impl UserDieselAdapter {
|
||||
pub fn new(repository: UserDieselRepository) -> Self {
|
||||
Self {
|
||||
repository
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl UserPort for UserDieselAdapter {
|
||||
fn get_by_id(&self, id: &Uuid) -> Result<Option<User>, Error> {
|
||||
match self.repository.get_by_id(id) {
|
||||
Ok(option_user_entity) => Ok(option_user_entity.map(|user_entity| user_entity.to_domain())),
|
||||
Err(diesel::result::Error::NotFound) => Ok(None),
|
||||
Err(e) => Err(Error::new(
|
||||
ErrorKind::Other,
|
||||
format!("Unable to get the user by its id… Cause: {}", e)
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_by_username(&self, username: &String) -> Result<Option<User>, Error> {
|
||||
self.repository.get_by_username(username)
|
||||
.map_err(|error| Error::new(
|
||||
ErrorKind::Other,
|
||||
format!("Unable to get the user by its username… Cause: {}", error)
|
||||
))
|
||||
.map(|option_user_entity| option_user_entity.map(|user_entity| user_entity.to_domain()))
|
||||
}
|
||||
|
||||
fn get_all(&self) -> Result<Vec<User>, Error> {
|
||||
self.repository.get_all()
|
||||
.map_err(|error| Error::new(
|
||||
ErrorKind::Other,
|
||||
format!("Unable to get all users… Cause: {}", error)
|
||||
))
|
||||
.map(|user_entities| user_entities.into_iter().map(|user_entity| user_entity.to_domain()).collect())
|
||||
}
|
||||
|
||||
fn count(&self) -> Result<u8, Error> {
|
||||
self.repository.count()
|
||||
.map_err(|error| Error::new(
|
||||
ErrorKind::Other,
|
||||
format!("Unable to count users… Cause: {}", error)
|
||||
))
|
||||
}
|
||||
|
||||
fn exists_by_name(&self, username: &String) -> Result<bool, Error> {
|
||||
self.repository.exists_by_name(username)
|
||||
.map_err(|error| Error::new(
|
||||
ErrorKind::Other,
|
||||
format!("Unable to check if a user exists by its name… Cause: {}", error)
|
||||
))
|
||||
}
|
||||
|
||||
fn insert(&self, user: &User) -> Result<(), Error> {
|
||||
let user_entity = crate::user::model::UserEntity::from(user);
|
||||
self.repository.insert(&user_entity)
|
||||
.map_err(|error| Error::new(
|
||||
ErrorKind::Other,
|
||||
format!("Unable to insert the user… Cause: {}", error)
|
||||
))
|
||||
}
|
||||
|
||||
fn update(&self, user: &User) -> Result<(), Error> {
|
||||
let user_entity = crate::user::model::UserEntity::from(user);
|
||||
self.repository.update(&user_entity)
|
||||
.map_err(|error| Error::new(
|
||||
ErrorKind::Other,
|
||||
format!("Unable to update the user… Cause: {}", error)
|
||||
))
|
||||
}
|
||||
|
||||
fn delete_by_id(&self, id: &Uuid) -> Result<(), Error> {
|
||||
self.repository.delete_by_id(id)
|
||||
.map_err(|error| Error::new(
|
||||
ErrorKind::Other,
|
||||
format!("Unable to delete the user by its id… Cause: {}", error)
|
||||
))
|
||||
}
|
||||
|
||||
fn clone_box(&self) -> Box<dyn UserPort> {
|
||||
Box::new(self.clone())
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
use diesel::prelude::*;
|
||||
use diesel::sqlite::SqliteConnection;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use uuid::Uuid;
|
||||
use super::model::UserEntity;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct UserDieselRepository {
|
||||
pub database_connection: Arc<Mutex<SqliteConnection>>,
|
||||
}
|
||||
|
||||
impl UserDieselRepository {
|
||||
pub fn new(database_connection: Arc<Mutex<SqliteConnection>>) -> Self {
|
||||
Self {
|
||||
database_connection,
|
||||
}
|
||||
}
|
||||
|
||||
fn get_connection(&self) -> std::sync::MutexGuard<'_, SqliteConnection> {
|
||||
self.database_connection.lock().unwrap()
|
||||
}
|
||||
|
||||
pub fn create_table(&self) -> Result<(), diesel::result::Error> {
|
||||
let mut connection = self.get_connection();
|
||||
diesel::sql_query(
|
||||
"CREATE TABLE IF NOT EXISTS \"user\" (
|
||||
id TEXT PRIMARY KEY,
|
||||
username VARCHAR NOT NULL,
|
||||
encrypted_password VARCHAR NOT NULL
|
||||
);"
|
||||
).execute(&mut *connection)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn insert(&self, user: &UserEntity) -> Result<(), diesel::result::Error> {
|
||||
let mut connection = self.get_connection();
|
||||
|
||||
diesel::insert_into(crate::schema::user::table)
|
||||
.values(user)
|
||||
.execute(&mut *connection)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn update(&self, user: &UserEntity) -> Result<(), diesel::result::Error> {
|
||||
let mut connection = self.get_connection();
|
||||
|
||||
diesel::update(crate::schema::user::table.find(&user.id.to_string()))
|
||||
.set((crate::schema::user::username.eq(user.username.clone()),
|
||||
crate::schema::user::encrypted_password.eq(user.encrypted_password.clone())))
|
||||
.execute(&mut *connection)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn delete_by_id(&self, id: &Uuid) -> Result<(), diesel::result::Error> {
|
||||
let mut connection = self.get_connection();
|
||||
|
||||
diesel::delete(crate::schema::user::table.find(id.to_string()))
|
||||
.execute(&mut *connection)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn count(&self) -> Result<u8, diesel::result::Error> {
|
||||
let mut connection = self.get_connection();
|
||||
|
||||
let count: i64 = crate::schema::user::table.count().get_result(&mut *connection)?;
|
||||
Ok(count as u8)
|
||||
}
|
||||
|
||||
pub fn get_by_id(&self, id: &Uuid) -> Result<Option<UserEntity>, diesel::result::Error> {
|
||||
let mut connection = self.get_connection();
|
||||
|
||||
let result: Result<UserEntity, _> = crate::schema::user::table
|
||||
.find(id.to_string())
|
||||
.first(&mut *connection);
|
||||
|
||||
match result {
|
||||
Ok(user_diesel) => Ok(Some(user_diesel)),
|
||||
Err(e) => Err(e),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn exists_by_name(&self, username: &String) -> Result<bool, diesel::result::Error> {
|
||||
let mut connection = self.get_connection();
|
||||
|
||||
let count: i64 = crate::schema::user::table
|
||||
.filter(crate::schema::user::username.eq(username))
|
||||
.count()
|
||||
.get_result(&mut *connection)?;
|
||||
Ok(count > 0)
|
||||
}
|
||||
|
||||
pub fn get_by_username(&self, username: &String) -> Result<Option<UserEntity>, diesel::result::Error> {
|
||||
let mut connection = self.get_connection();
|
||||
|
||||
let result: Result<UserEntity, _> = crate::schema::user::table
|
||||
.filter(crate::schema::user::username.eq(username))
|
||||
.first(&mut *connection);
|
||||
|
||||
match result {
|
||||
Ok(user_diesel) => Ok(Some(user_diesel)),
|
||||
Err(diesel::result::Error::NotFound) => Ok(None),
|
||||
Err(e) => Err(e),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_all(&self) -> Result<Vec<UserEntity>, diesel::result::Error> {
|
||||
let mut connection = self.get_connection();
|
||||
|
||||
let users: Vec<UserEntity> = crate::schema::user::table
|
||||
.order(crate::schema::user::username.asc())
|
||||
.load(&mut *connection)?;
|
||||
|
||||
Ok(users)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
pub mod adapter;
|
||||
pub mod diesel_adapter;
|
||||
pub mod diesel_repository;
|
||||
pub mod model;
|
||||
pub mod repository;
|
||||
@@ -0,0 +1,31 @@
|
||||
use surveillant_systeme_domain::user::model::User;
|
||||
use diesel::prelude::*;
|
||||
use uuid::Uuid;
|
||||
|
||||
#[derive(Queryable, Identifiable, Insertable, AsChangeset)]
|
||||
#[diesel(table_name = crate::schema::user)]
|
||||
pub struct UserEntity {
|
||||
pub id: String,
|
||||
pub username: String,
|
||||
pub encrypted_password: String,
|
||||
}
|
||||
|
||||
impl UserEntity {
|
||||
pub fn to_domain(&self) -> User {
|
||||
User {
|
||||
id: Uuid::parse_str(&self.id).unwrap(),
|
||||
username: self.username.clone(),
|
||||
encrypted_password: self.encrypted_password.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&User> for UserEntity {
|
||||
fn from(user: &User) -> Self {
|
||||
UserEntity {
|
||||
id: user.id.to_string(),
|
||||
username: user.username.clone(),
|
||||
encrypted_password: user.encrypted_password.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,184 @@
|
||||
use rusqlite::fallible_iterator::FallibleIterator;
|
||||
use rusqlite::{Connection, Error, Row};
|
||||
use std::sync::{Arc, Mutex, MutexGuard};
|
||||
use log::warn;
|
||||
use uuid::Uuid;
|
||||
use surveillant_systeme_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>>()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user