change cards table schema

In preparation for cramming:

- add odid for storing old deck on a per-card basis
- rename edue to odue
- at the moment note.did still exists, but in the future we may ignore it and
  use model.did instead
This commit is contained in:
Damien Elmes 2012-03-08 11:28:12 +09:00
parent 528224895c
commit a2312f9a1f
11 changed files with 44 additions and 29 deletions

View file

@ -38,7 +38,8 @@ class Card(object):
self.reps = 0
self.lapses = 0
self.left = 0
self.edue = 0
self.odue = 0
self.odid = 0
self.flags = 0
self.data = ""
@ -57,7 +58,8 @@ class Card(object):
self.reps,
self.lapses,
self.left,
self.edue,
self.odue,
self.odid,
self.flags,
self.data) = self.col.db.first(
"select * from cards where id = ?", self.id)
@ -70,7 +72,7 @@ class Card(object):
self.col.db.execute(
"""
insert or replace into cards values
(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)""",
(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)""",
self.id,
self.nid,
self.did,
@ -85,7 +87,8 @@ insert or replace into cards values
self.reps,
self.lapses,
self.left,
self.edue,
self.odue,
self.odid,
self.flags,
self.data)
@ -95,10 +98,10 @@ insert or replace into cards values
self.col.db.execute(
"""update cards set
mod=?, usn=?, type=?, queue=?, due=?, ivl=?, factor=?, reps=?,
lapses=?, left=?, edue=? where id = ?""",
lapses=?, left=?, odue=? where id = ?""",
self.mod, self.usn, self.type, self.queue, self.due, self.ivl,
self.factor, self.reps, self.lapses,
self.left, self.edue, self.id)
self.left, self.odue, self.id)
def q(self, reload=False):
return self.css() + self._getQA(reload)['q']

View file

@ -310,7 +310,7 @@ crt=?, mod=?, scm=?, dty=?, usn=?, ls=?, conf=?""",
ts += 1
# bulk update
self.db.executemany("""
insert into cards values (?,?,?,?,?,?,0,0,?,0,0,0,0,0,0,0,"")""",
insert into cards values (?,?,?,?,?,?,0,0,?,0,0,0,0,0,0,0,0,"")""",
data)
return rem

View file

@ -32,10 +32,10 @@ MEDIA_ADD = 0
MEDIA_REM = 1
# deck schema & syncing vars
SCHEMA_VERSION = 1
SCHEMA_VERSION = 2
SYNC_ZIP_SIZE = int(2.5*1024*1024)
SYNC_URL = os.environ.get("SYNC_URL") or "https://beta.ankiweb.net/sync/"
SYNC_VER = 0
SYNC_VER = 1
# Labels
##########################################################################

View file

@ -140,7 +140,7 @@ class AnkiExporter(Exporter):
nids[row[1]] = True
data.append(row)
self.dst.db.executemany(
"insert into cards values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",
"insert into cards values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",
data)
# notes
strnids = ids2str(nids.keys())

View file

