update fact ids, graves

- should never skip recording graves, for the sake of merging
- 1.0 upgrade will fail on decks that have the same fact creation date. need
      to work around this in the future
This commit is contained in:
Damien Elmes 2011-08-26 21:23:16 +09:00
parent 6644c04852
commit 644a885a07
5 changed files with 13 additions and 30 deletions

View file

@ -215,12 +215,7 @@ qconf=?, conf=?, data=?""",
########################################################################## ##########################################################################
def _logDels(self, ids, type): def _logDels(self, ids, type):
# limit ids to those created prior to last sync
tbl = "cards" if type == DEL_CARD else "facts" tbl = "cards" if type == DEL_CARD else "facts"
ids = self.db.list(
"select id from %s where crt < ? and id in %s" % (
tbl, ids2str(ids)), self.lastSync)
# log
self.db.executemany("insert into graves values (%d, ?, %d)" % ( self.db.executemany("insert into graves values (%d, ?, %d)" % (
intTime(), type), ([x] for x in ids)) intTime(), type), ([x] for x in ids))

View file

@ -17,12 +17,11 @@ class Fact(object):
self.id = id self.id = id
self.load() self.load()
else: else:
self.id = None self.id = intTime(1000)
self._model = model self._model = model
self.gid = deck.defaultGroup(model.conf['gid']) self.gid = deck.defaultGroup(model.conf['gid'])
self.mid = model.id self.mid = model.id
self.crt = intTime() self.mod = intTime()
self.mod = self.crt
self.tags = [] self.tags = []
self.fields = [""] * len(self._model.fields) self.fields = [""] * len(self._model.fields)
self.data = "" self.data = ""
@ -31,12 +30,11 @@ class Fact(object):
def load(self): def load(self):
(self.mid, (self.mid,
self.gid, self.gid,
self.crt,
self.mod, self.mod,
self.tags, self.tags,
self.fields, self.fields,
self.data) = self.deck.db.first(""" self.data) = self.deck.db.first("""
select mid, gid, crt, mod, tags, flds, data from facts where id = ?""", self.id) select mid, gid, mod, tags, flds, data from facts where id = ?""", self.id)
self.fields = splitFields(self.fields) self.fields = splitFields(self.fields)
self.tags = parseTags(self.tags) self.tags = parseTags(self.tags)
self._model = self.deck.getModel(self.mid) self._model = self.deck.getModel(self.mid)
@ -47,8 +45,8 @@ select mid, gid, crt, mod, tags, flds, data from facts where id = ?""", self.id)
sfld = stripHTML(self.fields[self._model.sortIdx()]) sfld = stripHTML(self.fields[self._model.sortIdx()])
tags = self.stringTags() tags = self.stringTags()
res = self.deck.db.execute(""" res = self.deck.db.execute("""
insert or replace into facts values (?, ?, ?, ?, ?, ?, ?, ?, ?)""", insert or replace into facts values (?, ?, ?, ?, ?, ?, ?, ?)""",
self.id, self.mid, self.gid, self.crt, self.id, self.mid, self.gid,
self.mod, tags, self.joinedFields(), self.mod, tags, self.joinedFields(),
sfld, self.data) sfld, self.data)
self.id = res.lastrowid self.id = res.lastrowid

View file

@ -69,7 +69,7 @@ class Finder(object):
return "select id from cards c where " + lim return "select id from cards c where " + lim
elif type.startswith("fact"): elif type.startswith("fact"):
if type == "factCrt": if type == "factCrt":
sort = "f.crt, c.ord" sort = "f.id, c.ord"
elif type == "factMod": elif type == "factMod":
sort = "f.mod, c.ord" sort = "f.mod, c.ord"
elif type == "factFld": elif type == "factFld":

View file

@ -94,7 +94,6 @@ create table if not exists facts (
id integer primary key, id integer primary key,
mid integer not null, mid integer not null,
gid integer not null, gid integer not null,
crt integer not null,
mod integer not null, mod integer not null,
tags text not null, tags text not null,
flds text not null, flds text not null,
@ -281,7 +280,7 @@ end)
""") """)
# pull facts into memory, so we can merge them with fields efficiently # pull facts into memory, so we can merge them with fields efficiently
facts = db.all(""" facts = db.all("""
select id, modelId, 1, cast(created as int), cast(modified as int), tags select id, modelId, 1, cast(created*1000 as int), cast(modified as int), tags
from facts order by created""") from facts order by created""")
# build field hash # build field hash
fields = {} fields = {}
@ -297,9 +296,11 @@ from facts order by created""")
from anki.utils import minimizeHTML from anki.utils import minimizeHTML
for c, row in enumerate(facts): for c, row in enumerate(facts):
oldid = row[0] oldid = row[0]
map[oldid] = c+1
row = list(row) row = list(row)
row[0] = c+1 # get rid of old created column and update id
row[0] = row[3]
del row[3]
map[oldid] = row[0]
row.append(minimizeHTML("\x1f".join([x[1] for x in sorted(fields[oldid])]))) row.append(minimizeHTML("\x1f".join([x[1] for x in sorted(fields[oldid])])))
data.append(row) data.append(row)
# use the new order to rewrite fact ids in cards table # use the new order to rewrite fact ids in cards table
@ -307,7 +308,7 @@ from facts order by created""")
# and put the facts into the new table # and put the facts into the new table
db.execute("drop table facts") db.execute("drop table facts")
_addSchema(db, False) _addSchema(db, False)
db.executemany("insert into facts values (?,?,?,?,?,?,?,'','')", data) db.executemany("insert into facts values (?,?,?,?,?,?,'','')", data)
db.execute("drop table fields") db.execute("drop table fields")
# media # media

View file

@ -65,18 +65,7 @@ def test_delete():
assert deck.db.scalar("select count() from cards") == 0 assert deck.db.scalar("select count() from cards") == 0
assert deck.db.scalar("select count() from fsums") == 0 assert deck.db.scalar("select count() from fsums") == 0
assert deck.db.scalar("select count() from revlog") == 0 assert deck.db.scalar("select count() from revlog") == 0
assert deck.db.scalar("select count() from graves") == 0 assert deck.db.scalar("select count() from graves") == 2
# add the fact back
deck.addFact(f)
assert deck.cardCount() == 1
cid = f.cards()[0].id
# delete again, this time with syncing enabled
deck.syncName = "abc"
deck.lastSync = time.time()
deck.delCards([cid])
assert deck.cardCount() == 0
assert deck.factCount() == 0
assert deck.db.scalar("select count() from graves") != 0
def test_misc(): def test_misc():
d = getEmptyDeck() d = getEmptyDeck()