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:
parent
fc713d2010
commit
9a6f2be2b6
30
anki/sync.py
30
anki/sync.py
@ -22,6 +22,9 @@ HTTP_TIMEOUT = 90
|
|||||||
HTTP_PROXY = None
|
HTTP_PROXY = None
|
||||||
HTTP_BUF_SIZE = 64*1024
|
HTTP_BUF_SIZE = 64*1024
|
||||||
|
|
||||||
|
class UnexpectedSchemaChange(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
# Incremental syncing
|
# Incremental syncing
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
|
||||||
@ -95,7 +98,11 @@ class Syncer:
|
|||||||
# ...and small objects
|
# ...and small objects
|
||||||
lchg = self.changes()
|
lchg = self.changes()
|
||||||
rchg = self.server.applyChanges(changes=lchg)
|
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
|
# step 3: stream large tables from server
|
||||||
runHook("sync", "server")
|
runHook("sync", "server")
|
||||||
while 1:
|
while 1:
|
||||||
@ -119,17 +126,20 @@ class Syncer:
|
|||||||
c = self.sanityCheck()
|
c = self.sanityCheck()
|
||||||
ret = self.server.sanityCheck2(client=c)
|
ret = self.server.sanityCheck2(client=c)
|
||||||
if ret['status'] != "ok":
|
if ret['status'] != "ok":
|
||||||
# roll back and force full sync
|
return self._forceFullSync()
|
||||||
self.col.rollback()
|
|
||||||
self.col.modSchema(False)
|
|
||||||
self.col.save()
|
|
||||||
return "sanityCheckFailed"
|
|
||||||
# finalize
|
# finalize
|
||||||
runHook("sync", "finalize")
|
runHook("sync", "finalize")
|
||||||
mod = self.server.finish()
|
mod = self.server.finish()
|
||||||
self.finish(mod)
|
self.finish(mod)
|
||||||
return "success"
|
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):
|
def _gravesChunk(self, graves):
|
||||||
lim = 250
|
lim = 250
|
||||||
chunk = dict(notes=[], cards=[], decks=[])
|
chunk = dict(notes=[], cards=[], decks=[])
|
||||||
@ -330,6 +340,14 @@ from notes where %s""" % d)
|
|||||||
l = self.col.models.get(r['id'])
|
l = self.col.models.get(r['id'])
|
||||||
# if missing locally or server is newer, update
|
# if missing locally or server is newer, update
|
||||||
if not l or r['mod'] > l['mod']:
|
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)
|
self.col.models.update(r)
|
||||||
|
|
||||||
# Decks
|
# Decks
|
||||||
|
Loading…
Reference in New Issue
Block a user