From 31a548ee421b3ed8c382dd0e432ce403ade4344c Mon Sep 17 00:00:00 2001 From: Damien Elmes Date: Tue, 22 Mar 2011 07:28:45 +0900 Subject: [PATCH] add a dirty flag when we make changes that need to be cleaned up on exit, we mark the deck dirty so that if we exit without saving, we can clean up on next open --- anki/cram.py | 1 + anki/deck.py | 26 +++++++++++++++++++------- anki/sched.py | 6 +----- anki/storage.py | 5 +++-- tests/test_cards.py | 2 +- 5 files changed, 25 insertions(+), 15 deletions(-) diff --git a/anki/cram.py b/anki/cram.py index e14974eb1..c1d963880 100644 --- a/anki/cram.py +++ b/anki/cram.py @@ -92,6 +92,7 @@ and gid in %s order by %s limit %d""" % (self.today+1+self.min, ivl = self._graduatingIvl(card, conf, early) card.due = self.today + ivl # temporarily suspend it + self.deck.setDirty() card.queue = -3 def _graduatingIvl(self, card, conf, early): diff --git a/anki/deck.py b/anki/deck.py index 6ba4b92c0..698bad916 100644 --- a/anki/deck.py +++ b/anki/deck.py @@ -77,6 +77,8 @@ class _Deck(object): self._stdSched = Scheduler(self) self.sched = self._stdSched self.media = MediaRegistry(self) + # check for improper shutdown + self.cleanup() def name(self): n = os.path.splitext(os.path.basename(self.path))[0] @@ -89,12 +91,13 @@ class _Deck(object): (self.crt, self.mod, self.scm, + self.dty, self.syncName, self.lastSync, self.qconf, self.conf, self.data) = self.db.first(""" -select crt, mod, scm, syncName, lastSync, +select crt, mod, scm, dty, syncName, lastSync, qconf, conf, data from deck""") self.qconf = simplejson.loads(self.qconf) self.conf = simplejson.loads(self.conf) @@ -105,9 +108,10 @@ qconf, conf, data from deck""") self.mod = intTime() self.db.execute( """update deck set -crt=?, mod=?, scm=?, syncName=?, lastSync=?, +crt=?, mod=?, scm=?, dty=?, syncName=?, lastSync=?, qconf=?, conf=?, data=?""", - self.crt, self.mod, self.scm, self.syncName, self.lastSync, + self.crt, self.mod, self.scm, self.dty, + self.syncName, self.lastSync, simplejson.dumps(self.qconf), simplejson.dumps(self.conf), simplejson.dumps(self.data)) @@ -122,7 +126,7 @@ qconf=?, conf=?, data=?""", def close(self, save=True): "Disconnect from DB." - self.sched.onClose() + self.cleanup() if self.db: if save: self.save() @@ -142,15 +146,23 @@ qconf=?, conf=?, data=?""", self.lock() def modSchema(self): - if not self.schemaDirty(): + if not self.schemaChanged(): # next sync will be full self.emptyTrash() self.scm = intTime() - def schemaDirty(self): + def schemaChanged(self): "True if schema changed since last sync, or syncing off." return self.scm > self.lastSync + def setDirty(self): + self.dty = True + + def cleanup(self): + if self.dty: + self.sched.onClose() + self.dty = False + # Object creation helpers ########################################################################## @@ -317,7 +329,7 @@ select id from facts where id not in (select distinct fid from cards)""") if not ids: return sids = ids2str(ids) - if self.schemaDirty(): + if self.schemaChanged(): # immediate delete? self.db.execute("delete from cards where id in %s" % sids) self.db.execute("delete from revlog where cid in %s" % sids) diff --git a/anki/sched.py b/anki/sched.py index c6464ee8c..d8dccc500 100644 --- a/anki/sched.py +++ b/anki/sched.py @@ -76,11 +76,6 @@ order by due""" % self._groupLimit("rev"), self.db.execute( "update cards set queue = type where queue between -3 and -2") - def _resetSchedBuried(self): - "Put temporarily suspended cards back into play." - self.db.execute( - "update cards set queue = type where queue = -3") - # Getting the next card ########################################################################## @@ -590,6 +585,7 @@ queue = 2 %s and due <= :lim order by %s limit %d""" % ( def buryFact(self, fid): "Bury all cards for fact until next session." + self.deck.setDirty() self.db.execute("update cards set queue = -2 where fid = ?", fid) # Counts diff --git a/anki/storage.py b/anki/storage.py index 8d87a6e6f..138ffd6c1 100644 --- a/anki/storage.py +++ b/anki/storage.py @@ -62,6 +62,7 @@ create table if not exists deck ( mod integer not null, scm integer not null, ver integer not null, + dty integer not null, syncName text not null, lastSync integer not null, qconf text not null, @@ -151,7 +152,7 @@ create table if not exists tags ( ); insert or ignore into deck -values(1,0,0,0,%(v)s,'',0,'', '', ''); +values(1,0,0,0,%(v)s,0,'',0,'', '', ''); """ % ({'v':CURRENT_VERSION})) import anki.deck import anki.groups @@ -356,7 +357,7 @@ def _migrateDeckTbl(db): db.execute("delete from deck") db.execute(""" insert or replace into deck select id, cast(created as int), :t, -:t, 99, ifnull(syncName, ""), cast(lastSync as int), +:t, 99, 0, ifnull(syncName, ""), cast(lastSync as int), "", "", "" from decks""", t=intTime()) # update selective study qconf = anki.deck.defaultQconf.copy() diff --git a/tests/test_cards.py b/tests/test_cards.py index 2309b1928..9827c41c6 100644 --- a/tests/test_cards.py +++ b/tests/test_cards.py @@ -53,7 +53,7 @@ def test_delete(): deck.addFact(f) cid = f.cards()[0].id # when the schema is dirty, deletion should be immediate - assert deck.schemaDirty() == True + assert deck.schemaChanged() == True deck.reset() deck.sched.answerCard(deck.sched.getCard(), 2) assert deck.db.scalar("select count() from revlog") == 1