[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