@ -232,7 +232,7 @@ class Anki2Importer(Importer):
cnt += 1
# apply
self.dst.db.executemany("""
insert into cards values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)""", cards)
insert into cards values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)""", cards)
self.dst.db.executemany("""
insert into revlog values (?,?,?,?,?,?,?,?,?)""", revlog)
self.log.append(_("%d cards imported.") % cnt)

View file

@ -11,11 +11,10 @@ from anki.lang import _, ngettext
from anki.consts import *
from anki.hooks import runHook
# revlog:
# types: 0=lrn, 1=rev, 2=relrn, 3=cram
# revlog types: 0=lrn, 1=rev, 2=relrn, 3=cram
# other queue types: -1=suspended, -2=buried
# positive intervals are in days (rev), negative intervals in seconds (lrn)
# the standard Anki scheduler
class Scheduler(object):
name = "std"
def __init__(self, col):
@ -104,9 +103,9 @@ order by due""" % self._deckLimit(),
return 3
def onClose(self):
"Unbury and remove temporary suspends on close."
"Unbury cards when closing."
self.col.db.execute(
"update cards set queue = type where queue between -3 and -2")
"update cards set queue = type where queue = -2")
# Rev/lrn/time daily stats
##########################################################################
@ -447,7 +446,7 @@ limit %d""" % (self._deckLimit(), self.reportLimit), lim=self.dayCutoff)
def _rescheduleAsRev(self, card, conf, early):
if card.type == 2:
# failed; put back entry due
card.due = card.edue
card.due = card.odue
else:
self._rescheduleNew(card, conf, early)
card.queue = 2
@ -498,7 +497,7 @@ limit %d""" % (self._deckLimit(), self.reportLimit), lim=self.dayCutoff)
extra = " and id in "+ids2str(ids)
self.col.db.execute("""
update cards set
due = edue, queue = 2, mod = %d, usn = %d
due = odue, queue = 2, mod = %d, usn = %d
where queue = 1 and type = 2
%s
""" % (intTime(), self.col.usn(), extra))
@ -600,7 +599,7 @@ did = ? and queue = 2 and due <= ? %s limit ?""" % order,
card.due = self.today + card.ivl
# put back in the learn queue?
if conf['delays']:
card.edue = card.due
card.odue = card.due
card.due = int(self._delayForGrade(conf, 0) + time.time())
card.left = len(conf['delays'])
card.queue = 1

View file

@ -46,7 +46,19 @@ def Collection(path, lock=True, server=False, sync=True):
# no upgrades necessary at the moment
def _upgradeSchema(db):
if db.scalar("select ver from col") < SCHEMA_VERSION:
print "upgrading"
db.execute("alter table cards rename to cards2")
_addSchema(db)
db.execute("""
insert into cards select
id, nid, did, ord, mod, usn, type, queue, due, ivl, factor, reps, lapses,
left, edue, 0, flags, data from cards2""")
db.execute("drop table cards2")
db.execute("update col set ver = 2")
_updateIndices(db)
return SCHEMA_VERSION
def _upgrade(col, ver):
return
@ -110,7 +122,8 @@ create table if not exists cards (
reps integer not null,
lapses integer not null,
left integer not null,
edue integer not null,
odue integer not null,
odid integer not null,
flags integer not null,
data text not null
);

View file

@ -182,7 +182,7 @@ from revlog where %s""" % d)
elif table == "cards":
return x("""
select id, nid, did, ord, mod, %d, type, queue, due, ivl, factor, reps,
lapses, left, edue, flags, data from cards where %s""" % d)
lapses, left, odue, odid, flags, data from cards where %s""" % d)
else:
return x("""
select id, guid, mid, did, mod, %d, tags, flds, '', '', flags, data
@ -363,7 +363,7 @@ from notes where %s""" % d)
def mergeCards(self, cards):
self.col.db.executemany(
"insert or replace into cards values "
"(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",
"(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",
self.newerRows(cards, "cards", 4))
def mergeNotes(self, notes):

View file

@ -226,7 +226,7 @@ order by created"""):
db.execute("drop table cards")
_addSchema(db, False)
db.executemany("""
insert into cards values (?,?,1,?,?,?,?,?,?,?,?,?,?,0,0,0,"")""",
insert into cards values (?,?,1,?,?,?,?,?,?,?,?,?,?,0,0,0,0,"")""",
rows)
# reviewHistory -> revlog
@ -679,7 +679,7 @@ and ord = ? limit 1""", m['id'], t['ord']):
# suspended cards don't use ranges anymore
col.db.execute("update cards set queue=-1 where queue between -3 and -1")
col.db.execute("update cards set queue=-2 where queue between 3 and 5")
col.db.execute("update cards set queue=-3 where queue between 6 and 8")
col.db.execute("update cards set queue=type where queue between 6 and 8")
# remove old deleted tables
for t in ("cards", "notes", "models", "media"):
col.db.execute("drop table if exists %sDeleted" % t)
@ -687,7 +687,7 @@ and ord = ? limit 1""", m['id'], t['ord']):
self._rewriteNewDue()
# and failed cards
left = len(col.decks.confForDid(1)['new']['delays'])
col.db.execute("update cards set edue = ?, left=? where type = 1",
col.db.execute("update cards set odue = ?, left=? where type = 1",
col.sched.today+1, left)
# and due cards
col.db.execute("""

View file

@ -51,7 +51,7 @@ def test_anki2():
imp.run()
check()
assert len(os.listdir(dst.media.dir())) == 1
print dst.path
#print dst.path
def test_anki1():
# get the deck path to import

View file

@ -176,7 +176,7 @@ def test_learn():
# now failed card handling
c.type = 2
c.queue = 1
c.edue = 123
c.odue = 123
d.sched.answerCard(c, 3)
assert c.due == 123
assert c.type == 2
@ -184,7 +184,7 @@ def test_learn():
# we should be able to remove manually, too
c.type = 2
c.queue = 1
c.edue = 321
c.odue = 321
c.flush()
d.sched.removeFailed()
c.load()
@ -245,7 +245,7 @@ def test_reviews():
d.sched.answerCard(c, 1)
assert c.queue == 1
# it should be due tomorrow, with an interval of 1
assert c.edue == d.sched.today + 1
assert c.odue == d.sched.today + 1
assert c.ivl == 1
# but because it's in the learn queue, its current due time should be in
# the future