mod schema if field/templates changed

Instead of throwing an error if schema not marked as changed,
just mark it changed, as that way it can be included as part of
the same transaction.
This commit is contained in:
Damien Elmes 2020-04-21 17:32:16 +10:00
parent f86c2dc567
commit b89dd32f78
7 changed files with 12 additions and 19 deletions

View file

@ -75,7 +75,6 @@ fn anki_error_to_proto_error(err: AnkiError, i18n: &I18n) -> pb::BackendError {
AnkiError::Interrupted => V::Interrupted(Empty {}), AnkiError::Interrupted => V::Interrupted(Empty {}),
AnkiError::CollectionNotOpen => V::InvalidInput(pb::Empty {}), AnkiError::CollectionNotOpen => V::InvalidInput(pb::Empty {}),
AnkiError::CollectionAlreadyOpen => V::InvalidInput(pb::Empty {}), AnkiError::CollectionAlreadyOpen => V::InvalidInput(pb::Empty {}),
AnkiError::SchemaChange => V::InvalidInput(pb::Empty {}),
AnkiError::JSONError { info } => V::JsonError(info), AnkiError::JSONError { info } => V::JsonError(info),
AnkiError::ProtoError { info } => V::ProtoError(info), AnkiError::ProtoError { info } => V::ProtoError(info),
}; };

View file

@ -172,14 +172,6 @@ impl Collection {
self.storage.usn(self.server) self.storage.usn(self.server)
} }
pub(crate) fn ensure_schema_modified(&self) -> Result<()> {
if !self.storage.schema_modified()? {
Err(AnkiError::SchemaChange)
} else {
Ok(())
}
}
pub(crate) fn before_upload(&self) -> Result<()> { pub(crate) fn before_upload(&self) -> Result<()> {
self.storage.clear_tag_usns()?; self.storage.clear_tag_usns()?;
self.storage.clear_deck_conf_usns()?; self.storage.clear_deck_conf_usns()?;

View file

@ -234,11 +234,12 @@ impl Collection {
} }
} }
/// Remove a deck configuration. This will force a full sync.
pub(crate) fn remove_deck_config(&self, dcid: DeckConfID) -> Result<()> { pub(crate) fn remove_deck_config(&self, dcid: DeckConfID) -> Result<()> {
if dcid.0 == 1 { if dcid.0 == 1 {
return Err(AnkiError::invalid_input("can't delete default conf")); return Err(AnkiError::invalid_input("can't delete default conf"));
} }
self.ensure_schema_modified()?; self.storage.set_schema_modified()?;
self.storage.remove_deck_conf(dcid) self.storage.remove_deck_conf(dcid)
} }
} }

View file

@ -45,9 +45,6 @@ pub enum AnkiError {
#[fail(display = "Close the existing collection first.")] #[fail(display = "Close the existing collection first.")]
CollectionAlreadyOpen, CollectionAlreadyOpen,
#[fail(display = "Operation modifies schema, but schema not marked modified.")]
SchemaChange,
} }
// error helpers // error helpers

View file

@ -205,6 +205,8 @@ impl From<NoteType> for NoteTypeProto {
} }
impl Collection { impl Collection {
/// Saves changes to a note type. This will force a full sync if templates
/// or fields have been added/removed/reordered.
pub fn update_notetype(&mut self, nt: &mut NoteType) -> Result<()> { pub fn update_notetype(&mut self, nt: &mut NoteType) -> Result<()> {
self.transact(None, |col| { self.transact(None, |col| {
let existing_notetype = col let existing_notetype = col

View file

@ -61,6 +61,8 @@ impl Collection {
return Ok(()); return Ok(());
} }
self.storage.set_schema_modified()?;
let nids = self.search_notes_only(&format!("mid:{}", nt.id))?; let nids = self.search_notes_only(&format!("mid:{}", nt.id))?;
let usn = self.usn()?; let usn = self.usn()?;
for nid in nids { for nid in nids {
@ -99,6 +101,8 @@ impl Collection {
return Ok(()); return Ok(());
} }
self.storage.set_schema_modified()?;
let changes = TemplateOrdChanges::new(ords, previous_template_count as u32); let changes = TemplateOrdChanges::new(ords, previous_template_count as u32);
if !changes.removed.is_empty() { if !changes.removed.is_empty() {
self.storage self.storage
@ -239,5 +243,3 @@ mod test {
Ok(()) Ok(())
} }
} }
// fixme: make sure we don't orphan notes

View file

@ -294,10 +294,10 @@ impl SqliteStorage {
.map_err(Into::into) .map_err(Into::into)
} }
pub(crate) fn schema_modified(&self) -> Result<bool> { pub(crate) fn set_schema_modified(&self) -> Result<()> {
self.db self.db
.prepare_cached("select scm > ls from col")? .prepare_cached("update col set scm = ?")?
.query_row(NO_PARAMS, |row| row.get(0)) .execute(&[TimestampMillis::now()])?;
.map_err(Into::into) Ok(())
} }
} }