force a full sync when fields or templates changed without schema mod

This is not an ideal solution and will not catch repositioned fields
or templates, but is at least an improvement over the previous behaviour.

https://github.com/dae/anki/pull/349#issuecomment-547236285
This commit is contained in:
Damien Elmes 2019-10-30 10:17:09 +10:00
parent fc713d2010
commit 9a6f2be2b6

View File

@ -22,6 +22,9 @@ HTTP_TIMEOUT = 90
HTTP_PROXY = None
HTTP_BUF_SIZE = 64*1024
class UnexpectedSchemaChange(Exception):
pass
# Incremental syncing
##########################################################################
@ -95,7 +98,11 @@ class Syncer:
# ...and small objects
lchg = self.changes()
rchg = self.server.applyChanges(changes=lchg)
self.mergeChanges(lchg, rchg)
try:
self.mergeChanges(lchg, rchg)
except UnexpectedSchemaChange:
self.server.abort()
return self._forceFullSync()
# step 3: stream large tables from server
runHook("sync", "server")
while 1:
@ -119,17 +126,20 @@ class Syncer:
c = self.sanityCheck()
ret = self.server.sanityCheck2(client=c)
if ret['status'] != "ok":
# roll back and force full sync
self.col.rollback()
self.col.modSchema(False)
self.col.save()
return "sanityCheckFailed"
return self._forceFullSync()
# finalize
runHook("sync", "finalize")
mod = self.server.finish()
self.finish(mod)
return "success"
def _forceFullSync(self):
# roll back and force full sync
self.col.rollback()
self.col.modSchema(False)
self.col.save()
return "sanityCheckFailed"
def _gravesChunk(self, graves):
lim = 250
chunk = dict(notes=[], cards=[], decks=[])
@ -330,6 +340,14 @@ from notes where %s""" % d)
l = self.col.models.get(r['id'])
# if missing locally or server is newer, update
if not l or r['mod'] > l['mod']:
# This is a hack to detect when the note type has been altered
# in an import without a full sync being forced. A future
# syncing algorithm should handle this in a better way.
if l:
if len(l['flds']) != len(r['flds']):
raise UnexpectedSchemaChange()
if len(l['tmpls']) != len(r['tmpls']):
raise UnexpectedSchemaChange()
self.col.models.update(r)
# Decks