don't bump mod time when moving cards into/out of a filtered deck

fixes the following:
- create a filtered deck and sync it
- review cards in the filtered deck and delete it
- sync again

The filtered deck deletion was bumping the mod time on cards at the
start of the sync, preventing the reviews from being synced from the
other side, leading to lost reviews and sanity check errors.
This commit is contained in:
Damien Elmes 2015-03-19 15:35:04 +11:00
parent b5ab140e7b
commit b0f7ddfefb
2 changed files with 34 additions and 4 deletions

View file

@ -975,8 +975,8 @@ select id from cards where did in %s and queue = 2 and due <= ? limit ?)"""
self.col.db.execute(""" self.col.db.execute("""
update cards set did = odid, queue = (case when type = 1 then 0 update cards set did = odid, queue = (case when type = 1 then 0
else type end), type = (case when type = 1 then 0 else type end), else type end), type = (case when type = 1 then 0 else type end),
due = odue, odue = 0, odid = 0, usn = ?, mod = ? where %s""" % lim, due = odue, odue = 0, odid = 0, usn = ? where %s""" % lim,
self.col.usn(), intTime()) self.col.usn())
def remFromDyn(self, cids): def remFromDyn(self, cids):
self.emptyDyn(None, "id in %s and odid" % ids2str(cids)) self.emptyDyn(None, "id in %s and odid" % ids2str(cids))
@ -1012,7 +1012,7 @@ due = odue, odue = 0, odid = 0, usn = ?, mod = ? where %s""" % lim,
t = intTime(); u = self.col.usn() t = intTime(); u = self.col.usn()
for c, id in enumerate(ids): for c, id in enumerate(ids):
# start at -100000 so that reviews are all due # start at -100000 so that reviews are all due
data.append((did, -100000+c, t, u, id)) data.append((did, -100000+c, u, id))
# due reviews stay in the review queue. careful: can't use # due reviews stay in the review queue. careful: can't use
# "odid or did", as sqlite converts to boolean # "odid or did", as sqlite converts to boolean
queue = """ queue = """
@ -1023,7 +1023,7 @@ due = odue, odue = 0, odid = 0, usn = ?, mod = ? where %s""" % lim,
update cards set update cards set
odid = (case when odid then odid else did end), odid = (case when odid then odid else did end),
odue = (case when odue then odue else due end), odue = (case when odue then odue else due end),
did = ?, queue = %s, due = ?, mod = ?, usn = ? where id = ?""" % queue, data) did = ?, queue = %s, due = ?, usn = ? where id = ?""" % queue, data)
def _dynIvlBoost(self, card): def _dynIvlBoost(self, card):
assert card.odid and card.type == 2 assert card.odid and card.type == 2

View file

@ -332,3 +332,33 @@ def _test_speed():
print "load %d" % ((time.time() - t)*1000); t = time.time() print "load %d" % ((time.time() - t)*1000); t = time.time()
assert client.sync() == "success" assert client.sync() == "success"
print "sync %d" % ((time.time() - t)*1000); t = time.time() print "sync %d" % ((time.time() - t)*1000); t = time.time()
@nose.with_setup(setup_modified)
def test_filtered_delete():
test_sync()
nid = deck1.db.scalar("select id from notes")
note = deck1.getNote(nid)
card = note.cards()[0]
card.type = 2
card.ivl = 10
card.factor = 2500
card.due = deck1.sched.today
card.flush()
# put cards into a filtered deck
did = deck1.decks.newDyn("dyn")
deck1.sched.rebuildDyn(did)
# sync the filtered deck
assert client.sync() == "success"
# answer the card locally
time.sleep(1)
card.load()
card.startTimer()
deck1.sched.answerCard(card, 4)
assert card.ivl > 10
# delete the filtered deck
deck1.decks.rem(did)
# sync again
assert client.sync() == "success"
card.load()
assert card.ivl > 10
return