mirror of
https://github.com/ankitects/anki.git
synced 2025-09-18 14:02:21 -04:00
Fix newer notes incorrectly being skipped when importing successive exports (#3693)
* add Note::set_modified_with_mtime * add struct for Collection::update_note_inner_without_cards's args * refactor Collection::update_note_inner_without_cards to use the arg struct * add Collection::update_note_inner_without_cards_using_mtime * use incoming note's mtime when updating notes during import
This commit is contained in:
parent
afd7fca4cb
commit
2a1448bc45
3 changed files with 86 additions and 48 deletions
|
@ -15,6 +15,7 @@ use crate::import_export::package::UpdateCondition;
|
|||
use crate::import_export::ImportError;
|
||||
use crate::import_export::ImportProgress;
|
||||
use crate::import_export::NoteLog;
|
||||
use crate::notes::UpdateNoteInnerWithoutCardsArgs;
|
||||
use crate::notetype::ChangeNotetypeInput;
|
||||
use crate::prelude::*;
|
||||
use crate::progress::ThrottlingProgressHandler;
|
||||
|
@ -463,15 +464,21 @@ impl<'n> NoteContext<'n> {
|
|||
self.munge_media(&mut note)?;
|
||||
let original = self.get_expected_note(note.id)?;
|
||||
let notetype = self.get_expected_notetype(note.notetype_id)?;
|
||||
self.target_col.update_note_inner_without_cards(
|
||||
&mut note,
|
||||
&original,
|
||||
¬etype,
|
||||
self.usn,
|
||||
true,
|
||||
self.normalize_notes,
|
||||
true,
|
||||
)?;
|
||||
// Preserve the incoming note's mtime to allow imports of successive exports
|
||||
let incoming_mtime = note.mtime;
|
||||
self.target_col
|
||||
.update_note_inner_without_cards_using_mtime(
|
||||
UpdateNoteInnerWithoutCardsArgs {
|
||||
note: &mut note,
|
||||
original: &original,
|
||||
notetype: ¬etype,
|
||||
usn: self.usn,
|
||||
mark_note_modified: true,
|
||||
normalize_text: self.normalize_notes,
|
||||
update_tags: true,
|
||||
},
|
||||
Some(incoming_mtime),
|
||||
)?;
|
||||
self.imports.log_updated(note, source_id);
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -220,11 +220,16 @@ impl Note {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn set_modified(&mut self, usn: Usn) {
|
||||
self.mtime = TimestampSecs::now();
|
||||
#[inline]
|
||||
pub(crate) fn set_modified_with_mtime(&mut self, usn: Usn, mtime: TimestampSecs) {
|
||||
self.mtime = mtime;
|
||||
self.usn = usn;
|
||||
}
|
||||
|
||||
pub(crate) fn set_modified(&mut self, usn: Usn) {
|
||||
self.set_modified_with_mtime(usn, TimestampSecs::now())
|
||||
}
|
||||
|
||||
pub(crate) fn nonempty_fields<'a>(&self, fields: &'a [NoteField]) -> HashSet<&'a str> {
|
||||
self.fields
|
||||
.iter()
|
||||
|
@ -346,6 +351,18 @@ fn invalid_char_for_field(c: char) -> bool {
|
|||
c.is_ascii_control() && c != '\n' && c != '\t'
|
||||
}
|
||||
|
||||
/// Used when calling [Collection::update_note_inner_without_cards] and
|
||||
/// [Collection::update_note_inner_without_cards_using_mtime]
|
||||
pub(crate) struct UpdateNoteInnerWithoutCardsArgs<'a> {
|
||||
pub(crate) note: &'a mut Note,
|
||||
pub(crate) original: &'a Note,
|
||||
pub(crate) notetype: &'a Notetype,
|
||||
pub(crate) usn: Usn,
|
||||
pub(crate) mark_note_modified: bool,
|
||||
pub(crate) normalize_text: bool,
|
||||
pub(crate) update_tags: bool,
|
||||
}
|
||||
|
||||
impl Collection {
|
||||
pub(crate) fn canonify_note_tags(&mut self, note: &mut Note, usn: Usn) -> Result<()> {
|
||||
if !note.tags.is_empty() {
|
||||
|
@ -434,40 +451,53 @@ impl Collection {
|
|||
normalize_text: bool,
|
||||
update_tags: bool,
|
||||
) -> Result<()> {
|
||||
self.update_note_inner_without_cards(
|
||||
self.update_note_inner_without_cards(UpdateNoteInnerWithoutCardsArgs {
|
||||
note,
|
||||
original,
|
||||
ctx.notetype,
|
||||
ctx.usn,
|
||||
notetype: ctx.notetype,
|
||||
usn: ctx.usn,
|
||||
mark_note_modified,
|
||||
normalize_text,
|
||||
update_tags,
|
||||
)?;
|
||||
})?;
|
||||
self.generate_cards_for_existing_note(ctx, note)
|
||||
}
|
||||
|
||||
// TODO: refactor into struct
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub(crate) fn update_note_inner_without_cards(
|
||||
#[inline]
|
||||
pub(crate) fn update_note_inner_without_cards_using_mtime(
|
||||
&mut self,
|
||||
note: &mut Note,
|
||||
original: &Note,
|
||||
notetype: &Notetype,
|
||||
usn: Usn,
|
||||
mark_note_modified: bool,
|
||||
normalize_text: bool,
|
||||
update_tags: bool,
|
||||
UpdateNoteInnerWithoutCardsArgs {
|
||||
note,
|
||||
original,
|
||||
notetype,
|
||||
usn,
|
||||
mark_note_modified,
|
||||
normalize_text,
|
||||
update_tags,
|
||||
}: UpdateNoteInnerWithoutCardsArgs,
|
||||
mtime: Option<TimestampSecs>,
|
||||
) -> Result<()> {
|
||||
if update_tags {
|
||||
self.canonify_note_tags(note, usn)?;
|
||||
}
|
||||
note.prepare_for_update(notetype, normalize_text)?;
|
||||
if mark_note_modified {
|
||||
note.set_modified(usn);
|
||||
if let Some(mtime) = mtime {
|
||||
note.set_modified_with_mtime(usn, mtime);
|
||||
} else {
|
||||
note.set_modified(usn);
|
||||
}
|
||||
}
|
||||
self.update_note_undoable(note, original)
|
||||
}
|
||||
|
||||
pub(crate) fn update_note_inner_without_cards(
|
||||
&mut self,
|
||||
args: UpdateNoteInnerWithoutCardsArgs<'_>,
|
||||
) -> Result<()> {
|
||||
self.update_note_inner_without_cards_using_mtime(args, None)
|
||||
}
|
||||
|
||||
pub(crate) fn remove_notes_inner(&mut self, nids: &[NoteId], usn: Usn) -> Result<usize> {
|
||||
let mut card_count = 0;
|
||||
for nid in nids {
|
||||
|
@ -542,15 +572,15 @@ impl Collection {
|
|||
out.update_tags,
|
||||
)?;
|
||||
} else {
|
||||
self.update_note_inner_without_cards(
|
||||
&mut note,
|
||||
&original,
|
||||
&nt,
|
||||
self.update_note_inner_without_cards(UpdateNoteInnerWithoutCardsArgs {
|
||||
note: &mut note,
|
||||
original: &original,
|
||||
notetype: &nt,
|
||||
usn,
|
||||
out.mark_modified,
|
||||
norm,
|
||||
out.update_tags,
|
||||
)?;
|
||||
mark_note_modified: out.mark_modified,
|
||||
normalize_text: norm,
|
||||
update_tags: out.update_tags,
|
||||
})?;
|
||||
}
|
||||
|
||||
changed_notes += 1;
|
||||
|
|
|
@ -9,6 +9,7 @@ use std::mem;
|
|||
use super::CardGenContext;
|
||||
use super::CardTemplate;
|
||||
use super::Notetype;
|
||||
use crate::notes::UpdateNoteInnerWithoutCardsArgs;
|
||||
use crate::prelude::*;
|
||||
use crate::search::JoinSearches;
|
||||
use crate::search::TemplateKind;
|
||||
|
@ -80,15 +81,15 @@ impl Collection {
|
|||
for nid in nids {
|
||||
let mut note = self.storage.get_note(nid)?.unwrap();
|
||||
let original = note.clone();
|
||||
self.update_note_inner_without_cards(
|
||||
&mut note,
|
||||
&original,
|
||||
nt,
|
||||
self.update_note_inner_without_cards(UpdateNoteInnerWithoutCardsArgs {
|
||||
note: &mut note,
|
||||
original: &original,
|
||||
notetype: nt,
|
||||
usn,
|
||||
true,
|
||||
mark_note_modified: true,
|
||||
normalize_text,
|
||||
false,
|
||||
)?;
|
||||
update_tags: false,
|
||||
})?;
|
||||
}
|
||||
} else {
|
||||
// nothing to do
|
||||
|
@ -104,15 +105,15 @@ impl Collection {
|
|||
let mut note = self.storage.get_note(nid)?.unwrap();
|
||||
let original = note.clone();
|
||||
note.reorder_fields(&ords);
|
||||
self.update_note_inner_without_cards(
|
||||
&mut note,
|
||||
&original,
|
||||
nt,
|
||||
self.update_note_inner_without_cards(UpdateNoteInnerWithoutCardsArgs {
|
||||
note: &mut note,
|
||||
original: &original,
|
||||
notetype: nt,
|
||||
usn,
|
||||
true,
|
||||
mark_note_modified: true,
|
||||
normalize_text,
|
||||
false,
|
||||
)?;
|
||||
update_tags: false,
|
||||
})?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue