update card ids

- upgrade facts before cards so we don't have to rewrite the cards table twice
- ensure duplicate card creation times are accounted for
This commit is contained in:
Damien Elmes 2011-08-26 22:25:20 +09:00
parent 644a885a07
commit f6189f453a
5 changed files with 46 additions and 52 deletions

View file

@ -28,7 +28,7 @@ class Card(object):
self.load()
else:
# to flush, set fid, ord, and due
self.id = None
self.id = intTime(1000)
self.gid = 1
self.crt = intTime()
self.type = 0
@ -47,7 +47,6 @@ class Card(object):
self.fid,
self.gid,
self.ord,
self.crt,
self.mod,
self.type,
self.queue,
@ -69,12 +68,11 @@ class Card(object):
self.deck.db.execute(
"""
insert or replace into cards values
(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)""",
(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)""",
self.id,
self.fid,
self.gid,
self.ord,
self.crt,
self.mod,
self.type,
self.queue,

View file

@ -21,7 +21,6 @@ class Fact(object):
self._model = model
self.gid = deck.defaultGroup(model.conf['gid'])
self.mid = model.id
self.mod = intTime()
self.tags = []
self.fields = [""] * len(self._model.fields)
self.data = ""

View file

@ -65,7 +65,6 @@ class Model(object):
else:
self.id = intTime(1000)
self.name = u""
self.mod = intTime()
self.conf = defaultConf.copy()
self.css = ""
self.fields = []

View file

@ -22,7 +22,7 @@ class CardStats(object):
c = self.card
fmt = lambda x, **kwargs: fmtTimeSpan(x, short=True, **kwargs)
self.txt = "<table width=100%%>"
self.addLine(_("Added"), self.date(c.crt))
self.addLine(_("Added"), self.date(c.id/1000))
first = self.deck.db.scalar(
"select min(time) from revlog where cid = ?", c.id)
last = self.deck.db.scalar(
@ -549,10 +549,10 @@ where 1 """ + self._limit())
self._line(i, _("Average ease factor"), "%d%%" % avg)
self._line(i, _("Highest ease factor"), "%d%%" % high)
min = self.deck.db.scalar(
"select min(crt) from cards where 1 " + self._limit())
"select min(id) from cards where 1 " + self._limit())
if min:
self._line(i, _("First card created"), _("%s ago") % fmtTimeSpan(
time.time() - min))
time.time() - (min/1000)))
info = "<table width=100%>" + "".join(i) + "</table><p>"
info += _('''\
A card's <i>ease factor</i> is the size of the next interval \

View file

@ -75,7 +75,6 @@ create table if not exists cards (
fid integer not null,
gid integer not null,
ord integer not null,
crt integer not null,
mod integer not null,
type integer not null,
queue integer not null,
@ -207,22 +206,6 @@ def _moveTable(db, table, cards=False):
db.execute("drop table "+table)
_addSchema(db, False)
def _insertWithIdChange(db, map, idx, table, numVals):
"Fetching and re-inserting is a lot faster than row by row updates."
data = []
for row in db.all("select * from %s" % table):
row = list(row)
try:
row[idx] = map[row[idx]]
data.append(row)
except:
# referenced non-existant object
pass
db.execute("delete from %s" % table)
db.executemany(
"insert into %s values (?%s)" % (table, ",?"*(numVals-1)),
data)
def _upgradeSchema(db):
"Alter tables prior to ORM initialization."
try:
@ -236,30 +219,6 @@ def _upgradeSchema(db):
return ver
runHook("1.x upgrade", db)
# cards
###########
# move into temp table
_moveTable(db, "cards", True)
# use the new order to rewrite card ids
cardmap = dict(db.all("select id, rowid from cards2"))
# move back, preserving new ids, and rewriting types
db.execute("""
insert into cards select rowid, factId, 1, ordinal, cast(created as int),
cast(modified as int),
(case relativeDelay
when 0 then 1
when 1 then 2
when 2 then 0 end),
(case type
when 0 then 1
when 1 then 2
when 2 then 0
else type end),
cast(due as int), cast(interval as int),
cast(factor*1000 as int), reps, noCount, 0, 0, 0, "" from cards2
order by created""")
db.execute("drop table cards2")
# tags
###########
_moveTable(db, "tags")
@ -293,24 +252,63 @@ from facts order by created""")
# bold/italics/underline cruft.
map = {}
data = []
factmap = {}
from anki.utils import minimizeHTML
for c, row in enumerate(facts):
oldid = row[0]
row = list(row)
# get rid of old created column and update id
factmap[row[0]] = row[3]
row[0] = row[3]
del row[3]
map[oldid] = row[0]
row.append(minimizeHTML("\x1f".join([x[1] for x in sorted(fields[oldid])])))
data.append(row)
# use the new order to rewrite fact ids in cards table
_insertWithIdChange(db, map, 1, "cards", 17)
# and put the facts into the new table
db.execute("drop table facts")
_addSchema(db, False)
db.executemany("insert into facts values (?,?,?,?,?,?,'','')", data)
db.execute("drop table fields")
# cards
###########
# we need to pull this into memory, to rewrite the creation time if
# it's not unique and update the fact id
times = {}
rows = []
cardmap = {}
for row in db.execute("""
select id, cast(created*1000 as int), factId, ordinal,
cast(modified as int),
(case relativeDelay
when 0 then 1
when 1 then 2
when 2 then 0 end),
(case type
when 0 then 1
when 1 then 2
when 2 then 0
else type end),
cast(due as int), cast(interval as int),
cast(factor*1000 as int), reps, noCount from cards
order by created"""):
# find an unused time
row = list(row)
while row[1] in times:
row[1] += 1
times[row[1]] = True
# rewrite fact id
row[2] = factmap[row[2]]
# note id change and save all but old id
cardmap[row[0]] = row[1]
rows.append(row[1:])
# drop old table and rewrite
db.execute("drop table cards")
_addSchema(db, False)
db.executemany("""
insert into cards values (?, ?, 1, ?, ?, ?, ?, ?, ?, ?, ?, ?, 0, 0, 0, "")""",
rows)
# media
###########
db.execute("drop table media")