mirror of
https://github.com/ankitects/anki.git
synced 2025-09-18 14:02:21 -04:00
Skip new notetype checks when importing apkg
This commit is contained in:
parent
be1b524396
commit
c0dd769090
10 changed files with 69 additions and 35 deletions
|
@ -107,6 +107,7 @@ message Notetype {
|
|||
message AddOrUpdateNotetypeRequest {
|
||||
bytes json = 1;
|
||||
bool preserve_usn_and_mtime = 2;
|
||||
bool skip_checks = 3;
|
||||
}
|
||||
|
||||
message StockNotetype {
|
||||
|
|
|
@ -235,7 +235,7 @@ class Anki2Importer(Importer):
|
|||
model = srcModel.copy()
|
||||
model["id"] = mid
|
||||
model["usn"] = self.col.usn()
|
||||
self.dst.models.update(model)
|
||||
self.dst.models.update(model, skip_checks=True)
|
||||
break
|
||||
# there's an existing model; do the schemas match?
|
||||
dstModel = self.dst.models.get(mid)
|
||||
|
@ -246,7 +246,7 @@ class Anki2Importer(Importer):
|
|||
model = srcModel.copy()
|
||||
model["id"] = mid
|
||||
model["usn"] = self.col.usn()
|
||||
self.dst.models.update(model)
|
||||
self.dst.models.update(model, skip_checks=True)
|
||||
break
|
||||
# as they don't match, try next id
|
||||
mid = NotetypeId(mid + 1)
|
||||
|
|
|
@ -527,12 +527,19 @@ and notes.mid = ? and cards.ord = ?""",
|
|||
pass
|
||||
|
||||
# @deprecated(replaced_by=update_dict)
|
||||
def update(self, notetype: NotetypeDict, preserve_usn: bool = True) -> None:
|
||||
def update(
|
||||
self,
|
||||
notetype: NotetypeDict,
|
||||
preserve_usn: bool = True,
|
||||
skip_checks: bool = False,
|
||||
) -> None:
|
||||
"Add or update an existing model. Use .update_dict() instead."
|
||||
self._remove_from_cache(notetype["id"])
|
||||
self.ensure_name_unique(notetype)
|
||||
notetype["id"] = self.col._backend.add_or_update_notetype(
|
||||
json=to_json_bytes(notetype), preserve_usn_and_mtime=preserve_usn
|
||||
json=to_json_bytes(notetype),
|
||||
preserve_usn_and_mtime=preserve_usn,
|
||||
skip_checks=skip_checks,
|
||||
)
|
||||
self.set_current(notetype)
|
||||
self._mutate_after_write(notetype)
|
||||
|
|
|
@ -17,7 +17,7 @@ impl NotetypesService for Backend {
|
|||
let mut notetype: Notetype = input.into();
|
||||
self.with_col(|col| {
|
||||
Ok(col
|
||||
.add_notetype(&mut notetype)?
|
||||
.add_notetype(&mut notetype, false)?
|
||||
.map(|_| notetype.id.0)
|
||||
.into())
|
||||
})
|
||||
|
@ -25,7 +25,7 @@ impl NotetypesService for Backend {
|
|||
|
||||
fn update_notetype(&self, input: pb::Notetype) -> Result<pb::OpChanges> {
|
||||
let mut notetype: Notetype = input.into();
|
||||
self.with_col(|col| col.update_notetype(&mut notetype))
|
||||
self.with_col(|col| col.update_notetype(&mut notetype, false))
|
||||
.map(Into::into)
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,7 @@ impl NotetypesService for Backend {
|
|||
let mut notetype: Notetype = legacy.into();
|
||||
self.with_col(|col| {
|
||||
Ok(col
|
||||
.add_notetype(&mut notetype)?
|
||||
.add_notetype(&mut notetype, false)?
|
||||
.map(|_| notetype.id.0)
|
||||
.into())
|
||||
})
|
||||
|
@ -43,7 +43,7 @@ impl NotetypesService for Backend {
|
|||
fn update_notetype_legacy(&self, input: pb::Json) -> Result<pb::OpChanges> {
|
||||
let legacy: NotetypeSchema11 = serde_json::from_slice(&input.json)?;
|
||||
let mut notetype: Notetype = legacy.into();
|
||||
self.with_col(|col| col.update_notetype(&mut notetype))
|
||||
self.with_col(|col| col.update_notetype(&mut notetype, false))
|
||||
.map(Into::into)
|
||||
}
|
||||
|
||||
|
@ -58,11 +58,11 @@ impl NotetypesService for Backend {
|
|||
nt.set_modified(col.usn()?);
|
||||
}
|
||||
if nt.id.0 == 0 {
|
||||
col.add_notetype(&mut nt)?;
|
||||
col.add_notetype(&mut nt, input.skip_checks)?;
|
||||
} else if !input.preserve_usn_and_mtime {
|
||||
col.update_notetype(&mut nt)?;
|
||||
col.update_notetype(&mut nt, input.skip_checks)?;
|
||||
} else {
|
||||
col.add_or_update_notetype_with_existing_id(&mut nt)?;
|
||||
col.add_or_update_notetype_with_existing_id(&mut nt, input.skip_checks)?;
|
||||
}
|
||||
Ok(pb::NotetypeId { ntid: nt.id.0 })
|
||||
})
|
||||
|
|
|
@ -273,7 +273,7 @@ impl Collection {
|
|||
// one note type exists
|
||||
if self.storage.get_all_notetype_names()?.is_empty() {
|
||||
let mut nt = all_stock_notetypes(&self.tr).remove(0);
|
||||
self.add_notetype_inner(&mut nt, usn)?;
|
||||
self.add_notetype_inner(&mut nt, usn, true)?;
|
||||
}
|
||||
|
||||
if out.card_ords_duplicated > 0
|
||||
|
@ -367,7 +367,7 @@ impl Collection {
|
|||
for n in 0..extra_cards_required {
|
||||
basic.add_template(&format!("Card {}", n + 2), &qfmt, &afmt);
|
||||
}
|
||||
self.add_notetype(&mut basic)?;
|
||||
self.add_notetype(&mut basic, true)?;
|
||||
Ok(Arc::new(basic))
|
||||
}
|
||||
|
||||
|
|
|
@ -117,11 +117,15 @@ impl Notetype {
|
|||
|
||||
impl Collection {
|
||||
/// Add a new notetype, and allocate it an ID.
|
||||
pub fn add_notetype(&mut self, notetype: &mut Notetype) -> Result<OpOutput<()>> {
|
||||
pub fn add_notetype(
|
||||
&mut self,
|
||||
notetype: &mut Notetype,
|
||||
skip_checks: bool,
|
||||
) -> Result<OpOutput<()>> {
|
||||
self.transact(Op::AddNotetype, |col| {
|
||||
let usn = col.usn()?;
|
||||
notetype.set_modified(usn);
|
||||
col.add_notetype_inner(notetype, usn)
|
||||
col.add_notetype_inner(notetype, usn, skip_checks)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -130,7 +134,11 @@ impl Collection {
|
|||
///
|
||||
/// This does not assign ordinals to the provided notetype, so if you wish
|
||||
/// to make use of template_idx, the notetype must be fetched again.
|
||||
pub fn update_notetype(&mut self, notetype: &mut Notetype) -> Result<OpOutput<()>> {
|
||||
pub fn update_notetype(
|
||||
&mut self,
|
||||
notetype: &mut Notetype,
|
||||
skip_checks: bool,
|
||||
) -> Result<OpOutput<()>> {
|
||||
self.transact(Op::UpdateNotetype, |col| {
|
||||
let original = col
|
||||
.storage
|
||||
|
@ -138,7 +146,12 @@ impl Collection {
|
|||
.ok_or(AnkiError::NotFound)?;
|
||||
let usn = col.usn()?;
|
||||
notetype.set_modified(usn);
|
||||
col.add_or_update_notetype_with_existing_id_inner(notetype, Some(original), usn)
|
||||
col.add_or_update_notetype_with_existing_id_inner(
|
||||
notetype,
|
||||
Some(original),
|
||||
usn,
|
||||
skip_checks,
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -147,11 +160,12 @@ impl Collection {
|
|||
pub fn add_or_update_notetype_with_existing_id(
|
||||
&mut self,
|
||||
notetype: &mut Notetype,
|
||||
skip_checks: bool,
|
||||
) -> Result<()> {
|
||||
self.transact_no_undo(|col| {
|
||||
let usn = col.usn()?;
|
||||
let existing = col.storage.get_notetype(notetype.id)?;
|
||||
col.add_or_update_notetype_with_existing_id_inner(notetype, existing, usn)
|
||||
col.add_or_update_notetype_with_existing_id_inner(notetype, existing, usn, skip_checks)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -419,7 +433,11 @@ impl Notetype {
|
|||
self.templates.push(CardTemplate::new(name, qfmt, afmt));
|
||||
}
|
||||
|
||||
pub(crate) fn prepare_for_update(&mut self, existing: Option<&Notetype>) -> Result<()> {
|
||||
pub(crate) fn prepare_for_update(
|
||||
&mut self,
|
||||
existing: Option<&Notetype>,
|
||||
skip_checks: bool,
|
||||
) -> Result<()> {
|
||||
if self.fields.is_empty() {
|
||||
return Err(AnkiError::invalid_input("1 field required"));
|
||||
}
|
||||
|
@ -450,9 +468,11 @@ impl Notetype {
|
|||
}
|
||||
}
|
||||
self.config.reqs = reqs;
|
||||
self.ensure_template_fronts_unique()?;
|
||||
self.ensure_valid_parsed_templates(&parsed_templates)?;
|
||||
self.ensure_cloze_if_cloze_notetype(&parsed_templates)?;
|
||||
if !skip_checks {
|
||||
self.ensure_template_fronts_unique()?;
|
||||
self.ensure_valid_parsed_templates(&parsed_templates)?;
|
||||
self.ensure_cloze_if_cloze_notetype(&parsed_templates)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -610,8 +630,13 @@ impl Collection {
|
|||
}
|
||||
|
||||
/// Caller must set notetype as modified if appropriate.
|
||||
pub(crate) fn add_notetype_inner(&mut self, notetype: &mut Notetype, usn: Usn) -> Result<()> {
|
||||
notetype.prepare_for_update(None)?;
|
||||
pub(crate) fn add_notetype_inner(
|
||||
&mut self,
|
||||
notetype: &mut Notetype,
|
||||
usn: Usn,
|
||||
skip_checks: bool,
|
||||
) -> Result<()> {
|
||||
notetype.prepare_for_update(None, skip_checks)?;
|
||||
self.ensure_notetype_name_unique(notetype, usn)?;
|
||||
self.add_notetype_undoable(notetype)?;
|
||||
self.set_current_notetype_id(notetype.id)
|
||||
|
@ -624,9 +649,10 @@ impl Collection {
|
|||
notetype: &mut Notetype,
|
||||
original: Option<Notetype>,
|
||||
usn: Usn,
|
||||
skip_checks: bool,
|
||||
) -> Result<()> {
|
||||
let normalize = self.get_config_bool(BoolKey::NormalizeNoteText);
|
||||
notetype.prepare_for_update(original.as_ref())?;
|
||||
notetype.prepare_for_update(original.as_ref(), skip_checks)?;
|
||||
self.ensure_notetype_name_unique(notetype, usn)?;
|
||||
|
||||
if let Some(original) = original {
|
||||
|
@ -671,7 +697,7 @@ impl Collection {
|
|||
let all = self.storage.get_all_notetype_names()?;
|
||||
if all.is_empty() {
|
||||
let mut nt = all_stock_notetypes(&self.tr).remove(0);
|
||||
self.add_notetype_inner(&mut nt, self.usn()?)?;
|
||||
self.add_notetype_inner(&mut nt, self.usn()?, true)?;
|
||||
self.set_current_notetype_id(nt.id)
|
||||
} else {
|
||||
self.set_current_notetype_id(all[0].0)
|
||||
|
|
|
@ -394,7 +394,7 @@ mod test {
|
|||
basic.add_field("Text"); // 4
|
||||
basic.add_field("idx5");
|
||||
// re-fetch to get ordinals
|
||||
col.update_notetype(&mut basic)?;
|
||||
col.update_notetype(&mut basic, false)?;
|
||||
let basic = col.get_notetype(basic.id)?.unwrap();
|
||||
|
||||
// if names match, assignments are out of order; unmatched entries
|
||||
|
|
|
@ -258,13 +258,13 @@ mod test {
|
|||
col.add_note(&mut note, DeckId(1))?;
|
||||
|
||||
nt.add_field("three");
|
||||
col.update_notetype(&mut nt)?;
|
||||
col.update_notetype(&mut nt, false)?;
|
||||
|
||||
let note = col.storage.get_note(note.id)?.unwrap();
|
||||
assert_eq!(note.fields(), &["one".to_string(), "two".into(), "".into()]);
|
||||
|
||||
nt.fields.remove(1);
|
||||
col.update_notetype(&mut nt)?;
|
||||
col.update_notetype(&mut nt, false)?;
|
||||
|
||||
let note = col.storage.get_note(note.id)?.unwrap();
|
||||
assert_eq!(note.fields(), &["one".to_string(), "".into()]);
|
||||
|
@ -281,13 +281,13 @@ mod test {
|
|||
.unwrap();
|
||||
nt.templates[0].config.q_format += "\n{{#Front}}{{some:Front}}{{Back}}{{/Front}}";
|
||||
nt.fields[0].name = "Test".into();
|
||||
col.update_notetype(&mut nt)?;
|
||||
col.update_notetype(&mut nt, false)?;
|
||||
assert_eq!(
|
||||
&nt.templates[0].config.q_format,
|
||||
"{{Test}}\n{{#Test}}{{some:Test}}{{Back}}{{/Test}}"
|
||||
);
|
||||
nt.fields.remove(0);
|
||||
col.update_notetype(&mut nt)?;
|
||||
col.update_notetype(&mut nt, false)?;
|
||||
assert_eq!(&nt.templates[0].config.q_format, "\n{{Back}}");
|
||||
|
||||
Ok(())
|
||||
|
@ -313,7 +313,7 @@ mod test {
|
|||
|
||||
// add an extra card template
|
||||
nt.add_template("card 2", "{{Front}}2", "");
|
||||
col.update_notetype(&mut nt)?;
|
||||
col.update_notetype(&mut nt, false)?;
|
||||
|
||||
assert_eq!(
|
||||
col.search_cards(note.id, SortMode::NoOrder).unwrap().len(),
|
||||
|
|
|
@ -15,7 +15,7 @@ use crate::{
|
|||
impl SqliteStorage {
|
||||
pub(crate) fn add_stock_notetypes(&self, tr: &I18n) -> Result<()> {
|
||||
for (idx, mut nt) in all_stock_notetypes(tr).into_iter().enumerate() {
|
||||
nt.prepare_for_update(None)?;
|
||||
nt.prepare_for_update(None, true)?;
|
||||
self.add_notetype(&mut nt)?;
|
||||
if idx == Kind::Basic as usize {
|
||||
self.set_config_entry(&ConfigEntry::boxed(
|
||||
|
|
|
@ -1386,7 +1386,7 @@ mod test {
|
|||
// and a new notetype
|
||||
let mut nt = all_stock_notetypes(&col1.tr).remove(0);
|
||||
nt.name = "new".into();
|
||||
col1.add_notetype(&mut nt)?;
|
||||
col1.add_notetype(&mut nt, false)?;
|
||||
|
||||
// add another note+card+tag
|
||||
let mut note = nt.new_note();
|
||||
|
@ -1502,7 +1502,7 @@ mod test {
|
|||
|
||||
let mut nt = col2.storage.get_notetype(nt.id)?.unwrap();
|
||||
nt.name = "newer".into();
|
||||
col2.update_notetype(&mut nt)?;
|
||||
col2.update_notetype(&mut nt, false)?;
|
||||
|
||||
// sync the changes back
|
||||
let out = ctx.normal_sync(&mut col2).await;
|
||||
|
|
Loading…
Reference in a new issue