API to mark a set of ids and search on the set or a subset

This commit is contained in:
Kovid Goyal 2011-03-08 11:48:27 -07:00
commit 201f0b1a17
3 changed files with 54 additions and 1 deletions

View File

@ -7,7 +7,7 @@ __copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>'
__docformat__ = 'restructuredtext en' __docformat__ = 'restructuredtext en'
import re, itertools, time, traceback import re, itertools, time, traceback
from itertools import repeat from itertools import repeat, izip
from datetime import timedelta from datetime import timedelta
from threading import Thread from threading import Thread
@ -194,6 +194,7 @@ class ResultCache(SearchQueryParser): # {{{
self.first_sort = True self.first_sort = True
self.search_restriction = '' self.search_restriction = ''
self.search_restriction_book_count = 0 self.search_restriction_book_count = 0
self.marked_ids_dict = {}
self.field_metadata = field_metadata self.field_metadata = field_metadata
self.all_search_locations = field_metadata.get_search_terms() self.all_search_locations = field_metadata.get_search_terms()
SearchQueryParser.__init__(self, self.all_search_locations, optimize=True) SearchQueryParser.__init__(self, self.all_search_locations, optimize=True)
@ -775,6 +776,34 @@ class ResultCache(SearchQueryParser): # {{{
def get_search_restriction_book_count(self): def get_search_restriction_book_count(self):
return self.search_restriction_book_count return self.search_restriction_book_count
def set_marked_ids(self, id_dict):
'''
ids in id_dict are "marked". They can be searched for by
using the search term ``marked:true``
:param id_dict: Either a dictionary mapping ids to values or a sequence
of ids. In the latter case, the value is set to 'true' for all ids. If
a mapping is provided, then the search can be used to search for
particular values: ``marked:value``
'''
if not hasattr(id_dict, 'items'):
# Simple list. Make it a dict of string 'true'
self.marked_ids_dict = dict(izip(id_dict, repeat(u'true',
len(id_dict))))
else:
self.marked_ids_dict = dict(**id_dict)
# Ensure that all the items in the dict are text
for id_,val in self.marked_ids_dict.iteritems():
self.marked_ids_dict[id_] = unicode(val)
# Set the values in the cache
marked_col = self.FIELD_MAP['marked']
for id_,val in self.marked_ids_dict.iteritems():
try:
self._data[id_][marked_col] = val
except:
pass
# }}} # }}}
def remove(self, id): def remove(self, id):
@ -824,6 +853,7 @@ class ResultCache(SearchQueryParser): # {{{
self._data[id] = CacheRow(db, self.composites, 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._data[id].append(db.book_on_device_string(id)) self._data[id].append(db.book_on_device_string(id))
self._data[id].append(self.marked_ids_dict.get(id, None))
except IndexError: except IndexError:
return None return None
try: try:
@ -840,6 +870,7 @@ class ResultCache(SearchQueryParser): # {{{
self._data[id] = CacheRow(db, self.composites, 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._data[id].append(db.book_on_device_string(id)) self._data[id].append(db.book_on_device_string(id))
self._data[id].append(self.marked_ids_dict.get(id, None))
self._map[0:0] = ids self._map[0:0] = ids
self._map_filtered[0:0] = ids self._map_filtered[0:0] = ids
@ -864,6 +895,15 @@ class ResultCache(SearchQueryParser): # {{{
for item in self._data: for item in self._data:
if item is not None: if item is not None:
item.append(db.book_on_device_string(item[0])) item.append(db.book_on_device_string(item[0]))
item.append(None)
marked_col = self.FIELD_MAP['marked']
for id_,val in self.marked_ids_dict.iteritems():
try:
self._data[id_][marked_col] = val
except:
pass
self._map = [i[0] for i in self._data if i is not None] self._map = [i[0] for i in self._data if i is not None]
if field is not None: if field is not None:
self.sort(field, ascending) self.sort(field, ascending)

View File

@ -374,6 +374,8 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
self.FIELD_MAP['ondevice'] = base = base+1 self.FIELD_MAP['ondevice'] = base = base+1
self.field_metadata.set_field_record_index('ondevice', base, prefer_custom=False) 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)
script = ''' script = '''
DROP VIEW IF EXISTS meta2; DROP VIEW IF EXISTS meta2;
@ -421,6 +423,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
self.row = self.data.row self.row = self.data.row
self.has_id = self.data.has_id self.has_id = self.data.has_id
self.count = self.data.count self.count = self.data.count
self.set_marked_ids = self.data.set_marked_ids
for prop in ( for prop in (
'author_sort', 'authors', 'comment', 'comments', 'author_sort', 'authors', 'comment', 'comments',

View File

@ -273,6 +273,16 @@ class FieldMetadata(dict):
'is_custom':False, 'is_custom':False,
'is_category':False, 'is_category':False,
'is_csp': False}), 'is_csp': False}),
('marked', {'table':None,
'column':None,
'datatype':'text',
'is_multiple':None,
'kind':'field',
'name': None,
'search_terms':['marked'],
'is_custom':False,
'is_category':False,
'is_csp': False}),
('series_index',{'table':None, ('series_index',{'table':None,
'column':None, 'column':None,
'datatype':'float', 'datatype':'float',