New multiple-notebook search query was way too slow. Now fixed.
- make model.Notebook.sql_search_notes() search either with user_id or an anonymous user_id, not both - update controller.Notebooks.search(), so if the anonymous user has access to the given notebook, then run the search as the anonymous user instead of the given user id - update unit tests - don't search trash/deleted notebooks
This commit is contained in:
parent
46b767ec27
commit
ae5c911c1c
3
NEWS
3
NEWS
|
@ -1,3 +1,6 @@
|
|||
1.3.34: May 19, 2008
|
||||
* Improved performance of searching multiple notebooks.
|
||||
|
||||
1.3.33: May 19, 2008
|
||||
* Searching now displays results from multiple notebooks and not just the
|
||||
current notebook.
|
||||
|
|
|
@ -920,9 +920,11 @@ class Notebooks( object ):
|
|||
if not self.__users.check_access( user_id, notebook_id ):
|
||||
raise Access_error()
|
||||
|
||||
anonymous = self.__database.select_one( User, User.sql_load_by_username( u"anonymous" ), use_cache = True )
|
||||
if not anonymous:
|
||||
raise Access_error()
|
||||
# if the anonymous user has access to the given notebook, then run the search as the anonymous
|
||||
# user instead of the given user id
|
||||
if self.__users.check_access( user_id = None, notebook_id = notebook_id ) is True:
|
||||
anonymous = self.__database.select_one( User, User.sql_load_by_username( u"anonymous" ), use_cache = True )
|
||||
user_id = anonymous.object_id
|
||||
|
||||
MAX_SEARCH_TEXT_LENGTH = 256
|
||||
if len( search_text ) > MAX_SEARCH_TEXT_LENGTH:
|
||||
|
@ -931,7 +933,7 @@ class Notebooks( object ):
|
|||
if len( search_text ) == 0:
|
||||
raise Validation_error( u"search_text", None, unicode, message = u"is missing" )
|
||||
|
||||
notes = self.__database.select_many( Note, Notebook.sql_search_notes( user_id, anonymous.object_id, notebook_id, search_text ) )
|
||||
notes = self.__database.select_many( Note, Notebook.sql_search_notes( user_id, notebook_id, search_text ) )
|
||||
|
||||
return dict(
|
||||
notes = notes,
|
||||
|
|
|
@ -276,15 +276,23 @@ class Test_controller( object ):
|
|||
Notebook.sql_load_note_by_title = lambda self, title: \
|
||||
lambda database: sql_load_note_by_title( self, title, database )
|
||||
|
||||
def sql_search_notes( user_id, anonymous_user_id, first_notebook_id, search_text, database ):
|
||||
def sql_search_notes( user_id, first_notebook_id, search_text, database ):
|
||||
first_notes = []
|
||||
other_notes = []
|
||||
search_text = search_text.lower()
|
||||
|
||||
for ( object_id, obj_list ) in database.objects.items():
|
||||
obj = obj_list[ -1 ]
|
||||
if isinstance( obj, Note ) and ( database.user_notebook.get( user_id ) or \
|
||||
( database.user_notebook.get( anonymous_user_id ) and note.notebook_id == first_notebook_id ) ) and \
|
||||
|
||||
if not isinstance( obj, Note ):
|
||||
continue
|
||||
|
||||
if user_id in database.user_notebook:
|
||||
for notebook_info in database.user_notebook[ user_id ]:
|
||||
if notebook_info[ 0 ] != obj.notebook_id:
|
||||
continue
|
||||
|
||||
if obj.deleted_from_id == None and \
|
||||
search_text in obj.contents.lower():
|
||||
if obj.notebook_id == first_notebook_id:
|
||||
first_notes.append( obj )
|
||||
|
@ -293,8 +301,8 @@ class Test_controller( object ):
|
|||
|
||||
return first_notes + other_notes
|
||||
|
||||
Notebook.sql_search_notes = staticmethod( lambda user_id, anonymous_user_id, first_notebook_id, search_text: \
|
||||
lambda database: sql_search_notes( user_id, anonymous_user_id, first_notebook_id, search_text, database ) )
|
||||
Notebook.sql_search_notes = staticmethod( lambda user_id, first_notebook_id, search_text: \
|
||||
lambda database: sql_search_notes( user_id, first_notebook_id, search_text, database ) )
|
||||
|
||||
def sql_highest_note_rank( self, database ):
|
||||
max_rank = -1
|
||||
|
|
|
@ -167,7 +167,7 @@ class Notebook( Persistent ):
|
|||
return "select id, revision, title, contents, notebook_id, startup, deleted_from_id, rank, user_id from note_current where notebook_id = %s and title = %s;" % ( quote( self.object_id ), quote( title ) )
|
||||
|
||||
@staticmethod
|
||||
def sql_search_notes( user_id, anonymous_user_id, first_notebook_id, search_text ):
|
||||
def sql_search_notes( user_id, first_notebook_id, search_text ):
|
||||
"""
|
||||
Return a SQL string to perform a full-text search for notes within notebooks readable by the
|
||||
given user whose contents contain the given search_text. This is a case-insensitive search.
|
||||
|
@ -192,12 +192,12 @@ class Notebook( Persistent ):
|
|||
from
|
||||
note_current, user_notebook, to_tsquery( 'default', %s ) query
|
||||
where
|
||||
note_current.notebook_id = user_notebook.notebook_id and ( user_notebook.user_id = %s or
|
||||
( user_notebook.user_id = %s and note_current.notebook_id = %s ) ) and
|
||||
note_current.notebook_id = user_notebook.notebook_id and user_notebook.user_id = %s and
|
||||
note_current.deleted_from_id is null and
|
||||
query @@ search order by note_current.notebook_id = %s desc, rank desc limit 20
|
||||
) as sub;
|
||||
""" % ( quote( search_text ), quote( user_id ), quote( anonymous_user_id ),
|
||||
quote( first_notebook_id ), quote( first_notebook_id ) )
|
||||
""" % ( quote( search_text ), quote( user_id ),
|
||||
quote( first_notebook_id ) )
|
||||
|
||||
def sql_highest_note_rank( self ):
|
||||
"""
|
||||
|
|
Reference in New Issue
Block a user