mirror of
https://github.com/ankitects/anki.git
synced 2025-09-21 15:32:23 -04:00
Keep source id of imported cards (or skip)
This commit is contained in:
parent
726438d1c5
commit
a0604a2e51
4 changed files with 89 additions and 7 deletions
|
@ -35,6 +35,14 @@ impl Collection {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn add_card_if_unique_undoable(&mut self, card: &Card) -> Result<bool> {
|
||||
let added = self.storage.add_card_if_unique(card)?;
|
||||
if added {
|
||||
self.save_undo(UndoableCardChange::Added(Box::new(card.clone())));
|
||||
}
|
||||
Ok(added)
|
||||
}
|
||||
|
||||
pub(super) fn update_card_undoable(&mut self, card: &mut Card, original: Card) -> Result<()> {
|
||||
if card.id.0 == 0 {
|
||||
return Err(AnkiError::invalid_input("card id not set"));
|
||||
|
|
|
@ -41,7 +41,6 @@ struct Context<'a> {
|
|||
remapped_notes: HashMap<NoteId, NoteId>,
|
||||
remapped_decks: HashMap<DeckId, DeckId>,
|
||||
remapped_deck_configs: HashMap<DeckConfigId, DeckConfigId>,
|
||||
remapped_cards: HashMap<CardId, CardId>,
|
||||
data: ExchangeData,
|
||||
usn: Usn,
|
||||
/// Map of source media files, that do not already exist in the target.
|
||||
|
@ -52,6 +51,7 @@ struct Context<'a> {
|
|||
/// Source notes that cannot be imported, because notes with the same guid
|
||||
/// exist in the target, but their notetypes don't match.
|
||||
conflicting_notes: HashSet<NoteId>,
|
||||
added_cards: HashSet<CardId>,
|
||||
normalize_notes: bool,
|
||||
}
|
||||
|
||||
|
@ -139,7 +139,7 @@ impl<'a> Context<'a> {
|
|||
remapped_notes: HashMap::new(),
|
||||
remapped_decks: HashMap::new(),
|
||||
remapped_deck_configs: HashMap::new(),
|
||||
remapped_cards: HashMap::new(),
|
||||
added_cards: HashSet::new(),
|
||||
used_media_entries: HashMap::new(),
|
||||
normalize_notes,
|
||||
})
|
||||
|
@ -405,9 +405,15 @@ impl<'a> Context<'a> {
|
|||
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);
|
||||
self.add_card(&mut card)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn add_card(&mut self, card: &mut Card) -> Result<()> {
|
||||
card.usn = self.usn;
|
||||
if self.target_col.add_card_if_unique_undoable(card)? {
|
||||
self.added_cards.insert(card.id);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -426,8 +432,7 @@ impl<'a> Context<'a> {
|
|||
|
||||
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;
|
||||
if self.added_cards.contains(&entry.cid) {
|
||||
entry.usn = self.usn;
|
||||
self.target_col.add_revlog_entry_undoable(entry)?;
|
||||
}
|
||||
|
|
41
rslib/src/storage/card/add_card_if_unique.sql
Normal file
41
rslib/src/storage/card/add_card_if_unique.sql
Normal file
|
@ -0,0 +1,41 @@
|
|||
INSERT
|
||||
OR IGNORE INTO cards (
|
||||
id,
|
||||
nid,
|
||||
did,
|
||||
ord,
|
||||
mod,
|
||||
usn,
|
||||
type,
|
||||
queue,
|
||||
due,
|
||||
ivl,
|
||||
factor,
|
||||
reps,
|
||||
lapses,
|
||||
left,
|
||||
odue,
|
||||
odid,
|
||||
flags,
|
||||
data
|
||||
)
|
||||
VALUES (
|
||||
?,
|
||||
?,
|
||||
?,
|
||||
?,
|
||||
?,
|
||||
?,
|
||||
?,
|
||||
?,
|
||||
?,
|
||||
?,
|
||||
?,
|
||||
?,
|
||||
?,
|
||||
?,
|
||||
?,
|
||||
?,
|
||||
?,
|
||||
?
|
||||
)
|
|
@ -145,6 +145,34 @@ impl super::SqliteStorage {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Add card if id is unique. True if card was added.
|
||||
pub(crate) fn add_card_if_unique(&self, card: &Card) -> Result<bool> {
|
||||
self.db
|
||||
.prepare_cached(include_str!("add_card_if_unique.sql"))?
|
||||
.execute(params![
|
||||
card.id,
|
||||
card.note_id,
|
||||
card.deck_id,
|
||||
card.template_idx,
|
||||
card.mtime,
|
||||
card.usn,
|
||||
card.ctype as u8,
|
||||
card.queue as i8,
|
||||
card.due,
|
||||
card.interval,
|
||||
card.ease_factor,
|
||||
card.reps,
|
||||
card.lapses,
|
||||
card.remaining_steps,
|
||||
card.original_due,
|
||||
card.original_deck_id,
|
||||
card.flags,
|
||||
CardData::from_card(card),
|
||||
])
|
||||
.map(|n_rows| n_rows == 1)
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
/// Add or update card, using the provided ID. Used for syncing & undoing.
|
||||
pub(crate) fn add_or_update_card(&self, card: &Card) -> Result<()> {
|
||||
let mut stmt = self.db.prepare_cached(include_str!("add_or_update.sql"))?;
|
||||
|
|
Loading…
Reference in a new issue