Package Camelot :: Package camelot :: Package view :: Module search
[frames] | no frames]

Source Code for Module Camelot.camelot.view.search

  1  #  ============================================================================ 
  2  # 
  3  #  Copyright (C) 2007-2008 Conceptive Engineering bvba. All rights reserved. 
  4  #  www.conceptive.be / project-camelot@conceptive.be 
  5  # 
  6  #  This file is part of the Camelot Library. 
  7  # 
  8  #  This file may be used under the terms of the GNU General Public 
  9  #  License version 2.0 as published by the Free Software Foundation 
 10  #  and appearing in the file LICENSE.GPL included in the packaging of 
 11  #  this file.  Please review the following information to ensure GNU 
 12  #  General Public Licensing requirements will be met: 
 13  #  http://www.trolltech.com/products/qt/opensource.html 
 14  # 
 15  #  If you are unsure which license is appropriate for your use, please 
 16  #  review the following information: 
 17  #  http://www.trolltech.com/products/qt/licensing.html or contact 
 18  #  project-camelot@conceptive.be. 
 19  # 
 20  #  This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 
 21  #  WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 
 22  # 
 23  #  For use of this library in commercial applications, please contact 
 24  #  project-camelot@conceptive.be 
 25  # 
 26  #  ============================================================================ 
 27   
 28  """ 
 29  Helper functions to search through a collection of entities 
 30  """ 
 31  import logging 
 32   
 33  logger = logging.getLogger('camelot.view.search') 
 34   
 35  import sqlalchemy.types 
 36  from sqlalchemy.sql import operators 
 37   
 38  import camelot.types 
 39   
40 -def create_entity_search_query_decorator(admin, text):
41 """create a query decorator to search through a collection of entities 42 @param admin: the admin interface of the entity 43 @param text: the text to search for 44 @return: a function that can be applied to a query to make the query filter 45 only the objects related to the requested text or None if no such decorator 46 could be build 47 """ 48 from elixir import entities 49 from sqlalchemy import orm, sql 50 from camelot.view import utils 51 52 if len(text.strip()): 53 from sqlalchemy import Unicode, or_ 54 # arguments for the where clause 55 args = [] 56 # join conditions : list of join entities 57 joins = [] 58 search_tables = [admin.entity.table] 59 for entity in entities: 60 if issubclass(admin.entity, entity): 61 search_tables.append(entity.table) 62 63 def append_column(c): 64 if issubclass(c.type.__class__, camelot.types.Color): 65 pass 66 elif issubclass(c.type.__class__, camelot.types.File): 67 pass 68 elif issubclass(c.type.__class__, camelot.types.Code): 69 codes = text.split(c.type.separator) 70 args.append(c.like(['%'] + codes + ['%'])) 71 args.append(c.like(['%'] + codes)) 72 args.append(c.like(codes + ['%'])) 73 elif issubclass(c.type.__class__, camelot.types.VirtualAddress): 74 args.append(c.like(('%','%'+text+'%'))) 75 elif issubclass(c.type.__class__, camelot.types.Image): 76 pass 77 elif issubclass(c.type.__class__, sqlalchemy.types.Integer): 78 try: 79 args.append(c==utils.int_from_string(text)) 80 except Exception, utils.ParsingError: 81 pass 82 elif issubclass(c.type.__class__, sqlalchemy.types.Date): 83 try: 84 args.append(c==utils.date_from_string(text)) 85 except Exception, utils.ParsingError: 86 pass 87 elif issubclass(c.type.__class__, sqlalchemy.types.Float): 88 try: 89 float_value = utils.float_from_string(text) 90 precision = c.type.precision 91 if isinstance(precision, (tuple)): 92 precision = precision[1] 93 delta = 0.1**precision 94 args.append(sql.and_(c>=float_value-delta, c<=float_value+delta)) 95 except Exception, utils.ParsingError: 96 pass 97 elif issubclass(c.type.__class__, (Unicode, )) or \ 98 (hasattr(c.type, 'impl') and \ 99 issubclass(c.type.impl.__class__, (Unicode, ))): 100 logger.debug('look in column : %s'%c.name) 101 args.append(operators.ilike_op(c, '%'+text+'%'))
102 103 for table in search_tables: 104 for c in table._columns: 105 append_column(c) 106 107 for column_name in admin.list_search: 108 path = column_name.split('.') 109 target = admin.entity 110 for p in path: 111 mapper = orm.class_mapper(target) 112 property = mapper.get_property(p, resolve_synonyms=True) 113 if isinstance(property, orm.properties.PropertyLoader): 114 joins.append(getattr(target, p)) 115 target = property._get_target().class_ 116 else: 117 append_column(property.columns[0]) 118 #args.append(property.columns[0].like('%'+text+'%')) 119 120 def create_query_decorator(joins, args): 121 122 def query_decorator(q): 123 for join in joins: 124 q = q.join(join) 125 if len(args): 126 if len(args)>1: 127 q = q.filter(or_(*args)) 128 else: 129 q = q.filter(args[0]) 130 return q 131 132 return query_decorator 133 134 return create_query_decorator(joins, args) 135