diff --git a/anki/cards.py b/anki/cards.py index 4ae4b9e69..5073ef97b 100644 --- a/anki/cards.py +++ b/anki/cards.py @@ -22,6 +22,7 @@ class Card(object): self.deck = deck self.timerStarted = None self._qa = None + self._rd = None if id: self.id = id self.load() @@ -106,14 +107,30 @@ streak=?, lapses=?, grade=?, cycles=?, edue=? where id = ?""", def _getQA(self, reload=False): if not self._qa or reload: - self._qa = self.deck.renderQA([self.id], "card")[0] + gname = self.deck.db.scalar( + "select name from groups where id = ?", self.gid) + f = self.fact(); m = self.model() + data = [self.id, f.id, m.id, self.gid, self.ord, f.stringTags(), + f.joinedFields(), ""] + self._qa = self.deck._renderQA(self.model(), gname, data) return self._qa + def _reviewData(self, reload=False): + "Fetch the model and fact." + if not self._rd or reload: + f = self.deck.getFact(self.fid) + m = self.deck.getModel(f.mid) + self._rd = [f, m] + return self._rd + def fact(self): - return self.deck.getFact(self.fid) + return self._reviewData()[0] + + def model(self, reload=False): + return self._reviewData()[1] def template(self): - return self.deck.getTemplate(self.fact().mid, self.ord) + return self._reviewData()[1].templates[self.ord] def startTimer(self): self.timerStarted = time.time() diff --git a/anki/deck.py b/anki/deck.py index 698bad916..59fac6b62 100644 --- a/anki/deck.py +++ b/anki/deck.py @@ -68,6 +68,7 @@ class _Deck(object): d = datetime.datetime(d.year, d.month, d.day) d += datetime.timedelta(hours=4) self.crt = int(time.mktime(d.timetuple())) + self.modelCache = {} self.undoEnabled = False self.sessionStartReps = 0 self.sessionStartTime = 0 @@ -172,11 +173,13 @@ qconf=?, conf=?, data=?""", def getFact(self, id): return anki.facts.Fact(self, id=id) - def getTemplate(self, mid, ord): - return self.getModel(mid).templates[ord] - def getModel(self, mid): - return anki.models.Model(self, mid) + "Memoizes; call .reset() to reset cache." + if mid in self.modelCache: + return self.modelCache[mid] + m = anki.models.Model(self, mid) + self.modelCache[mid] = m + return m # Utils ########################################################################## @@ -189,6 +192,7 @@ qconf=?, conf=?, data=?""", def reset(self): "Rebuild the queue and reload data after DB modified." + self.modelCache = {} self.sched.reset() # Facts @@ -434,6 +438,7 @@ select id from cards where fid in (select id from facts where mid = ?)""", return [self._renderQA(mods[row[2]], groups[row[3]], row) for row in self._qaData(where)] + # fixme: don't need gid or data def _renderQA(self, model, gname, data): "Returns hash of id, question, answer." # data is [cid, fid, mid, gid, ord, tags, flds, data] diff --git a/anki/facts.py b/anki/facts.py index 375ec34d7..6e13146d2 100644 --- a/anki/facts.py +++ b/anki/facts.py @@ -44,7 +44,7 @@ select mid, gid, crt, mod, tags, flds, data from facts where id = ?""", self.id) self.mod = intTime() # facts table sfld = self._fields[self._model.sortIdx()] - tags = canonifyTags(self.tags) + tags = self.stringTags() res = self.deck.db.execute(""" insert or replace into facts values (?, ?, ?, ?, ?, ?, ?, ?, ?)""", self.id, self.mid, self.gid, self.crt, @@ -107,6 +107,9 @@ insert or replace into facts values (?, ?, ?, ?, ?, ?, ?, ?, ?)""", def hasTag(self, tag): return hasTag(tag, self.tags) + def stringTags(self): + return canonifyTags(self.tags) + # Unique/duplicate checks ##################################################