diff --git a/anki/consts.py b/anki/consts.py index e4bebc4de..eddaec2c3 100644 --- a/anki/consts.py +++ b/anki/consts.py @@ -22,6 +22,9 @@ REV_CARDS_OLD_FIRST = 0 REV_CARDS_NEW_FIRST = 1 REV_CARDS_RANDOM = 2 +# maximum characters to store in sort cache +SORT_FIELD_LEN = 20 + # Labels ########################################################################## diff --git a/anki/deck.py b/anki/deck.py index a95e75ac1..1f7ef3b6c 100644 --- a/anki/deck.py +++ b/anki/deck.py @@ -627,9 +627,13 @@ where id = :id""", vals) def currentModel(self): return self.getModel(self.conf['currentModelId']) - def allModels(self): - return [self.getModel(id) for id in self.db.list( - "select id from models")] + def models(self): + "Return a dict of mid -> model." + mods = {} + for m in [self.getModel(id) for id in self.db.list( + "select id from models")]: + mods[m.id] = m + return mods def getModel(self, mid): return anki.models.Model(self, mid) @@ -860,9 +864,7 @@ where tid in %s""" % strids, now=time.time()) where = "" else: raise Exception() - mods = {} - for m in self.allModels(): - mods[m.id] = m + mods = self.models() groups = dict(self.db.all("select id, name from groups")) return [self._renderQA(mods[row[2]], groups[row[3]], row) for row in self._qaData(where)] @@ -908,24 +910,32 @@ from cards c, facts f, models m, groups g where c.fid == f.id and f.mid == m.id and c.gid = g.id %s""" % where) - # Field checksum bulk update + # Field checksums and sorting fields ########################################################################## - def updateFieldChecksums(self, fids): - "Update all field checksums, after find&replace, etc." + def _fieldData(self, sfids): + return self.db.execute( + "select id, mid, flds from facts where id in "+sfids) + + def updateFieldCache(self, fids, csum=True): + "Update field checksums and sort cache, after find&replace, etc." sfids = ids2str(fids) - mods = {} - for m in self.allModels(): - mods[m.id] = m + mods = self.models() r = [] - for row in self._qaData(where="and f.id in "+sfids): - fields = splitFields(row[6]) - model = mods[row[2]] - for c, f in enumerate(model.fields): - if f['uniq'] and fields[c]: - r.append((row[1], model.id, fieldChecksum(fields[c]))) - self.db.execute("delete from fsums where fid in "+sfids) - self.db.executemany("insert into fsums values (?,?,?)", r) + r2 = [] + for (fid, mid, flds) in self._fieldData(sfids): + fields = splitFields(flds) + model = mods[mid] + if csum: + for c, f in enumerate(model.fields): + if f['uniq'] and fields[c]: + r.append((fid, mid, fieldChecksum(fields[c]))) + r2.append((stripHTML(fields[model.sortIdx()])[ + :SORT_FIELD_LEN], fid)) + if csum: + self.db.execute("delete from fsums where fid in "+sfids) + self.db.executemany("insert into fsums values (?,?,?)", r) + self.db.executemany("update facts set sfld = ? where id = ?", r2) # Tags ########################################################################## diff --git a/anki/facts.py b/anki/facts.py index b8d416592..3a6f6f38b 100644 --- a/anki/facts.py +++ b/anki/facts.py @@ -40,7 +40,7 @@ select mid, crt, mod, tags, flds, data from facts where id = ?""", self.id) def flush(self): self.mod = intTime() # facts table - sfld = self._fields[self.model.sortField()] + sfld = self._fields[self.model.sortIdx()] res = self.deck.db.execute(""" insert or replace into facts values (?, ?, ?, ?, ?, ?, ?, ?)""", self.id, self.mid, self.crt, diff --git a/anki/models.py b/anki/models.py index 606956176..5730710e8 100644 --- a/anki/models.py +++ b/anki/models.py @@ -10,6 +10,7 @@ from anki.lang import _ ########################################################################## defaultConf = { + 'sortf': 0, } defaultField = { @@ -75,6 +76,9 @@ insert or replace into models values (?, ?, ?, ?, ?, ?, ?)""", self.genCSS()) self.id = ret.lastrowid + def fids(self): + return self.deck.db.list("select id from facts where mid = ?", self.id) + # Fields ################################################## @@ -89,9 +93,13 @@ insert or replace into models values (?, ?, ?, ?, ?, ?, ?)""", "Mapping of field name -> (ord, conf)." return dict([(f['name'], (c, f)) for c, f in enumerate(self.fields)]) - def sortField(self): - print "sortField() fixme" - return 0 + def sortIdx(self): + return self.conf['sortf'] + + def setSortIdx(self, idx): + assert idx > 0 and idx < len(self.fields) + self.conf['sortf'] = idx + self.deck.updateFieldCache(self.fids(), csum=False) # Templates ################################################## diff --git a/anki/storage.py b/anki/storage.py index ec8b05536..dbc515e2a 100644 --- a/anki/storage.py +++ b/anki/storage.py @@ -307,10 +307,12 @@ originalPath from media2""") # models ########### + import anki.models _moveTable(db, "models") db.execute(""" insert into models select id, cast(modified as int), -name, "{}", "{}", "{}", "" from models2""") +name, "{}", "{}", ?, "" from models2""", simplejson.dumps( + anki.models.defaultConf)) db.execute("drop table models2") # reviewHistory -> revlog @@ -454,9 +456,9 @@ questionAlign, lastFontColour, allowEmptyAnswer, typeAnswer from cardModels"""): def _rewriteModelIds(deck): # rewrite model/template/field ids - models = deck.allModels() + models = deck.models() deck.db.execute("delete from models") - for c, m in enumerate(models): + for c, m in enumerate(models.values()): old = m.id m.id = c+1 m.flush() @@ -468,7 +470,7 @@ def _postSchemaUpgrade(deck): # fix up model/template ids _rewriteModelIds(deck) # update uniq cache - deck.updateFieldChecksums(deck.db.list("select id from facts")) + deck.updateFieldCache(deck.db.list("select id from facts")) # remove old views for v in ("failedCards", "revCardsOld", "revCardsNew", "revCardsDue", "revCardsRandom", "acqCardsRandom",