From 12d85b50cc0cce5dbe33bc3a88fffb229516ca6b Mon Sep 17 00:00:00 2001 From: trivernis Date: Sat, 5 Feb 2022 18:28:55 +0100 Subject: [PATCH] Fix preset creation Signed-off-by: trivernis --- ..._fix-uniqueness-of-sorting-preset-keys.sql | 17 +++++ .../src/entities/sorting_preset_key.rs | 1 + .../src/dao/sorting_preset/add.rs | 62 +++++++++++++------ .../src/dao/sorting_preset/mod.rs | 6 +- .../src/namespaces/files/mod.rs | 6 +- .../src/namespaces/presets.rs | 2 + 6 files changed, 67 insertions(+), 27 deletions(-) create mode 100644 mediarepo-daemon/mediarepo-database/migrations/20220205165133_fix-uniqueness-of-sorting-preset-keys.sql diff --git a/mediarepo-daemon/mediarepo-database/migrations/20220205165133_fix-uniqueness-of-sorting-preset-keys.sql b/mediarepo-daemon/mediarepo-database/migrations/20220205165133_fix-uniqueness-of-sorting-preset-keys.sql new file mode 100644 index 0000000..e2b3c71 --- /dev/null +++ b/mediarepo-daemon/mediarepo-database/migrations/20220205165133_fix-uniqueness-of-sorting-preset-keys.sql @@ -0,0 +1,17 @@ +PRAGMA foreign_keys= off; +ALTER TABLE sorting_preset_keys + RENAME TO _sorting_preset_keys_old; + +CREATE TABLE sorting_preset_keys +( + preset_id INTEGER REFERENCES sorting_presets (id) ON DELETE CASCADE, + key_id INTEGER REFERENCES sort_keys (id), + key_index INTEGER NOT NULL DEFAULT 0, + PRIMARY KEY (preset_id, key_id, key_index) +); + +INSERT INTO sorting_preset_keys SELECT * FROM _sorting_preset_keys_old; + +DROP TABLE _sorting_preset_keys_old; + +PRAGMA foreign_keys= on; diff --git a/mediarepo-daemon/mediarepo-database/src/entities/sorting_preset_key.rs b/mediarepo-daemon/mediarepo-database/src/entities/sorting_preset_key.rs index 4381031..6d882db 100644 --- a/mediarepo-daemon/mediarepo-database/src/entities/sorting_preset_key.rs +++ b/mediarepo-daemon/mediarepo-database/src/entities/sorting_preset_key.rs @@ -9,6 +9,7 @@ pub struct Model { #[sea_orm(primary_key)] key_id: i32, + #[sea_orm(primary_key)] key_index: i32, } diff --git a/mediarepo-daemon/mediarepo-logic/src/dao/sorting_preset/add.rs b/mediarepo-daemon/mediarepo-logic/src/dao/sorting_preset/add.rs index f8e51f6..81c8aeb 100644 --- a/mediarepo-daemon/mediarepo-logic/src/dao/sorting_preset/add.rs +++ b/mediarepo-daemon/mediarepo-logic/src/dao/sorting_preset/add.rs @@ -4,7 +4,13 @@ use mediarepo_core::error::RepoResult; use mediarepo_database::entities::{sort_key, sorting_preset, sorting_preset_key}; use sea_orm::prelude::*; use sea_orm::ActiveValue::Set; -use sea_orm::{Condition, ConnectionTrait, DatabaseTransaction, JoinType, QuerySelect}; +use sea_orm::{ + Condition, ConnectionTrait, DatabaseTransaction, DbBackend, FromQueryResult, JoinType, + QuerySelect, Statement, +}; + +#[allow(unused_imports)] +use sea_orm::TryGetableMany; // otherwise intellijrust hates on me impl SortingPresetDao { #[tracing::instrument(level = "debug", skip(self))] @@ -33,10 +39,17 @@ impl SortingPresetDao { trx.commit().await?; return Ok(SortingPresetDto::new(model, keys)); } - let preset_model = sorting_preset::ActiveModel { - ..Default::default() - }; - let preset_model = preset_model.insert(&trx).await?; + + // sea_orm currently doesn't support all-default-value inserts. + // TODOD: Replace after the change for default inserts has been merged + let preset_model = sorting_preset::Model::find_by_statement(Statement::from_string( + DbBackend::Sqlite, + "INSERT INTO sorting_presets DEFAULT VALUES RETURNING *;".to_string(), + )) + .one(&trx) + .await? + .expect("failed to insert new sorting preset"); + let mapping_models = key_ids .into_iter() .map(|(idx, key)| sorting_preset_key::ActiveModel { @@ -45,9 +58,12 @@ impl SortingPresetDao { key_index: Set(idx as i32), }) .collect::>(); - sorting_preset_key::Entity::insert_many(mapping_models) - .exec(&trx) - .await?; + + if !mapping_models.is_empty() { + sorting_preset_key::Entity::insert_many(mapping_models) + .exec(&trx) + .await?; + } trx.commit().await?; Ok(SortingPresetDto::new(preset_model, keys)) @@ -56,19 +72,21 @@ impl SortingPresetDao { async fn add_keys( trx: &DatabaseTransaction, - mut keys: Vec, + keys: Vec, ) -> RepoResult> { let mut key_dtos = find_sort_keys(trx, &keys).await?; + let mut insert_keys = keys.clone(); + key_dtos.iter().for_each(|key| { - keys.retain(|k| { + insert_keys.retain(|k| { k.ascending != key.ascending() - && Some(k.key_type) != key.key_type() - && key.value() != key.value() + || k.key_type != key.key_type().unwrap() + || !compare_opts_eq(key.value(), k.value.as_ref()) }) }); - if !keys.is_empty() { - let active_models: Vec = keys + if !insert_keys.is_empty() { + let active_models: Vec = insert_keys .iter() .cloned() .map(|key| sort_key::ActiveModel { @@ -81,7 +99,7 @@ async fn add_keys( sort_key::Entity::insert_many(active_models) .exec(trx) .await?; - let mut new_keys = find_sort_keys(trx, &keys).await?; + let mut new_keys = find_sort_keys(trx, &insert_keys).await?; key_dtos.append(&mut new_keys); } @@ -91,9 +109,9 @@ async fn add_keys( key_dtos .iter() .find(|key| { - k.ascending != key.ascending() - && Some(k.key_type) != key.key_type() - && key.value() != key.value() + k.ascending == key.ascending() + && k.key_type == key.key_type().unwrap() + && compare_opts_eq(key.value(), k.value.as_ref()) }) .cloned() }) @@ -144,3 +162,11 @@ fn create_mapping_condition(entry: (usize, i32)) -> Condition { .add(sorting_preset_key::Column::KeyId.eq(entry.1)) .add(sorting_preset_key::Column::KeyIndex.eq(entry.0 as i32)) } + +fn compare_opts_eq(opt1: Option, opt2: Option) -> bool { + if let (Some(opt1), Some(opt2)) = (&opt1, &opt2) { + opt1 == opt2 + } else { + opt1.is_none() && opt2.is_none() + } +} diff --git a/mediarepo-daemon/mediarepo-logic/src/dao/sorting_preset/mod.rs b/mediarepo-daemon/mediarepo-logic/src/dao/sorting_preset/mod.rs index a265aa5..06fbf1c 100644 --- a/mediarepo-daemon/mediarepo-logic/src/dao/sorting_preset/mod.rs +++ b/mediarepo-daemon/mediarepo-logic/src/dao/sorting_preset/mod.rs @@ -5,7 +5,7 @@ use crate::dto::{SortKeyDto, SortingPresetDto}; use mediarepo_core::error::RepoResult; use mediarepo_database::entities::{sort_key, sorting_preset, sorting_preset_key}; use sea_orm::prelude::*; -use sea_orm::{JoinType, QueryOrder, QuerySelect}; +use sea_orm::QueryOrder; dao_provider!(SortingPresetDao); @@ -14,10 +14,6 @@ impl SortingPresetDao { pub async fn all(&self) -> RepoResult> { let presets = sorting_preset::Entity::find() .find_with_related(sort_key::Entity) - .join( - JoinType::InnerJoin, - sorting_preset_key::Relation::SortingKey.def(), - ) .order_by_asc(sorting_preset_key::Column::KeyIndex) .all(&self.ctx.db) .await? diff --git a/mediarepo-daemon/mediarepo-socket/src/namespaces/files/mod.rs b/mediarepo-daemon/mediarepo-socket/src/namespaces/files/mod.rs index 644a6f0..339b6bd 100644 --- a/mediarepo-daemon/mediarepo-socket/src/namespaces/files/mod.rs +++ b/mediarepo-daemon/mediarepo-socket/src/namespaces/files/mod.rs @@ -291,10 +291,8 @@ impl FilesNamespace { let found_thumbnail = thumbnails.into_iter().find(|thumb| { let Dimensions { height, width } = thumb.size(); - *height >= min_size.0 - && *height <= max_size.0 - && *width >= min_size.1 - && *width <= max_size.1 + (*height <= max_size.0 && *width <= max_size.1) + && (*width >= min_size.1 || *height >= min_size.0) }); let thumbnail = if let Some(thumbnail) = found_thumbnail { diff --git a/mediarepo-daemon/mediarepo-socket/src/namespaces/presets.rs b/mediarepo-daemon/mediarepo-socket/src/namespaces/presets.rs index 1e2ad3c..fbcd50c 100644 --- a/mediarepo-daemon/mediarepo-socket/src/namespaces/presets.rs +++ b/mediarepo-daemon/mediarepo-socket/src/namespaces/presets.rs @@ -65,6 +65,8 @@ impl PresetsNamespace { let id = event.payload::()?; let repo = get_repo_from_context(ctx).await; repo.sorting_preset().delete(id).await?; + ctx.emit_to(Self::name(), "delete_sorting_preset", ()) + .await?; Ok(()) }