mirror of
https://github.com/ankitects/anki.git
synced 2025-11-11 15:17:12 -05:00
refactor ordering
This commit is contained in:
parent
291bd399b7
commit
efe6177c7a
4 changed files with 64 additions and 100 deletions
|
|
@ -632,9 +632,9 @@ update facts set tags = :t, mod = :n where id = :id""", [fix(row) for row in res
|
||||||
# Finding cards
|
# Finding cards
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
|
||||||
def findCards(self, query):
|
def findCards(self, query, sort=None):
|
||||||
import anki.find
|
import anki.find
|
||||||
return anki.find.Finder(self).findCards(query)
|
return anki.find.Finder(self).findCards(query, sort)
|
||||||
|
|
||||||
def findReplace(self, *args, **kwargs):
|
def findReplace(self, *args, **kwargs):
|
||||||
import anki.find
|
import anki.find
|
||||||
|
|
|
||||||
149
anki/find.py
149
anki/find.py
|
|
@ -20,15 +20,61 @@ class Finder(object):
|
||||||
def __init__(self, deck):
|
def __init__(self, deck):
|
||||||
self.deck = deck
|
self.deck = deck
|
||||||
|
|
||||||
def findCards(self, query):
|
def findCards(self, query, sort=None):
|
||||||
|
"Return a list of card ids for QUERY."
|
||||||
self.query = query
|
self.query = query
|
||||||
(q, args) = self.findCardsWhere()
|
self._findLimits()
|
||||||
query = "select id from cards"
|
if not self.lims['valid']:
|
||||||
if q:
|
return []
|
||||||
query += " where " + q
|
(q, args) = self._whereClause()
|
||||||
print query, args
|
query = self._orderedSelect(sort, q)
|
||||||
return self.deck.db.list(query, **args)
|
return self.deck.db.list(query, **args)
|
||||||
|
|
||||||
|
def _whereClause(self):
|
||||||
|
x = []
|
||||||
|
if self.lims['fact']:
|
||||||
|
x.append("fid in (select id from facts where %s)" % " and ".join(
|
||||||
|
self.lims['fact']))
|
||||||
|
if self.lims['card']:
|
||||||
|
x.extend(self.lims['card'])
|
||||||
|
q = " and ".join(x)
|
||||||
|
if not q:
|
||||||
|
q = "1"
|
||||||
|
return q, self.lims['args']
|
||||||
|
|
||||||
|
def _orderedSelect(self, type, lim):
|
||||||
|
if not type:
|
||||||
|
return "select id from cards where " + lim
|
||||||
|
elif type.startswith("fact"):
|
||||||
|
if type == "factCrt":
|
||||||
|
sort = "f.crt"
|
||||||
|
elif type == "factMod":
|
||||||
|
sort = "f.mod"
|
||||||
|
elif type == "factFld":
|
||||||
|
sort = "f.sfld collate nocase"
|
||||||
|
else:
|
||||||
|
raise Exception()
|
||||||
|
return """
|
||||||
|
select c.id from cards c, facts f where %s and c.id=f.id
|
||||||
|
order by %s""" % (lim, sort)
|
||||||
|
elif type.startswith("card"):
|
||||||
|
if type == "cardMod":
|
||||||
|
sort = "c.mod"
|
||||||
|
elif type == "cardReps":
|
||||||
|
sort = "c.reps"
|
||||||
|
elif type == "cardDue":
|
||||||
|
sort = "c.due"
|
||||||
|
elif type == "cardEase":
|
||||||
|
sort = "c.ease"
|
||||||
|
elif type == "cardLapses":
|
||||||
|
sort = "c.lapses"
|
||||||
|
else:
|
||||||
|
raise Exception()
|
||||||
|
return "select c.id from cards c where %s order by %s" % (
|
||||||
|
lim, sort)
|
||||||
|
else:
|
||||||
|
raise Exception()
|
||||||
|
|
||||||
def _findLimits(self):
|
def _findLimits(self):
|
||||||
"Generate a list of fact/card limits for the query."
|
"Generate a list of fact/card limits for the query."
|
||||||
self.lims = {
|
self.lims = {
|
||||||
|
|
@ -142,19 +188,6 @@ where mid in %s and flds like ? escape '\\'""" % (
|
||||||
extra = "not" if isNeg else ""
|
extra = "not" if isNeg else ""
|
||||||
self.lims['fact'].append("id %s in %s" % (extra, ids2str(fids)))
|
self.lims['fact'].append("id %s in %s" % (extra, ids2str(fids)))
|
||||||
|
|
||||||
def findCardsWhere(self):
|
|
||||||
self._findLimits()
|
|
||||||
if not self.lims['valid']:
|
|
||||||
return "0", {}
|
|
||||||
x = []
|
|
||||||
if self.lims['fact']:
|
|
||||||
x.append("fid in (select id from facts where %s)" % " and ".join(
|
|
||||||
self.lims['fact']))
|
|
||||||
if self.lims['card']:
|
|
||||||
x.extend(self.lims['card'])
|
|
||||||
q = " and ".join(x)
|
|
||||||
return q, self.lims['args']
|
|
||||||
|
|
||||||
def _fieldNames(self):
|
def _fieldNames(self):
|
||||||
fields = set()
|
fields = set()
|
||||||
for m in self.deck.models().values():
|
for m in self.deck.models().values():
|
||||||
|
|
@ -323,81 +356,3 @@ def findDuplicates(deck, fmids):
|
||||||
else:
|
else:
|
||||||
vals[val].append(fid)
|
vals[val].append(fid)
|
||||||
return [(k,v) for (k,v) in vals.items() if len(v) > 1]
|
return [(k,v) for (k,v) in vals.items() if len(v) > 1]
|
||||||
|
|
||||||
# Find & sort
|
|
||||||
##########################################################################
|
|
||||||
|
|
||||||
# copied from ankiqt and trivially changed; will not work at the moment
|
|
||||||
|
|
||||||
# if idx == 0:
|
|
||||||
# self.sortKey = "question"
|
|
||||||
# elif idx == 1:
|
|
||||||
# self.sortKey = "answer"
|
|
||||||
# elif idx == 2:
|
|
||||||
# self.sortKey = "created"
|
|
||||||
# elif idx == 3:
|
|
||||||
# self.sortKey = "modified"
|
|
||||||
# elif idx == 4:
|
|
||||||
# self.sortKey = "combinedDue"
|
|
||||||
# elif idx == 5:
|
|
||||||
# self.sortKey = "interval"
|
|
||||||
# elif idx == 6:
|
|
||||||
# self.sortKey = "reps"
|
|
||||||
# elif idx == 7:
|
|
||||||
# self.sortKey = "factor"
|
|
||||||
# elif idx == 8:
|
|
||||||
# self.sortKey = "fact"
|
|
||||||
# elif idx == 9:
|
|
||||||
# self.sortKey = "noCount"
|
|
||||||
# elif idx == 10:
|
|
||||||
# self.sortKey = "firstAnswered"
|
|
||||||
# else:
|
|
||||||
# self.sortKey = ("field", self.sortFields[idx-11])
|
|
||||||
|
|
||||||
def findSorted(deck, query, sortKey):
|
|
||||||
# sorting
|
|
||||||
if not query.strip():
|
|
||||||
ads = ""
|
|
||||||
else:
|
|
||||||
ids = self.deck.findCards(query)
|
|
||||||
ads = "cards.id in %s" % ids2str(ids)
|
|
||||||
sort = ""
|
|
||||||
if isinstance(sortKey, types.StringType):
|
|
||||||
# card property
|
|
||||||
if sortKey == "fact":
|
|
||||||
sort = "order by facts.created, cards.created"
|
|
||||||
else:
|
|
||||||
sort = "order by cards." + sortKey
|
|
||||||
if sortKey in ("question", "answer"):
|
|
||||||
sort += " collate nocase"
|
|
||||||
if sortKey == "fact":
|
|
||||||
query = """
|
|
||||||
select cards.id from cards, facts
|
|
||||||
where cards.fid = facts.id """
|
|
||||||
if ads:
|
|
||||||
query += "and " + ads + " "
|
|
||||||
else:
|
|
||||||
query = "select id from cards "
|
|
||||||
if ads:
|
|
||||||
query += "where %s " % ads
|
|
||||||
query += sort
|
|
||||||
else:
|
|
||||||
# field value
|
|
||||||
ret = self.deck.db.all(
|
|
||||||
"select id, numeric from fields where name = :name",
|
|
||||||
name=sortKey[1])
|
|
||||||
fields = ",".join([str(x[0]) for x in ret])
|
|
||||||
# if multiple models have the same field, use the first numeric bool
|
|
||||||
numeric = ret[0][1]
|
|
||||||
if numeric:
|
|
||||||
order = "cast(fdata.value as real)"
|
|
||||||
else:
|
|
||||||
order = "fdata.value collate nocase"
|
|
||||||
if ads:
|
|
||||||
ads = " and " + ads
|
|
||||||
query = ("select cards.id "
|
|
||||||
"from fdata, cards where fdata.fmid in (%s) "
|
|
||||||
"and fdata.fid = cards.fid" + ads +
|
|
||||||
" order by cards.ordinal, %s") % (fields, order)
|
|
||||||
# run the query
|
|
||||||
self.cards = self.deck.db.all(query)
|
|
||||||
|
|
|
||||||
|
|
@ -99,7 +99,7 @@ create table if not exists facts (
|
||||||
mod integer not null,
|
mod integer not null,
|
||||||
tags text not null,
|
tags text not null,
|
||||||
flds text not null,
|
flds text not null,
|
||||||
sfld text not null,
|
sfld integer not null,
|
||||||
data text not null
|
data text not null
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ def test_findCards():
|
||||||
f['Front'] = u'cat'
|
f['Front'] = u'cat'
|
||||||
f['Back'] = u'sheep'
|
f['Back'] = u'sheep'
|
||||||
deck.addFact(f)
|
deck.addFact(f)
|
||||||
|
catCard = f.cards()[0]
|
||||||
f = deck.newFact()
|
f = deck.newFact()
|
||||||
f['Front'] = u'template test'
|
f['Front'] = u'template test'
|
||||||
f['Back'] = u'foo bar'
|
f['Back'] = u'foo bar'
|
||||||
|
|
@ -56,6 +57,8 @@ def test_findCards():
|
||||||
c.flush()
|
c.flush()
|
||||||
assert deck.findCards("is:due") == [c.id]
|
assert deck.findCards("is:due") == [c.id]
|
||||||
c.queue = -1
|
c.queue = -1
|
||||||
|
# ensure this card gets a later mod time
|
||||||
|
import time; time.sleep(1)
|
||||||
c.flush()
|
c.flush()
|
||||||
assert deck.findCards("is:suspended") == [c.id]
|
assert deck.findCards("is:suspended") == [c.id]
|
||||||
# fids
|
# fids
|
||||||
|
|
@ -75,3 +78,9 @@ def test_findCards():
|
||||||
assert len(deck.findCards("back:sheep")) == 2
|
assert len(deck.findCards("back:sheep")) == 2
|
||||||
assert len(deck.findCards("-back:sheep")) == 3
|
assert len(deck.findCards("-back:sheep")) == 3
|
||||||
assert len(deck.findCards("front:")) == 5
|
assert len(deck.findCards("front:")) == 5
|
||||||
|
# ordering
|
||||||
|
assert deck.findCards("front:", sort="factCrt")[-1] == c.id
|
||||||
|
assert deck.findCards("", sort="factCrt")[-1] == c.id
|
||||||
|
assert deck.findCards("", sort="factFld")[0] == catCard.id
|
||||||
|
assert deck.findCards("", sort="factFld")[-1] == c.id
|
||||||
|
assert deck.findCards("", sort="cardMod")[-1] == c.id
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue