diff --git a/src/calibre/library/database2.py b/src/calibre/library/database2.py index 0f3a1a72fa..8fef5d36bc 100644 --- a/src/calibre/library/database2.py +++ b/src/calibre/library/database2.py @@ -257,11 +257,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns): 'flags', 'uuid', 'has_cover', - '''(SELECT sortconcat(bl.id, authors.name || ':::' || REPLACE(authors.sort, ',','|')) - FROM authors, books_authors_link as bl - WHERE bl.book=books.id and authors.id=bl.author - ORDER BY bl.id) au_map''', - '(SELECT group_concat(format) FROM data WHERE book=books.id) formats' + ('au_map', 'authors', 'author', 'aum_sortconcat(link.id, authors.name, authors.sort)') ] lines = [] for col in columns: @@ -278,10 +274,9 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns): self.FIELD_MAP = {'id':0, 'title':1, 'authors':2, 'timestamp':3, 'size':4, 'rating':5, 'tags':6, 'comments':7, 'series':8, - 'publisher':9, 'series_index':10, - 'sort':11, 'author_sort':12, 'formats':13, 'isbn':14, 'path':15, - 'lccn':16, 'pubdate':17, 'flags':18, 'uuid':19, 'cover':20, - 'au_map':21, 'formats':22} + 'publisher':9, 'series_index':10, 'sort':11, 'author_sort':12, + 'formats':13, 'isbn':14, 'path':15, 'lccn':16, 'pubdate':17, + 'flags':18, 'uuid':19, 'cover':20, 'au_map':21} for k,v in self.FIELD_MAP.iteritems(): self.field_metadata.set_field_record_index(k, v, prefer_custom=False) @@ -710,7 +705,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns): self.data.set(idx, fm['all_metadata'], mi, row_is_id = index_is_id) aut_list = row[fm['au_map']] - aut_list = [p.split(':::') for p in aut_list.split(',')] + aut_list = [p.split(':::') for p in aut_list.split(':#:')] aum = [] aus = {} for (author, author_sort) in aut_list: diff --git a/src/calibre/library/sqlite.py b/src/calibre/library/sqlite.py index 0458ada27b..75856dd0f6 100644 --- a/src/calibre/library/sqlite.py +++ b/src/calibre/library/sqlite.py @@ -87,6 +87,23 @@ class SortedConcatenate(object): class SafeSortedConcatenate(SortedConcatenate): sep = '|' +class AumSortedConcatenate(object): + '''String concatenation aggregator for the author sort map''' + def __init__(self): + self.ans = {} + + def step(self, ndx, author, sort): + if author is not None: + self.ans[ndx] = author + ':::' + sort + + def finalize(self): + keys = self.ans.keys() + if len(keys) == 0: + return None + if len(keys) == 1: + return self.ans[keys[0]] + return ':#:'.join([self.ans[v] for v in sorted(keys)]) + class Connection(sqlite.Connection): def get(self, *args, **kw): @@ -155,6 +172,7 @@ class DBThread(Thread): c_ext_loaded = load_c_extensions(self.conn) self.conn.row_factory = sqlite.Row if self.row_factory else lambda cursor, row : list(row) self.conn.create_aggregate('concat', 1, Concatenate) + self.conn.create_aggregate('aum_sortconcat', 3, AumSortedConcatenate) if not c_ext_loaded: self.conn.create_aggregate('sortconcat', 2, SortedConcatenate) self.conn.create_aggregate('sort_concat', 2, SafeSortedConcatenate)