From f6189f453a52333307ef9c535aa8c19294010c65 Mon Sep 17 00:00:00 2001 From: Damien Elmes Date: Fri, 26 Aug 2011 22:25:20 +0900 Subject: [PATCH] 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 --- anki/cards.py | 6 ++-- anki/facts.py | 1 - anki/models.py | 1 - anki/stats.py | 6 ++-- anki/storage.py | 84 ++++++++++++++++++++++++------------------------- 5 files changed, 46 insertions(+), 52 deletions(-) diff --git a/anki/cards.py b/anki/cards.py index b04a1b510..21cfab8d1 100644 --- a/anki/cards.py +++ b/anki/cards.py @@ -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, diff --git a/anki/facts.py b/anki/facts.py index 6ac4bfaa2..b4a1067ab 100644 --- a/anki/facts.py +++ b/anki/facts.py @@ -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 = "" diff --git a/anki/models.py b/anki/models.py index 5de780de6..dc2e7267f 100644 --- a/anki/models.py +++ b/anki/models.py @@ -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 = [] diff --git a/anki/stats.py b/anki/stats.py index db7b1a71b..5227849f4 100644 --- a/anki/stats.py +++ b/anki/stats.py @@ -22,7 +22,7 @@ class CardStats(object): c = self.card fmt = lambda x, **kwargs: fmtTimeSpan(x, short=True, **kwargs) self.txt = "" - 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 = "
" + "".join(i) + "

" info += _('''\ A card's ease factor is the size of the next interval \ diff --git a/anki/storage.py b/anki/storage.py index 920c80d7b..675189bee 100644 --- a/anki/storage.py +++ b/anki/storage.py @@ -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")