1) Add 'series_sort' virtual column.

2) fixed bug causing exceptions when using zero-parameter functions at the innermost position in the value stack.
This commit is contained in:
Charles Haley 2012-03-21 15:29:57 +01:00
parent ab19edb96f
commit 86d85fd06c
6 changed files with 53 additions and 9 deletions

View File

@ -1170,6 +1170,8 @@ class TagsModel(QAbstractItemModel): # {{{
charclass = ''.join(letters_seen)
if k == 'author_sort':
expr = r'%s:"~(^[%s])|(&\s*[%s])"'%(k, charclass, charclass)
elif k == 'series':
expr = r'series_sort:"~^[%s]"'%(charclass)
else:
expr = r'%s:"~^[%s]"'%(k, charclass)
if node_searches[tag_item.tag.state] == 'true':

View File

@ -172,11 +172,14 @@ def force_to_bool(val):
class CacheRow(list): # {{{
def __init__(self, db, composites, val):
def __init__(self, db, composites, val, series_col, series_sort_col):
self.db = db
self._composites = composites
list.__init__(self, val)
self._must_do = len(composites) > 0
self._series_col = series_col
self._series_sort_col = series_sort_col
self._series_sort = None
def __getitem__(self, col):
if self._must_do:
@ -191,12 +194,19 @@ class CacheRow(list): # {{{
elif col in self._composites:
is_comp = True
if is_comp:
id = list.__getitem__(self, 0)
id_ = list.__getitem__(self, 0)
self._must_do = False
mi = self.db.get_metadata(id, index_is_id=True,
mi = self.db.get_metadata(id_, index_is_id=True,
get_user_categories=False)
for c in self._composites:
self[c] = mi.get(self._composites[c])
if col == self._series_sort_col and self._series_sort is None:
if self[self._series_col]:
self._series_sort = title_sort(self[self._series_col])
self[self._series_sort_col] = self._series_sort
else:
self._series_sort = ''
self[self._series_sort_col] = ''
return list.__getitem__(self, col)
def __getslice__(self, i, j):
@ -226,6 +236,8 @@ class ResultCache(SearchQueryParser): # {{{
for key in field_metadata:
if field_metadata[key]['datatype'] == 'composite':
self.composites[field_metadata[key]['rec_index']] = key
self.series_col = field_metadata['series']['rec_index']
self.series_sort_col = field_metadata['series_sort']['rec_index']
self._data = []
self._map = self._map_filtered = []
self.first_sort = True
@ -918,9 +930,11 @@ class ResultCache(SearchQueryParser): # {{{
for id in ids:
try:
self._data[id] = CacheRow(db, self.composites,
db.conn.get('SELECT * from meta2 WHERE id=?', (id,))[0])
db.conn.get('SELECT * from meta2 WHERE id=?', (id,))[0],
self.series_col, self.series_sort_col)
self._data[id].append(db.book_on_device_string(id))
self._data[id].append(self.marked_ids_dict.get(id, None))
self._data[id].append(None)
except IndexError:
return None
try:
@ -935,9 +949,11 @@ class ResultCache(SearchQueryParser): # {{{
self._data.extend(repeat(None, max(ids)-len(self._data)+2))
for id in ids:
self._data[id] = CacheRow(db, self.composites,
db.conn.get('SELECT * from meta2 WHERE id=?', (id,))[0])
db.conn.get('SELECT * from meta2 WHERE id=?', (id,))[0],
self.series_col, self.series_sort_col)
self._data[id].append(db.book_on_device_string(id))
self._data[id].append(self.marked_ids_dict.get(id, None))
self._data[id].append(None)
self._map[0:0] = ids
self._map_filtered[0:0] = ids
@ -962,11 +978,13 @@ class ResultCache(SearchQueryParser): # {{{
temp = db.conn.get('SELECT * FROM meta2')
self._data = list(itertools.repeat(None, temp[-1][0]+2)) if temp else []
for r in temp:
self._data[r[0]] = CacheRow(db, self.composites, r)
self._data[r[0]] = CacheRow(db, self.composites, r,
self.series_col, self.series_sort_col)
for item in self._data:
if item is not None:
item.append(db.book_on_device_string(item[0]))
item.append(None)
item.append(None)
marked_col = self.FIELD_MAP['marked']
for id_,val in self.marked_ids_dict.iteritems():

View File

@ -434,6 +434,8 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
self.field_metadata.set_field_record_index('ondevice', base, prefer_custom=False)
self.FIELD_MAP['marked'] = base = base+1
self.field_metadata.set_field_record_index('marked', base, prefer_custom=False)
self.FIELD_MAP['series_sort'] = base = base+1
self.field_metadata.set_field_record_index('series_sort', base, prefer_custom=False)
script = '''
DROP VIEW IF EXISTS meta2;

View File

@ -327,6 +327,16 @@ class FieldMetadata(dict):
'is_custom':False,
'is_category':False,
'is_csp': False}),
('series_sort', {'table':None,
'column':None,
'datatype':'text',
'is_multiple':{},
'kind':'field',
'name':_('Series Sort'),
'search_terms':['series_sort'],
'is_custom':False,
'is_category':False,
'is_csp': False}),
('sort', {'table':None,
'column':None,
'datatype':'text',

View File

@ -218,7 +218,7 @@ class _CompileParser(_Parser):
def expr(self, level):
if self.compile_text:
self.max_level = max(level, self.max_level)
self.max_level = max(level+1, self.max_level)
if self.token_is_id():
funcs = formatter_functions().get_functions()

View File

@ -12,6 +12,7 @@ import inspect, re, traceback
from calibre import human_readable
from calibre.constants import DEBUG
from calibre.ebooks.metadata import title_sort
from calibre.utils.titlecase import titlecase
from calibre.utils.icu import capitalize, strcmp, sort_key
from calibre.utils.date import parse_date, format_date, now, UNDEFINED_DATE
@ -836,6 +837,17 @@ class BuiltinOndevice(BuiltinFormatterFunction):
return _('Yes')
return ''
class BuiltinSeriesSort(BuiltinFormatterFunction):
name = 'series_sort'
arg_count = 0
category = 'Get values from metadata'
__doc__ = doc = _('booksize() -- return the series sort value')
def evaluate(self, formatter, kwargs, mi, locals):
if mi.series:
return title_sort(mi.series)
return ''
class BuiltinHasCover(BuiltinFormatterFunction):
name = 'has_cover'
arg_count = 0
@ -1149,8 +1161,8 @@ _formatter_builtins = [
BuiltinListSort(), BuiltinListUnion(), BuiltinLookup(),
BuiltinLowercase(), BuiltinMultiply(), BuiltinNot(),
BuiltinOndevice(), BuiltinOr(), BuiltinPrint(), BuiltinRawField(),
BuiltinRe(), BuiltinSelect(), BuiltinShorten(), BuiltinStrcat(),
BuiltinStrcatMax(),
BuiltinRe(), BuiltinSelect(), BuiltinSeriesSort(), BuiltinShorten(),
BuiltinStrcat(), BuiltinStrcatMax(),
BuiltinStrcmp(), BuiltinStrInList(), BuiltinStrlen(), BuiltinSubitems(),
BuiltinSublist(),BuiltinSubstr(), BuiltinSubtract(), BuiltinSwapAroundComma(),
BuiltinSwitch(), BuiltinTemplate(), BuiltinTest(), BuiltinTitlecase(),