Add import_cards(), import_revlog()

This commit is contained in:
RumovZ 2022-04-08 18:12:37 +02:00
parent ffdd8b741e
commit 08791e24fc
2 changed files with 66 additions and 8 deletions

View file

@ -5,8 +5,7 @@ use std::{
borrow::Cow, borrow::Cow,
collections::{HashMap, HashSet}, collections::{HashMap, HashSet},
fs::File, fs::File,
io::{self}, io, mem,
mem,
sync::Arc, sync::Arc,
}; };
@ -40,6 +39,7 @@ struct Context<'a> {
remapped_notes: HashMap<NoteId, NoteId>, remapped_notes: HashMap<NoteId, NoteId>,
remapped_decks: HashMap<DeckId, DeckId>, remapped_decks: HashMap<DeckId, DeckId>,
remapped_deck_configs: HashMap<DeckConfigId, DeckConfigId>, remapped_deck_configs: HashMap<DeckConfigId, DeckConfigId>,
remapped_cards: HashMap<CardId, CardId>,
data: ExchangeData, data: ExchangeData,
usn: Usn, usn: Usn,
/// Map of source media files, that do not already exist in the target. /// Map of source media files, that do not already exist in the target.
@ -97,12 +97,7 @@ impl Collection {
let archive = ZipArchive::new(file)?; let archive = ZipArchive::new(file)?;
let mut ctx = Context::new(archive, self, search, with_scheduling)?; let mut ctx = Context::new(archive, self, search, with_scheduling)?;
ctx.prepare_media()?; ctx.import()?;
ctx.import_notetypes()?;
ctx.import_notes()?;
ctx.import_deck_configs()?;
ctx.import_decks()?;
ctx.copy_media()?;
Ok(()) Ok(())
} }
@ -152,11 +147,23 @@ impl<'a> Context<'a> {
remapped_notes: HashMap::new(), remapped_notes: HashMap::new(),
remapped_decks: HashMap::new(), remapped_decks: HashMap::new(),
remapped_deck_configs: HashMap::new(), remapped_deck_configs: HashMap::new(),
remapped_cards: HashMap::new(),
used_media_entries: HashMap::new(), used_media_entries: HashMap::new(),
normalize_notes, normalize_notes,
}) })
} }
fn import(&mut self) -> Result<()> {
self.prepare_media()?;
self.import_notetypes()?;
self.import_notes()?;
self.import_deck_configs()?;
self.import_decks()?;
self.import_cards()?;
self.import_revlog()?;
self.copy_media()
}
fn prepare_media(&mut self) -> Result<()> { fn prepare_media(&mut self) -> Result<()> {
let existing_sha1s = self.target_col.all_existing_sha1s()?; let existing_sha1s = self.target_col.all_existing_sha1s()?;
for mut entry in extract_media_entries(&Meta::new_legacy(), &mut self.archive)? { for mut entry in extract_media_entries(&Meta::new_legacy(), &mut self.archive)? {
@ -392,6 +399,50 @@ impl<'a> Context<'a> {
.get_deck_by_name(deck.name.as_native_str()) .get_deck_by_name(deck.name.as_native_str())
} }
fn import_cards(&mut self) -> Result<()> {
let existing = self.target_col.storage.all_cards_as_nid_and_ord()?;
for mut card in mem::take(&mut self.data.cards) {
if self.conflicting_notes.contains(&card.note_id) {
continue;
}
self.remap_note_id(&mut card);
if existing.contains(&(card.note_id, card.template_idx)) {
// TODO: maybe update
continue;
}
self.remap_deck_id(&mut card);
// TODO: adjust collection-relative due times
// TODO: remove cards from filtered decks
let old_id = mem::take(&mut card.id);
self.target_col.add_card(&mut card)?;
self.remapped_cards.insert(old_id, card.id);
}
Ok(())
}
fn remap_note_id(&self, card: &mut Card) {
if let Some(nid) = self.remapped_notes.get(&card.note_id) {
card.note_id = *nid;
}
}
fn remap_deck_id(&self, card: &mut Card) {
if let Some(did) = self.remapped_decks.get(&card.deck_id) {
card.deck_id = *did;
}
}
fn import_revlog(&mut self) -> Result<()> {
for mut entry in mem::take(&mut self.data.revlog) {
if let Some(cid) = self.remapped_cards.get(&entry.cid) {
entry.cid = *cid;
entry.usn = self.usn;
self.target_col.add_revlog_entry_undoable(entry)?;
}
}
Ok(())
}
fn copy_media(&mut self) -> Result<()> { fn copy_media(&mut self) -> Result<()> {
for (used, entry) in self.used_media_entries.values() { for (used, entry) in self.used_media_entries.values() {
if *used { if *used {

View file

@ -400,6 +400,13 @@ impl super::SqliteStorage {
.collect() .collect()
} }
pub(crate) fn all_cards_as_nid_and_ord(&self) -> Result<HashSet<(NoteId, u16)>> {
self.db
.prepare("SELECT nid, ord FROM cards")?
.query_and_then([], |r| Ok((NoteId(r.get(0)?), r.get(1)?)))?
.collect()
}
pub(crate) fn card_ids_of_notes(&self, nids: &[NoteId]) -> Result<Vec<CardId>> { pub(crate) fn card_ids_of_notes(&self, nids: &[NoteId]) -> Result<Vec<CardId>> {
let mut stmt = self let mut stmt = self
.db .db