From b89dd32f789857994c530851338263771db07097 Mon Sep 17 00:00:00 2001 From: Damien Elmes Date: Tue, 21 Apr 2020 17:32:16 +1000 Subject: [PATCH] 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. --- rslib/src/backend/mod.rs | 1 - rslib/src/collection.rs | 8 -------- rslib/src/deckconf.rs | 3 ++- rslib/src/err.rs | 3 --- rslib/src/notetype/mod.rs | 2 ++ rslib/src/notetype/schemachange.rs | 6 ++++-- rslib/src/storage/sqlite.rs | 8 ++++---- 7 files changed, 12 insertions(+), 19 deletions(-) diff --git a/rslib/src/backend/mod.rs b/rslib/src/backend/mod.rs index 0a7f33b8e..e9fc61a9f 100644 --- a/rslib/src/backend/mod.rs +++ b/rslib/src/backend/mod.rs @@ -75,7 +75,6 @@ fn anki_error_to_proto_error(err: AnkiError, i18n: &I18n) -> pb::BackendError { AnkiError::Interrupted => V::Interrupted(Empty {}), AnkiError::CollectionNotOpen => V::InvalidInput(pb::Empty {}), AnkiError::CollectionAlreadyOpen => V::InvalidInput(pb::Empty {}), - AnkiError::SchemaChange => V::InvalidInput(pb::Empty {}), AnkiError::JSONError { info } => V::JsonError(info), AnkiError::ProtoError { info } => V::ProtoError(info), }; diff --git a/rslib/src/collection.rs b/rslib/src/collection.rs index 6406c751d..780fbbce2 100644 --- a/rslib/src/collection.rs +++ b/rslib/src/collection.rs @@ -172,14 +172,6 @@ impl Collection { 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<()> { self.storage.clear_tag_usns()?; self.storage.clear_deck_conf_usns()?; diff --git a/rslib/src/deckconf.rs b/rslib/src/deckconf.rs index f43ee2927..e92a33297 100644 --- a/rslib/src/deckconf.rs +++ b/rslib/src/deckconf.rs @@ -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<()> { if dcid.0 == 1 { 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) } } diff --git a/rslib/src/err.rs b/rslib/src/err.rs index 018fde067..543bcb589 100644 --- a/rslib/src/err.rs +++ b/rslib/src/err.rs @@ -45,9 +45,6 @@ pub enum AnkiError { #[fail(display = "Close the existing collection first.")] CollectionAlreadyOpen, - - #[fail(display = "Operation modifies schema, but schema not marked modified.")] - SchemaChange, } // error helpers diff --git a/rslib/src/notetype/mod.rs b/rslib/src/notetype/mod.rs index 4cc9a2638..4bc3d6e56 100644 --- a/rslib/src/notetype/mod.rs +++ b/rslib/src/notetype/mod.rs @@ -205,6 +205,8 @@ impl From for NoteTypeProto { } 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<()> { self.transact(None, |col| { let existing_notetype = col diff --git a/rslib/src/notetype/schemachange.rs b/rslib/src/notetype/schemachange.rs index ca385d794..e731e733c 100644 --- a/rslib/src/notetype/schemachange.rs +++ b/rslib/src/notetype/schemachange.rs @@ -61,6 +61,8 @@ impl Collection { return Ok(()); } + self.storage.set_schema_modified()?; + let nids = self.search_notes_only(&format!("mid:{}", nt.id))?; let usn = self.usn()?; for nid in nids { @@ -99,6 +101,8 @@ impl Collection { return Ok(()); } + self.storage.set_schema_modified()?; + let changes = TemplateOrdChanges::new(ords, previous_template_count as u32); if !changes.removed.is_empty() { self.storage @@ -239,5 +243,3 @@ mod test { Ok(()) } } - -// fixme: make sure we don't orphan notes diff --git a/rslib/src/storage/sqlite.rs b/rslib/src/storage/sqlite.rs index bd4d4497a..00307723f 100644 --- a/rslib/src/storage/sqlite.rs +++ b/rslib/src/storage/sqlite.rs @@ -294,10 +294,10 @@ impl SqliteStorage { .map_err(Into::into) } - pub(crate) fn schema_modified(&self) -> Result { + pub(crate) fn set_schema_modified(&self) -> Result<()> { self.db - .prepare_cached("select scm > ls from col")? - .query_row(NO_PARAMS, |row| row.get(0)) - .map_err(Into::into) + .prepare_cached("update col set scm = ?")? + .execute(&[TimestampMillis::now()])?; + Ok(()) } }