force a full sync if there have been schema changes on either side

This commit is contained in:
Damien Elmes 2011-02-11 02:40:29 +09:00
parent 7c2b202163
commit 1b7ac91a2a
2 changed files with 14 additions and 53 deletions

View file

@ -98,8 +98,11 @@ class SyncTools(object):
"Sync two decks locally. Reimplement this for finer control." "Sync two decks locally. Reimplement this for finer control."
if not self.prepareSync(0): if not self.prepareSync(0):
return return
sums = self.summaries() lsum = self.summary(self.deck.lastSync)
payload = self.genPayload(sums) rsum = self.server.summary(self.deck.lastSync)
if not lsum or not rsum:
raise Exception("full sync required")
payload = self.genPayload((lsum, rsum))
res = self.server.applyPayload(payload) res = self.server.applyPayload(payload)
self.applyPayloadReply(res) self.applyPayloadReply(res)
self.deck.reset() self.deck.reset()
@ -111,15 +114,11 @@ class SyncTools(object):
if self.localTime == self.remoteTime: if self.localTime == self.remoteTime:
return False return False
l = self._lastSync(); r = self.server._lastSync() l = self._lastSync(); r = self.server._lastSync()
# set lastSync to the lower of the two sides, and account for slow # set lastSync to the lower of the two sides, account for slow clocks,
# clocks & assume it took up to 10 seconds for the reply to arrive # and assume it took up to 10 seconds for the reply to arrive
self.deck.lastSync = min(l, r) - timediff - 10 self.deck.lastSync = max(0, min(l, r) - timediff - 10)
return True return True
def summaries(self):
return (self.summary(self.deck.lastSync),
self.server.summary(self.deck.lastSync))
def genPayload(self, summaries): def genPayload(self, summaries):
(lsum, rsum) = summaries (lsum, rsum) = summaries
self.preSyncRefresh() self.preSyncRefresh()
@ -219,10 +218,11 @@ class SyncTools(object):
def summary(self, lastSync): def summary(self, lastSync):
"Generate a full summary of modtimes for two-way syncing." "Generate a full summary of modtimes for two-way syncing."
# client may have selected an earlier sync time # if client may have selected an earlier sync time
self.deck.lastSync = lastSync self.deck.lastSync = lastSync
# ensure we're flushed first # return early if there's been a schema change
self.deck.s.flush() if self.deck.getFloat("schemaMod") > lastSync:
return None
return { return {
# cards # cards
"cards": self.realLists(self.deck.s.all( "cards": self.realLists(self.deck.s.all(

View file

@ -133,7 +133,7 @@ def test_localsync_models():
assert deck1.currentModel.cardModels[1].active == True assert deck1.currentModel.cardModels[1].active == True
deck2.currentModel.cardModels[1].active = False deck2.currentModel.cardModels[1].active = False
deck2.currentModel.setModified() deck2.currentModel.setModified()
deck2.setModified() deck2.flushMod()
client.sync() client.sync()
assert deck1.currentModel.cardModels[1].active == False assert deck1.currentModel.cardModels[1].active == False
# remove a card model # remove a card model
@ -144,25 +144,8 @@ def test_localsync_models():
assert len(deck1.currentModel.cardModels) == 1 assert len(deck1.currentModel.cardModels) == 1
client.sync() client.sync()
assert len(deck2.currentModel.cardModels) == 1 assert len(deck2.currentModel.cardModels) == 1
# add a field
c = deck1.getCard()
deck1.addFieldModel(c.fact.model, FieldModel(u"yo"))
deck1.s.refresh(c.fact)
assert len(c.fact.fields) == 3
assert c.fact['yo'] == u""
client.sync()
c2 = deck2.s.query(Card).get(c.id)
deck2.s.refresh(c2.fact)
assert c2.fact['yo'] == u""
# remove the field
assert "yo" in c2.fact.keys()
deck2.deleteFieldModel(c2.fact.model, c2.fact.model.fieldModels[2])
deck2.s.refresh(c2.fact)
assert "yo" not in c2.fact.keys()
client.sync()
deck1.s.refresh(c.fact)
assert "yo" not in c.fact.keys()
# rename a field # rename a field
c = deck1.getCard()
assert u"Front" in c.fact.keys() assert u"Front" in c.fact.keys()
deck1.renameFieldModel(deck1.currentModel, deck1.renameFieldModel(deck1.currentModel,
deck1.currentModel.fieldModels[0], deck1.currentModel.fieldModels[0],
@ -257,28 +240,6 @@ def test_localsync_media():
assert deck1.s.scalar("select count(1) from media") == 3 assert deck1.s.scalar("select count(1) from media") == 3
assert deck2.s.scalar("select count(1) from media") == 3 assert deck2.s.scalar("select count(1) from media") == 3
# One way syncing
##########################################################################
@nose.with_setup(setup_local, teardown)
def test_oneway_simple():
assert deck1.s.scalar("select count(1) from cards") == 2
assert deck2.s.scalar("select count(1) from cards") == 2
assert deck1.cardCount == 2
assert deck2.cardCount == 2
assert deck1.s.scalar("select id from tags where tag = 'foo'")
assert not deck1.s.scalar("select id from tags where tag = 'bar'")
server.deckName = "dummy"
client.syncOneWay(0)
assert deck1.s.scalar("select count(1) from cards") == 4
assert deck2.s.scalar("select count(1) from cards") == 2
assert deck1.cardCount == 4
assert deck2.cardCount == 2
assert deck1.s.scalar("select id from tags where tag = 'foo'")
assert deck1.s.scalar("select id from tags where tag = 'bar'")
# should be a noop
client.syncOneWay(0)
# Remote tests # Remote tests
########################################################################## ##########################################################################