[Erp5-report] r17167 - in /erp5/trunk/products: ERP5Catalog/tests/ ZSQLCatalog/ ZSQLCatalog...

nobody at svn.erp5.org nobody at svn.erp5.org
Wed Oct 24 15:39:29 CEST 2007


Author: jerome
Date: Wed Oct 24 15:39:29 2007
New Revision: 17167

URL: http://svn.erp5.org?rev=17167&view=rev
Log:
Allow to force the key behaviour of by passing a key= argument to a Query constructor


Modified:
    erp5/trunk/products/ERP5Catalog/tests/testERP5Catalog.py
    erp5/trunk/products/ZSQLCatalog/SQLCatalog.py
    erp5/trunk/products/ZSQLCatalog/tests/testZSQLCatalog.py

Modified: erp5/trunk/products/ERP5Catalog/tests/testERP5Catalog.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5Catalog/tests/testERP5Catalog.py?rev=17167&r1=17166&r2=17167&view=diff
==============================================================================
--- erp5/trunk/products/ERP5Catalog/tests/testERP5Catalog.py (original)
+++ erp5/trunk/products/ERP5Catalog/tests/testERP5Catalog.py Wed Oct 24 15:39:29 2007
@@ -2017,6 +2017,20 @@
     result = sql_connection.manage_test(sql % sub_obj.getUid())
     self.assertSameSet(['little_owner'], [x.owner for x in result])
 
+  def test_ExactMatchSearch(self):
+    # test exact match search with queries
+    doc = self._makeOrganisation(title='Foo%')
+    other_doc = self._makeOrganisation(title='FooBar')
+    ctool = self.getCatalogTool()
+
+    # by default, % in catalog search is a wildcard:
+    self.assertEquals(sorted([doc, other_doc]),
+      sorted([x.getObject() for x in 
+        ctool(portal_type='Organisation', title='Foo%')]))
+    # ... but you can force searches with an exact match key
+    self.assertEquals([doc], [x.getObject() for x in
+       ctool(portal_type='Organisation', title=dict(query='Foo%',
+                                                    key='ExactMatch'))])
 
 def test_suite():
   suite = unittest.TestSuite()

Modified: erp5/trunk/products/ZSQLCatalog/SQLCatalog.py
URL: http://svn.erp5.org/erp5/trunk/products/ZSQLCatalog/SQLCatalog.py?rev=17167&r1=17166&r2=17167&view=diff
==============================================================================
--- erp5/trunk/products/ZSQLCatalog/SQLCatalog.py (original)
+++ erp5/trunk/products/ZSQLCatalog/SQLCatalog.py Wed Oct 24 15:39:29 2007
@@ -180,6 +180,13 @@
     self._register()
     tid = get_ident()
     self.temporary_buffer.setdefault(tid, []).extend(iterable)
+
+
+# valid search modes for queries
+FULL_TEXT_SEARCH_MODE = 'FullText'
+EXACT_MATCH_SEARCH_MODE = 'ExactMatch'
+KEYWORD_SEARCH_MODE = 'Keyword'
+
 
 class QueryMixin:
   
