convert genCards() to bulk update; drop random

This commit is contained in:
Damien Elmes 2011-10-22 03:39:34 +09:00
parent 852189808f
commit 46dd863f3c
4 changed files with 42 additions and 42 deletions

View file

@ -5,7 +5,7 @@
import time, os, random, re, stat, simplejson, datetime, copy, shutil
from anki.lang import _, ngettext
from anki.utils import ids2str, hexifyID, checksum, fieldChecksum, stripHTML, \
intTime, splitFields, joinFields
intTime, splitFields, joinFields, maxID
from anki.hooks import runHook, runFilter
from anki.sched import Scheduler
from anki.models import ModelManager
@ -280,27 +280,36 @@ crt=?, mod=?, scm=?, dty=?, usn=?, ls=?, conf=?""",
ok.append(t)
return ok
def genCards(self, fact, templates):
"Generate cards for templates if cards not empty. Return cards."
cards = []
# if random mode, determine insertion point
if self.models.randomNew():
# if this fact has existing new cards, use their due time
due = self.db.scalar(
"select due from cards where fid = ? and queue = 0", fact.id)
due = due or self._randPos()
else:
due = fact.id
for template in self.findTemplates(fact, checkActive=False):
if template not in templates:
continue
# if it doesn't already exist
if not self.db.scalar(
"select 1 from cards where fid = ? and ord = ?",
fact.id, template['ord']):
# create
cards.append(self._newCard(fact, template, due))
return cards
def genCards(self, fids, limit=None):
"Generate cards for active or limited, non-empty templates."
# build map of (fid,ord) so we don't create dupes
sfids = ids2str(fids)
have = {}
for fid, ord in self.db.execute(
"select fid, ord from cards where fid in "+sfids):
have[(fid,ord)] = True
# build cards for each fact
data = []
ts = maxID(self.db)
for fid, mid, gid, flds in self.db.execute(
"select id, mid, gid, flds from facts where id in "+sfids):
model = self.models.get(mid)
avail = self.models.availOrds(model, flds)
ok = []
for t in model['tmpls']:
if not limit and not t['actv']:
continue
elif limit and t not in limit:
continue
elif (fid,t['ord']) in have:
continue
if t['ord'] in avail:
data.append((ts, fid, t['gid'] or gid, t['ord'],
ts, fid))
# bulk update
self.db.executemany("""
insert into cards values (?,?,?,?,?,-1,0,0,?,0,0,0,0,0,0,0,"")""",
data)
# type 0 - when previewing in add dialog, only non-empty & active
# type 1 - when previewing edit, only existing

View file

@ -2,7 +2,7 @@
# Copyright: Damien Elmes <anki@ichi2.net>
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
from anki.utils import intTime
from anki.utils import intTime, maxID
# Base importer
##########################################################################
@ -27,11 +27,7 @@ class Importer(object):
# need to make sure our starting point is safe.
def _prepareTS(self):
now = intTime(1000)
for tbl in "cards", "facts":
now = max(now, self.dst.db.scalar(
"select max(id) from %s" % tbl))
self._ts = now
self._ts = maxID(self.dst.db)
def ts(self):
self._ts += 1

View file

@ -182,6 +182,14 @@ def timestampID(db, table):
t += 1
return t
def maxID(db):
"Return the first safe ID to use."
now = intTime(1000)
for tbl in "cards", "facts":
now = max(now, db.scalar(
"select max(id) from %s" % tbl))
return now + 1
def guid64():
return random.randint(-sys.maxint-1, sys.maxint)

View file

@ -12,21 +12,8 @@ def test_genCards():
f['Front'] = u'1'
f['Back'] = u'2'
deck.addFact(f)
cards = deck.genCards(f, f.model()['tmpls'])
assert len(cards) == 1
assert cards[0].ord == 1
deck.genCards([f.id], f.model()['tmpls'])
assert deck.cardCount() == 2
assert cards[0].due == f.id
# should work on random mode too
deck.models.current()['newOrder'] = NEW_CARDS_RANDOM
f = deck.newFact()
f['Front'] = u'1'
f['Back'] = u'2'
deck.addFact(f)
cards = deck.genCards(f, f.model()['tmpls'])
assert deck.cardCount() == 4
c = deck.db.list("select due from cards where fid = ?", f.id)
assert c[0] == c[1]
def test_previewCards():
deck = getEmptyDeck()