store the ordinals in templates/fields

this makes it more convenient to pass around templates/fields without having
to instrument them with their position in the list
This commit is contained in:
Damien Elmes 2011-03-13 00:48:19 +09:00
parent e6a8f7f619
commit d5cce19b56
3 changed files with 41 additions and 37 deletions

View file

@ -217,10 +217,10 @@ qconf=?, conf=?, data=?""",
def findTemplates(self, fact, checkActive=True): def findTemplates(self, fact, checkActive=True):
"Return active, non-empty templates." "Return active, non-empty templates."
ok = [] ok = []
for c, template in enumerate(fact.model.templates): for template in fact.model.templates:
if template['actv'] or not checkActive: if template['actv'] or not checkActive:
# [cid, fid, mid, gid, ord, tags, flds, data] # [cid, fid, mid, gid, ord, tags, flds, data]
data = [1, 1, fact.model.id, 1, c, data = [1, 1, fact.model.id, 1, template['ord'],
"", fact.joinedFields(), ""] "", fact.joinedFields(), ""]
now = self._renderQA(fact.model, "", data) now = self._renderQA(fact.model, "", data)
data[6] = "\x1f".join([""]*len(fact._fields)) data[6] = "\x1f".join([""]*len(fact._fields))
@ -230,21 +230,19 @@ qconf=?, conf=?, data=?""",
if not template['emptyAns']: if not template['emptyAns']:
if now['a'] == empty['a']: if now['a'] == empty['a']:
continue continue
# add ordinal
template['ord'] = c
ok.append(template) ok.append(template)
return ok return ok
def addCards(self, fact, tids): def genCards(self, fact, templates):
"Generate cards for templates if cards not empty."
# templates should have .ord set
ids = [] ids = []
for template in self.findTemplates(fact, False): for template in self.findTemplates(fact, False):
if template.id not in tids: if template not in templates:
continue continue
if self.db.scalar(""" if not self.db.scalar(
select count(id) from cards "select 1 from cards where fid = ? and ord = ?",
where fid = :fid and tid = :cmid""", fact.id, template.ord):
fid=fact.id, cmid=template.id) == 0:
# enough for 10 card models assuming 0.00001 timer precision
card = anki.cards.Card( card = anki.cards.Card(
fact, template, fact, template,
fact.created+0.0001*template.ord) fact.created+0.0001*template.ord)
@ -257,19 +255,6 @@ where fid = :fid and tid = :cmid""",
self.setMod() self.setMod()
return ids return ids
def factIsInvalid(self, fact):
"True if existing fact is invalid. Returns the error."
try:
fact.assertValid()
fact.assertUnique(self.db)
except FactInvalidError, e:
return e
def factUseCount(self, fid):
"Return number of cards referencing a given fact id."
return self.db.scalar("select count(id) from cards where fid = :id",
id=fid)
def _deleteFacts(self, ids): def _deleteFacts(self, ids):
"Bulk delete facts by ID. Don't call this directly." "Bulk delete facts by ID. Don't call this directly."
if not ids: if not ids:
@ -478,9 +463,9 @@ select id from cards where fid in (select id from facts where mid = ?)""",
fields = splitFields(flds) fields = splitFields(flds)
model = mods[mid] model = mods[mid]
if csum: if csum:
for c, f in enumerate(model.fields): for f in model.fields:
if f['uniq'] and fields[c]: if f['uniq'] and fields[f['ord']]:
r.append((fid, mid, fieldChecksum(fields[c]))) r.append((fid, mid, fieldChecksum(fields[f['ord']])))
r2.append((stripHTML(fields[model.sortIdx()])[ r2.append((stripHTML(fields[model.sortIdx()])[
:SORT_FIELD_LEN], fid)) :SORT_FIELD_LEN], fid))
if csum: if csum:

View file

