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

View file

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

View file

@ -182,6 +182,14 @@ def timestampID(db, table):
t += 1 t += 1
return t 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(): def guid64():
return random.randint(-sys.maxint-1, sys.maxint) return random.randint(-sys.maxint-1, sys.maxint)

View file

@ -12,21 +12,8 @@ def test_genCards():
f['Front'] = u'1' f['Front'] = u'1'
f['Back'] = u'2' f['Back'] = u'2'
deck.addFact(f) deck.addFact(f)
cards = deck.genCards(f, f.model()['tmpls']) deck.genCards([f.id], f.model()['tmpls'])
assert len(cards) == 1
assert cards[0].ord == 1
assert deck.cardCount() == 2 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(): def test_previewCards():
deck = getEmptyDeck() deck = getEmptyDeck()