diff --git a/src/database/content_folder/folder_view.rs b/src/database/content_folder/folder_view.rs index 9c8933a..6889bc7 100644 --- a/src/database/content_folder/folder_view.rs +++ b/src/database/content_folder/folder_view.rs @@ -15,7 +15,7 @@ pub struct FolderView { impl FolderView { /// Loads the top-most folder view, which is not a folder and may not have parents. - pub async fn index(operator: &ContentFolderOperator) -> Result { + pub async fn index(operator: &ContentFolderOperator<'_>) -> Result { let children = operator .list() .await? @@ -37,7 +37,7 @@ impl FolderView { /// - the requested ID does not exist // TODO: optimize with custom query pub async fn from_id( - operator: &ContentFolderOperator, + operator: &ContentFolderOperator<'_>, id: i32, ) -> Result { let list = operator.list().await?; diff --git a/src/database/content_folder/operator.rs b/src/database/content_folder/operator.rs index 6789f4c..6a51079 100644 --- a/src/database/content_folder/operator.rs +++ b/src/database/content_folder/operator.rs @@ -1,37 +1,35 @@ -use chrono::Utc; use sea_orm::*; use snafu::prelude::*; +use std::ops::Deref; use std::str::FromStr; -use crate::database::operation::OperationLog; -use crate::database::operation::OperationType; use crate::database::operation::Table; -use crate::database::operator::DatabaseOperator; +use crate::database::operator::{DatabaseOperator, TableOperator}; use crate::extractors::normalized_path::NormalizedPathComponent; -use crate::extractors::user::User; -use crate::state::AppState; use super::*; #[derive(Clone, Debug)] -pub struct ContentFolderOperator { - pub state: AppState, - pub user: Option, +pub struct ContentFolderOperator<'a> { + pub db: &'a DatabaseOperator, } -impl ContentFolderOperator { - pub fn new(state: AppState, user: Option) -> Self { - Self { state, user } +impl Deref for ContentFolderOperator<'_> { + type Target = DatabaseOperator; + + fn deref(&self) -> &DatabaseOperator { + self.db } +} - pub fn db(&self) -> DatabaseOperator { - DatabaseOperator { - state: self.state.clone(), - user: self.user.clone(), - } +impl TableOperator for ContentFolderOperator<'_> { + fn table(&self) -> Table { + Table::ContentFolder } +} +impl ContentFolderOperator<'_> { /// List content folders /// /// Should not fail, unless SQLite was corrupted for some reason. @@ -106,24 +104,13 @@ impl ContentFolderOperator { .context(IOSnafu)?; } - let operation_log = OperationLog { - user: self.user.clone(), - date: Utc::now(), - operation: ContentFolderOperation::Create { - id: model.id, - name: model.name.to_string(), - parent: parent.as_ref().map(|x| (x.id, x.name.to_string())), - } - .into(), - operation_type: OperationType::Create, - table: Table::ContentFolder, - }; - - self.state - .logger - .write(operation_log) - .await - .context(LoggerSnafu)?; + self.log_create(ContentFolderOperation::Create { + id: model.id, + name: model.name.to_string(), + parent: parent.as_ref().map(|x| (x.id, x.name.to_string())), + }) + .await + .context(LoggerSnafu)?; Ok(model) } diff --git a/src/database/operator.rs b/src/database/operator.rs index b4115e3..8bce469 100644 --- a/src/database/operator.rs +++ b/src/database/operator.rs @@ -1,6 +1,37 @@ +use chrono::Utc; + +use std::ops::Deref; + use crate::database::content_folder::ContentFolderOperator; +use crate::database::operation::{Operation, OperationLog, OperationType, Table}; use crate::extractors::user::User; use crate::state::AppState; +use crate::state::logger::LoggerError; + +pub trait TableOperator: Deref { + fn table(&self) -> Table; + + fn log_create( + &self, + operation: impl Into, + ) -> impl std::future::Future> { + self.log(self.table(), OperationType::Create, operation.into()) + } + + fn log_update( + &self, + operation: impl Into, + ) -> impl std::future::Future> { + self.log(self.table(), OperationType::Update, operation.into()) + } + + fn log_delete( + &self, + operation: impl Into, + ) -> impl std::future::Future> { + self.log(self.table(), OperationType::Delete, operation.into()) + } +} #[derive(Clone, Debug)] pub struct DatabaseOperator { @@ -13,10 +44,24 @@ impl DatabaseOperator { Self { state, user } } - pub fn content_folder(&self) -> ContentFolderOperator { - ContentFolderOperator { - state: self.state.clone(), + pub async fn log( + &self, + table: Table, + operation_type: OperationType, + operation: Operation, + ) -> Result<(), LoggerError> { + let operation = OperationLog { user: self.user.clone(), - } + date: Utc::now(), + operation, + operation_type, + table, + }; + + self.state.logger.write(operation).await + } + + pub fn content_folder<'a>(&'a self) -> ContentFolderOperator<'a> { + ContentFolderOperator { db: self } } }