@@ -289,7 +296,7 @@
   format - type date : %d/%m/%Y
            type float : 1 234.12
   """
-  def __init__(self, format=None, operator=None, range=None,
+  def __init__(self, format=None, operator=None, range=None, key=None,
                      search_mode=None, table_alias_list=None, type=None, **kw):
     self.format = format
     if operator is None:
@@ -304,6 +311,7 @@
     self.key = key_list[0]
     self.value = kw[self.key]
     self.type = type
+    self.search_key = key
 
   def __call__(self):
     self.asSQLExpression()
@@ -322,6 +330,8 @@
     return result
 
   def getSearchMode(self):
+    """Search mode used for Full Text search
+    """
     return self.search_mode
 
   def asSearchTextExpression(self):
@@ -345,7 +355,8 @@
     sql_expression = ''
     value = self.getValue()
     key = self.getKey()
-    ignore_key=0
+    search_key = self.search_key
+    ignore_key = 0
     if key_alias_dict is not None:
       # Try to find the alias
       if key not in key_alias_dict:
@@ -387,10 +398,10 @@
         where_expression.append("%s > %s" % (key, query_max))
     elif isSimpleType(value) or isinstance(value, DateTime) \
         or (isinstance(value, (list, tuple)) and self.operator.upper() != 'IN'):
-      # Convert into lists any value which contain a ;
-      # Refer to _listGlobalActions DCWorkflow patch
-      # for example of use
-      if isinstance(value, basestring):
+      # Convert into lists any value which contain 'OR'
+      # Refer to _listGlobalActions DCWorkflow patch for example of use
+      if isinstance(value, basestring) \
+                and search_key != EXACT_MATCH_SEARCH_MODE:
         value = value.split(' OR ')
         value = map(lambda x:x.strip(), value)
       value_list = value
@@ -401,7 +412,7 @@
         comparison_operator = None
         if (value != '' or not ignore_empty_string) \
                         and isinstance(value, basestring):
-          if '%' in value:
+          if '%' in value and search_key != EXACT_MATCH_SEARCH_MODE:
             comparison_operator = 'LIKE'
           elif len(value) >= 1 and value[0:2] in ('<=','!=','>='):
             comparison_operator = value[0:2]
@@ -409,11 +420,15 @@
           elif len(value) >= 1 and value[0] in ('=','>','<'):
             comparison_operator = value[0]
             value = value[1:]
-          elif key in keyword_search_keys:
+          elif search_key == KEYWORD_SEARCH_MODE or (
+                   key in keyword_search_keys and
+                    search_key != EXACT_MATCH_SEARCH_MODE):
             # We must add % in the request to simulate the catalog
             comparison_operator = 'LIKE'
             value = '%%%s%%' % value
-          elif key in full_text_search_keys:
+          elif search_key == FULL_TEXT_SEARCH_MODE or (
+                  key in full_text_search_keys
+                  and search_key != EXACT_MATCH_SEARCH_MODE):
             # We must add % in the request to simulate the catalog
             # we first check if there is a special search_mode for this key
             # incl. table name, or for all keys of that name,

Modified: erp5/trunk/products/ZSQLCatalog/tests/testZSQLCatalog.py
URL: http://svn.erp5.org/erp5/trunk/products/ZSQLCatalog/tests/testZSQLCatalog.py?rev=17167&r1=17166&r2=17167&view=diff
==============================================================================
--- erp5/trunk/products/ZSQLCatalog/tests/testZSQLCatalog.py (original)
+++ erp5/trunk/products/ZSQLCatalog/tests/testZSQLCatalog.py Wed Oct 24 15:39:29 2007
@@ -39,16 +39,13 @@
 from Products.ZSQLCatalog.SQLCatalog import ComplexQuery
 from Products.ZSQLCatalog.SQLCatalog import NegatedQuery
 
-try:
-  from transaction import get as get_transaction
-except ImportError:
-  pass
 
 class TestZSQLCatalog(unittest.TestCase):
   """Tests for ZSQL Catalog.
   """
   def setUp(self):
     self._catalog = ZSQLCatalog()
+  # TODO ?
 
 
 class TestSQLCatalog(unittest.TestCase):
@@ -100,12 +97,19 @@
 
 
 class TestQuery(unittest.TestCase):
+  """Test SQL bits generated from Queries
+  """
   def testSimpleQuery(self):
     q = Query(title='Foo')
     self.assertEquals(
           dict(where_expression="title = 'Foo'",
                select_expression_list=[]),
           q.asSQLExpression(keyword_search_keys=[], full_text_search_keys=[]))
+
+  def testQueryMultipleKeys(self):
+    # using multiple keys is invalid and raises
+    # KeyError: 'Query must have only one key'
+    self.assertRaises(KeyError, Query, title='Foo', reference='bar')
 
   def testNoneQuery(self):
     q = Query(title=None)
@@ -168,6 +172,7 @@
                select_expression_list=[]),
           q.asSQLExpression(keyword_search_keys=[], full_text_search_keys=[]))
 
+  # format
   def testDateFormat(self):
     q = Query(date=DateTime(2001, 02, 03), format='%Y/%m/%d', type='date')
     self.assertEquals(
@@ -177,6 +182,7 @@
                select_expression_list=[]),
           q.asSQLExpression(keyword_search_keys=[], full_text_search_keys=[]))
   
+  # full text
   def testSimpleQueryFullText(self):
     q = Query(title='Foo')
     self.assertEquals(dict(where_expression="MATCH title AGAINST ('Foo' )",
@@ -185,7 +191,28 @@
           q.asSQLExpression(keyword_search_keys=[],
                             full_text_search_keys=['title']))
 
-  def testSimpleQuerySearchKey(self):
+  def testSimpleQueryFullTextSearchMode(self):
+    q = Query(title='Foo',
+              search_mode='in_boolean_mode')
+    self.assertEquals(dict(
+      where_expression="MATCH title AGAINST ('Foo' IN BOOLEAN MODE)",
+      select_expression_list=
+        ["MATCH title AGAINST ('Foo' IN BOOLEAN MODE) AS title_relevance"]),
+          q.asSQLExpression(keyword_search_keys=[],
+                            full_text_search_keys=['title']))
+  
+  def testSimpleQueryFullTextStat__(self):
+    # stat__ is an internal implementation artifact to prevent adding
+    # select_expression for countFolder
+    q = Query(title='Foo')
+    self.assertEquals(dict(
+                    where_expression="MATCH title AGAINST ('Foo' )",
+                    select_expression_list=[]),
+          q.asSQLExpression(keyword_search_keys=[],
+                            full_text_search_keys=['title'],
+                            stat__=1))
+
+  def testSimpleQueryKeywordSearchKey(self):
     q = Query(title='Foo')
     self.assertEquals(dict(where_expression="title LIKE '%Foo%'",
                            select_expression_list=[]),
@@ -201,6 +228,7 @@
           q.asSQLExpression(keyword_search_keys=[],
                             full_text_search_keys=[]))
 
+  # complex queries
   def testSimpleComplexQuery(self):
     q1 = Query(title='Foo')
     q2 = Query(reference='Bar')
@@ -222,6 +250,33 @@
           select_expression_list=[]),
      q.asSQLExpression(keyword_search_keys=[],
                        full_text_search_keys=[]))
+
+  
+  # forced keys
+  def testSimpleQueryForcedKeywordSearchKey(self):
+    q = Query(title='Foo', key='Keyword')
+    self.assertEquals("title LIKE '%Foo%'",
+          q.asSQLExpression(keyword_search_keys=[],
+                            full_text_search_keys=[])['where_expression'])
+
+  def testSimpleQueryForcedFullText(self):
+    q = Query(title='Foo', key='FullText')
+    self.assertEquals("MATCH title AGAINST ('Foo' )",
+          q.asSQLExpression(keyword_search_keys=[],
+                            full_text_search_keys=[])['where_expression'])
+
+  def testSimpleQueryForcedExactMatch(self):
+    q = Query(title='Foo', key='ExactMatch')
+    self.assertEquals("title = 'Foo'",
+          q.asSQLExpression(keyword_search_keys=['title'],
+                            full_text_search_keys=[])['where_expression'])
+
+  def testSimpleQueryForcedExactMatchOR(self):
+    q = Query(title='Foo% OR %?ar', key='ExactMatch')
+    self.assertEquals("title = 'Foo% OR %?ar'",
+          q.asSQLExpression(keyword_search_keys=['title'],
+                            full_text_search_keys=[])['where_expression'])
+
 
 def test_suite():
   suite = unittest.TestSuite()




More information about the Erp5-report mailing list