tweak find code

This commit is contained in:
Damien Elmes 2011-11-28 20:04:14 +09:00
parent d903b50d5f
commit 67e4f0d1cc
3 changed files with 30 additions and 36 deletions

View file

@ -283,6 +283,11 @@ usn=?,mod=? where id in %s""" % ids2str(cids),
g = self.get(self.col.conf['topDeck']) g = self.get(self.col.conf['topDeck'])
return g return g
def topIds(self):
"All dids from top level."
t = self.top()
return [t['id']] + [a[1] for a in self.children(t['id'])]
def active(self): def active(self):
"The currrently active dids." "The currrently active dids."
return self.col.conf['activeDecks'] return self.col.conf['activeDecks']

View file

@ -5,7 +5,6 @@
import re import re
from anki.utils import ids2str, splitFields, joinFields, stripHTML, intTime from anki.utils import ids2str, splitFields, joinFields, stripHTML, intTime
SEARCH_TAG = 0 SEARCH_TAG = 0
SEARCH_TYPE = 1 SEARCH_TYPE = 1
SEARCH_PHRASE = 2 SEARCH_PHRASE = 2
@ -46,40 +45,34 @@ class Finder(object):
if not self.lims['valid']: if not self.lims['valid']:
return [] return []
(q, args) = self._whereClause() (q, args) = self._whereClause()
query = self._orderedSelect(q) order = self._order()
query = """\
select c.id from cards c, notes n where %s
and c.nid=n.id %s""" % (q, order)
res = self.col.db.list(query, **args) res = self.col.db.list(query, **args)
if self.col.conf['sortBackwards']: if self.col.conf['sortBackwards']:
res.reverse() res.reverse()
return res return res
def _whereClause(self): def _whereClause(self):
x = [] q = " and ".join(self.lims['preds'])
if self.lims['note']:
x.append("nid in (select id from notes where %s)" % " and ".join(
self.lims['note']))
if self.lims['card']:
x.extend(self.lims['card'])
q = " and ".join(x)
if not q: if not q:
q = "1" q = "1"
return q, self.lims['args'] return q, self.lims['args']
def _orderedSelect(self, lim): def _order(self):
type = self.col.conf['sortType'] type = self.col.conf['sortType']
if not type: if not type:
return "select id from cards c where " + lim return
elif type.startswith("note"): if type.startswith("note"):
if type == "noteCrt": if type == "noteCrt":
sort = "f.id, c.ord" sort = "n.id, c.ord"
elif type == "noteMod": elif type == "noteMod":
sort = "f.mod, c.ord" sort = "n.mod, c.ord"
elif type == "noteFld": elif type == "noteFld":
sort = "f.sfld collate nocase, c.ord" sort = "n.sfld collate nocase, c.ord"
else: else:
raise Exception() raise Exception()
return """
select c.id from cards c, notes f where %s and c.nid=f.id
order by %s""" % (lim, sort)
elif type.startswith("card"): elif type.startswith("card"):
if type == "cardMod": if type == "cardMod":
sort = "c.mod" sort = "c.mod"
@ -95,16 +88,12 @@ order by %s""" % (lim, sort)
sort = "c.ivl" sort = "c.ivl"
else: else:
raise Exception() raise Exception()
return "select c.id from cards c where %s order by %s" % ( return " order by " + sort
lim, sort)
else:
raise Exception()
def _findLimits(self): def _findLimits(self):
"Generate a list of note/card limits for the query." "Generate a list of note/card limits for the query."
self.lims = { self.lims = {
'note': [], 'preds': [],
'card': [],
'args': {}, 'args': {},
'valid': True 'valid': True
} }
@ -128,7 +117,7 @@ order by %s""" % (lim, sort)
def _findTag(self, val, neg, c): def _findTag(self, val, neg, c):
if val == "none": if val == "none":
self.lims['note'].append("select id from notes where tags = ''") self.lims['preds'].append("select id from notes where tags = ''")
return return
extra = "not" if neg else "" extra = "not" if neg else ""
val = val.replace("*", "%") val = val.replace("*", "%")
@ -137,7 +126,7 @@ order by %s""" % (lim, sort)
if not val.endswith("%"): if not val.endswith("%"):
val += " %" val += " %"
self.lims['args']["_tag_%d" % c] = val self.lims['args']["_tag_%d" % c] = val
self.lims['note'].append( self.lims['preds'].append(
"tags %s like :_tag_%d""" % (extra, c)) "tags %s like :_tag_%d""" % (extra, c))
def _findCardState(self, val, neg): def _findCardState(self, val, neg):
@ -159,7 +148,7 @@ order by %s""" % (lim, sort)
if neg: if neg:
cond = "not (%s)" % cond cond = "not (%s)" % cond
if cond: if cond:
self.lims['card'].append(cond) self.lims['preds'].append(cond)
else: else:
self.lims['valid'] = False self.lims['valid'] = False
@ -168,7 +157,7 @@ order by %s""" % (lim, sort)
extra = "not" if neg else "" extra = "not" if neg else ""
if not self.full: if not self.full:
self.lims['args']["_text_%d"%c] = "%"+val+"%" self.lims['args']["_text_%d"%c] = "%"+val+"%"
self.lims['note'].append("flds %s like :_text_%d escape '\\'" % ( self.lims['preds'].append("flds %s like :_text_%d escape '\\'" % (
extra, c)) extra, c))
else: else:
# in the future we may want to apply this at the end to speed up # in the future we may want to apply this at the end to speed up
@ -178,10 +167,10 @@ order by %s""" % (lim, sort)
"select id, flds from notes"): "select id, flds from notes"):
if val in stripHTML(flds): if val in stripHTML(flds):
nids.append(nid) nids.append(nid)
self.lims['note'].append("id in " + ids2str(nids)) self.lims['preds'].append("n.id in " + ids2str(nids))
def _findNids(self, val): def _findNids(self, val):
self.lims['note'].append("id in (%s)" % val) self.lims['preds'].append("n.id in (%s)" % val)
def _findModel(self, val, isNeg): def _findModel(self, val, isNeg):
extra = "not" if isNeg else "" extra = "not" if isNeg else ""
@ -189,12 +178,12 @@ order by %s""" % (lim, sort)
for m in self.col.models.all(): for m in self.col.models.all():
if m['name'].lower() == val: if m['name'].lower() == val:
ids.append(m['id']) ids.append(m['id'])
self.lims['note'].append("mid %s in %s" % (extra, ids2str(ids))) self.lims['preds'].append("mid %s in %s" % (extra, ids2str(ids)))
def _findDeck(self, val, isNeg): def _findDeck(self, val, isNeg):
extra = "!" if isNeg else "" extra = "!" if isNeg else ""
id = self.col.decks.id(val, create=False) or 0 id = self.col.decks.id(val, create=False) or 0
self.lims['card'].append("c.did %s= %s" % (extra, id)) self.lims['preds'].append("c.did %s= %s" % (extra, id))
def _findTemplate(self, val, isNeg): def _findTemplate(self, val, isNeg):
lims = [] lims = []
@ -209,7 +198,7 @@ order by %s""" % (lim, sort)
for t in m['tmpls']: for t in m['tmpls']:
# ordinal number? # ordinal number?
if num is not None and t['ord'] == num: if num is not None and t['ord'] == num:
self.lims['card'].append("ord %s %d" % (comp, num)) self.lims['preds'].append("ord %s %d" % (comp, num))
found = True found = True
# template name? # template name?
elif t['name'].lower() == val.lower(): elif t['name'].lower() == val.lower():
@ -218,7 +207,7 @@ order by %s""" % (lim, sort)
"and ord %s %d)") % (m['id'], comp, t['ord'])) "and ord %s %d)") % (m['id'], comp, t['ord']))
found = True found = True
if lims: if lims:
self.lims['card'].append("(" + " or ".join(lims) + ")") self.lims['preds'].append("(" + " or ".join(lims) + ")")
self.lims['valid'] = found self.lims['valid'] = found
def _findField(self, token, isNeg): def _findField(self, token, isNeg):
@ -252,7 +241,7 @@ where mid in %s and flds like ? escape '\\'""" % (
if re.search(regex, strg): if re.search(regex, strg):
nids.append(id) nids.append(id)
extra = "not" if isNeg else "" extra = "not" if isNeg else ""
self.lims['note'].append("id %s in %s" % (extra, ids2str(nids))) self.lims['preds'].append("n.id %s in %s" % (extra, ids2str(nids)))
# Most of this function was written by Marcus # Most of this function was written by Marcus
def _parseQuery(self): def _parseQuery(self):

View file

@ -3,7 +3,7 @@
# 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
import os, shutil, re, urllib, urllib2, time, unicodedata, \ import os, shutil, re, urllib, urllib2, time, unicodedata, \
urllib, sys, shutil, simplejson, zipfile urllib, sys, simplejson, zipfile
from cStringIO import StringIO from cStringIO import StringIO
from anki.utils import checksum, intTime, namedtmp, isWin from anki.utils import checksum, intTime, namedtmp, isWin
from anki.lang import _ from anki.lang import _