@ -16,6 +16,7 @@ defaultConf = {
defaultField = { defaultField = {
'name': "", 'name': "",
'ord': None,
'rtl': False, 'rtl': False,
'req': False, 'req': False,
'uniq': False, 'uniq': False,
@ -28,6 +29,7 @@ defaultField = {
defaultTemplate = { defaultTemplate = {
'name': "", 'name': "",
'ord': None,
'actv': True, 'actv': True,
'qfmt': "", 'qfmt': "",
'afmt': "", 'afmt': "",
@ -101,14 +103,14 @@ insert or replace into models values (?, ?, ?, ?, ?, ?, ?)""",
return "" return ""
# fields # fields
css = "".join([self._fieldCSS( css = "".join([self._fieldCSS(
".fm%s.%s" % (hexifyID(self.id), hexifyID(c)), ".fm%s.%s" % (hexifyID(self.id), hexifyID(f['ord'])),
(f['font'], f['qsize'], f['qcol'], f['rtl'], f['pre'])) (f['font'], f['qsize'], f['qcol'], f['rtl'], f['pre']))
for c, f in enumerate(self.fields)]) for f in self.fields])
# templates # templates
css += "".join(["#cm%s-%s {text-align:%s;background:%s}\n" % ( css += "".join(["#cm%s-%s {text-align:%s;background:%s}\n" % (
hexifyID(self.id), hexifyID(c), hexifyID(self.id), hexifyID(t['ord']),
("center", "left", "right")[t['align']], t['bg']) ("center", "left", "right")[t['align']], t['bg'])
for c, t in enumerate(self.templates)]) for t in self.templates])
return css return css
def _rewriteFont(self, font): def _rewriteFont(self, font):
@ -136,8 +138,8 @@ insert or replace into models values (?, ?, ?, ?, ?, ?, ?)""",
################################################## ##################################################
def fieldMap(self): def fieldMap(self):
"Mapping of field name -> (ord, conf)." "Mapping of field name -> (ord, field)."
return dict([(f['name'], (c, f)) for c, f in enumerate(self.fields)]) return dict([(f['name'], (f['ord'], f)) for f in self.fields])
def sortIdx(self): def sortIdx(self):
return self.conf['sortf'] return self.conf['sortf']
@ -152,6 +154,7 @@ insert or replace into models values (?, ?, ?, ?, ?, ?, ?)""",
def addField(self, field): def addField(self, field):
self.fields.append(field) self.fields.append(field)
self._updateFieldOrds()
self.flush() self.flush()
def add(fields): def add(fields):
fields.append("") fields.append("")
@ -161,7 +164,7 @@ insert or replace into models values (?, ?, ?, ?, ?, ?, ?)""",
def delField(self, field): def delField(self, field):
idx = self.fields.index(field) idx = self.fields.index(field)
self.fields.remove(field) self.fields.remove(field)
self.flush() self._updateFieldOrds()
def delete(fields): def delete(fields):
del fields[idx] del fields[idx]
return fields return fields
@ -169,6 +172,7 @@ insert or replace into models values (?, ?, ?, ?, ?, ?, ?)""",
if idx == self.sortIdx(): if idx == self.sortIdx():
# need to rebuild # need to rebuild
self.deck.updateFieldCache(self.fids(), csum=False) self.deck.updateFieldCache(self.fids(), csum=False)
# flushes
self.renameField(field, None) self.renameField(field, None)
def moveField(self, field, idx): def moveField(self, field, idx):
@ -177,6 +181,7 @@ insert or replace into models values (?, ?, ?, ?, ?, ?, ?)""",
return return
self.fields.remove(field) self.fields.remove(field)
self.fields.insert(idx, field) self.fields.insert(idx, field)
self._updateFieldOrds()
self.flush() self.flush()
def move(fields, oldidx=oldidx): def move(fields, oldidx=oldidx):
val = fields[oldidx] val = fields[oldidx]
@ -200,6 +205,10 @@ insert or replace into models values (?, ?, ?, ?, ?, ?, ?)""",
field['name'] = newName field['name'] = newName
self.flush() self.flush()
def _updateFieldOrds(self):
for c, f in enumerate(self.fields):
f['ord'] = c
def _transformFields(self, fn): def _transformFields(self, fn):
self.deck.startProgress() self.deck.startProgress()
self.deck.modSchema() self.deck.modSchema()
@ -219,6 +228,8 @@ insert or replace into models values (?, ?, ?, ?, ?, ?, ?)""",
def addTemplate(self, template): def addTemplate(self, template):
self.deck.modSchema() self.deck.modSchema()
self.templates.append(template) self.templates.append(template)
self._updateTemplOrds()
self.flush()
def delTemplate(self, template): def delTemplate(self, template):
self.deck.modSchema() self.deck.modSchema()
@ -232,8 +243,13 @@ select c.id from cards c, facts f where c.fid=f.id and mid = ? and ord = ?""",
update cards set ord = ord - 1 where fid in (select id from facts update cards set ord = ord - 1 where fid in (select id from facts
where mid = ?) and ord > ?""", self.id, ord) where mid = ?) and ord > ?""", self.id, ord)
self.templates.remove(template) self.templates.remove(template)
self._updateTemplOrds()
self.flush() self.flush()
def _updateTemplOrds(self):
for c, t in enumerate(self.templates):
t['ord'] = c
# Model changing # Model changing
########################################################################## ##########################################################################

View file

@ -454,11 +454,15 @@ questionAlign, lastFontColour, allowEmptyAnswer, typeAnswer from cardModels"""):
db.execute("drop table cardModels") db.execute("drop table cardModels")
return mods return mods
def _rewriteModelIds(deck): def _fixupModels(deck):
# rewrite model/template/field ids # rewrite model/template/field ids
models = deck.models() models = deck.models()
deck.db.execute("delete from models") deck.db.execute("delete from models")
for c, m in enumerate(models.values()): for c, m in enumerate(models.values()):
# update ordinals
m._updateFieldOrds()
m._updateTemplOrds()
# rewrite id
old = m.id old = m.id
m.id = c+1 m.id = c+1
m.flush() m.flush()
@ -467,8 +471,7 @@ def _rewriteModelIds(deck):
def _postSchemaUpgrade(deck): def _postSchemaUpgrade(deck):
"Handle the rest of the upgrade to 2.0." "Handle the rest of the upgrade to 2.0."
import anki.deck import anki.deck
# fix up model/template ids _fixupModels(deck)
_rewriteModelIds(deck)
# update uniq cache # update uniq cache
deck.updateFieldCache(deck.db.list("select id from facts")) deck.updateFieldCache(deck.db.list("select id from facts"))
# remove old views # remove old views