From 37322b13a7225c5eff225d629b7b3ce3f68b3270 Mon Sep 17 00:00:00 2001 From: trivernis Date: Sun, 30 Jan 2022 15:03:00 +0100 Subject: [PATCH] Implement integrity check Signed-off-by: trivernis --- mediarepo-daemon/mediarepo-core/src/error.rs | 5 ++- .../dao/job/migrate_content_descriptors.rs | 1 + .../mediarepo-logic/src/dao/job/mod.rs | 1 + .../src/dao/job/sqlite_operations.rs | 44 +++++++++++++++++++ .../mediarepo-socket/src/namespaces/jobs.rs | 2 +- 5 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 mediarepo-daemon/mediarepo-logic/src/dao/job/sqlite_operations.rs diff --git a/mediarepo-daemon/mediarepo-core/src/error.rs b/mediarepo-daemon/mediarepo-core/src/error.rs index 820e854..7f5dfbc 100644 --- a/mediarepo-daemon/mediarepo-core/src/error.rs +++ b/mediarepo-daemon/mediarepo-core/src/error.rs @@ -38,8 +38,11 @@ pub enum RepoError { #[error("failed to decode data {0}")] Decode(#[from] data_encoding::DecodeError), - #[error("Failed to read repo.toml configuration file {0}")] + #[error("failed to read repo.toml configuration file {0}")] Config(#[from] config::ConfigError), + + #[error("the database file is corrupted {0}")] + Corrupted(String), } #[derive(Error, Debug)] diff --git a/mediarepo-daemon/mediarepo-logic/src/dao/job/migrate_content_descriptors.rs b/mediarepo-daemon/mediarepo-logic/src/dao/job/migrate_content_descriptors.rs index a339cc8..6c395fe 100644 --- a/mediarepo-daemon/mediarepo-logic/src/dao/job/migrate_content_descriptors.rs +++ b/mediarepo-daemon/mediarepo-logic/src/dao/job/migrate_content_descriptors.rs @@ -9,6 +9,7 @@ use sea_orm::ActiveValue::Set; use sea_orm::ConnectionTrait; impl JobDao { + #[tracing::instrument(level = "debug", skip(self))] pub async fn migrate_content_descriptors(&self) -> RepoResult<()> { let cds: Vec = content_descriptor::Entity::find().all(&self.ctx.db).await?; diff --git a/mediarepo-daemon/mediarepo-logic/src/dao/job/mod.rs b/mediarepo-daemon/mediarepo-logic/src/dao/job/mod.rs index 1d6c510..c47b28a 100644 --- a/mediarepo-daemon/mediarepo-logic/src/dao/job/mod.rs +++ b/mediarepo-daemon/mediarepo-logic/src/dao/job/mod.rs @@ -1,4 +1,5 @@ pub mod migrate_content_descriptors; +pub mod sqlite_operations; use crate::dao::{DaoContext, DaoProvider}; diff --git a/mediarepo-daemon/mediarepo-logic/src/dao/job/sqlite_operations.rs b/mediarepo-daemon/mediarepo-logic/src/dao/job/sqlite_operations.rs new file mode 100644 index 0000000..132bdf9 --- /dev/null +++ b/mediarepo-daemon/mediarepo-logic/src/dao/job/sqlite_operations.rs @@ -0,0 +1,44 @@ +use crate::dao::job::JobDao; +use mediarepo_core::error::RepoError::Corrupted; +use mediarepo_core::error::RepoResult; +use sea_orm::DatabaseBackend::Sqlite; +use sea_orm::{ConnectionTrait, FromQueryResult, Statement}; + +#[derive(Debug, FromQueryResult)] +struct IntegrityCheckResult { + integrity_check: String, +} + +impl JobDao { + #[tracing::instrument(level = "debug", skip(self))] + pub async fn check_integrity(&self) -> RepoResult<()> { + let check_result: Option = IntegrityCheckResult::find_by_statement( + Statement::from_string(Sqlite, String::from("PRAGMA integrity_check;")), + ) + .one(&self.ctx.db) + .await?; + tracing::debug!("check result = {:?}", check_result); + + check_result + .ok_or_else(|| Corrupted(String::from("no check result"))) + .and_then(map_check_result) + } + + #[tracing::instrument(level = "debug", skip(self))] + pub async fn vacuum(&self) -> RepoResult<()> { + self.ctx + .db + .execute(Statement::from_string(Sqlite, String::from("VACUUM;"))) + .await?; + + Ok(()) + } +} + +fn map_check_result(result: IntegrityCheckResult) -> RepoResult<()> { + if result.integrity_check == "ok" { + Ok(()) + } else { + Err(Corrupted(result.integrity_check)) + } +} diff --git a/mediarepo-daemon/mediarepo-socket/src/namespaces/jobs.rs b/mediarepo-daemon/mediarepo-socket/src/namespaces/jobs.rs index 208c5ce..d345e42 100644 --- a/mediarepo-daemon/mediarepo-socket/src/namespaces/jobs.rs +++ b/mediarepo-daemon/mediarepo-socket/src/namespaces/jobs.rs @@ -30,7 +30,7 @@ impl JobsNamespace { match run_request.job_type { JobType::MigrateContentDescriptors => job_dao.migrate_content_descriptors().await?, JobType::CalculateSizes => calculate_all_sizes(ctx).await?, - JobType::CheckIntegrity => {} + JobType::CheckIntegrity => job_dao.check_integrity().await?, } ctx.emit_to(Self::name(), "run_job", ()).await?;