From c2244acd01bae366d1b9950bb3678d60a03f6ce3 Mon Sep 17 00:00:00 2001 From: RumovZ Date: Sun, 5 Jun 2022 10:55:49 +0200 Subject: [PATCH] Skip importing foreign notes with filtered decks Were implicitly imported into the default deck before. Also some refactoring to fetch deck ids and names beforehand. --- rslib/src/import_export/text/import.rs | 60 ++++++++++++++++++-------- 1 file changed, 42 insertions(+), 18 deletions(-) diff --git a/rslib/src/import_export/text/import.rs b/rslib/src/import_export/text/import.rs index ad1427c25..24fb0ee34 100644 --- a/rslib/src/import_export/text/import.rs +++ b/rslib/src/import_export/text/import.rs @@ -1,7 +1,12 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::{borrow::Cow, collections::HashMap, mem, sync::Arc}; +use std::{ + borrow::Cow, + collections::{HashMap, HashSet}, + mem, + sync::Arc, +}; use super::NameOrId; use crate::{ @@ -53,7 +58,7 @@ struct Context<'a> { /// Contains the optional default notetype with the default key. notetypes: HashMap>>, /// Contains the optional default deck id with the default key. - deck_ids: HashMap>, + deck_ids: DeckIdsByNameOrId, usn: Usn, normalize_notes: bool, today: u32, @@ -62,6 +67,12 @@ struct Context<'a> { existing_notes: HashMap<(NotetypeId, u32), Vec>, } +struct DeckIdsByNameOrId { + ids: HashSet, + names: HashMap, + default: Option, +} + struct NoteContext { note: Note, dupes: Vec, @@ -70,6 +81,33 @@ struct NoteContext { deck_id: DeckId, } +impl DeckIdsByNameOrId { + fn new(col: &mut Collection, default: &NameOrId) -> Result { + let names: HashMap = col + .get_all_normal_deck_names()? + .into_iter() + .map(|(id, name)| (name, id)) + .collect(); + let ids = names.values().copied().collect(); + let mut new = Self { + ids, + names, + default: None, + }; + new.default = new.get(default); + + Ok(new) + } + + fn get(&self, name_or_id: &NameOrId) -> Option { + match name_or_id { + _ if *name_or_id == NameOrId::default() => self.default, + NameOrId::Id(id) => self.ids.get(&DeckId(*id)).copied(), + NameOrId::Name(name) => self.names.get(name).copied(), + } + } +} + impl<'a> Context<'a> { fn new(data: &ForeignData, col: &'a mut Collection) -> Result { let usn = col.usn()?; @@ -80,11 +118,7 @@ impl<'a> Context<'a> { NameOrId::default(), col.notetype_by_name_or_id(&data.default_notetype)?, ); - let mut deck_ids = HashMap::new(); - deck_ids.insert( - NameOrId::default(), - col.deck_id_by_name_or_id(&data.default_deck)?, - ); + let deck_ids = DeckIdsByNameOrId::new(col, &data.default_deck)?; let existing_notes = col.storage.all_notes_by_type_and_checksum()?; Ok(Self { col, @@ -119,16 +153,6 @@ impl<'a> Context<'a> { }) } - fn deck_id_for_note(&mut self, note: &ForeignNote) -> Result> { - Ok(if let Some(did) = self.deck_ids.get(¬e.deck) { - *did - } else { - let did = self.col.deck_id_by_name_or_id(¬e.deck)?; - self.deck_ids.insert(note.deck.clone(), did); - did - }) - } - fn import_foreign_notes( &mut self, notes: Vec, @@ -145,7 +169,7 @@ impl<'a> Context<'a> { continue; } if let Some(notetype) = self.notetype_for_note(&foreign)? { - if let Some(deck_id) = self.deck_id_for_note(&foreign)? { + if let Some(deck_id) = self.deck_ids.get(&foreign.deck) { let ctx = self.build_note_context(foreign, notetype, deck_id, global_tags)?; self.import_note(ctx, updated_tags, &mut log)?; } else {