From 98e6e34cd46aa361c8dc1a211371b89bea6a4905 Mon Sep 17 00:00:00 2001 From: Sebastien Robin <seb@nexedi.com> Date: Thu, 21 Jan 2010 15:30:20 +0000 Subject: [PATCH] * define getProperty on zsqlbrain in order to get values either on the brain or on the real object * update unit test for getProperty * add new method hasColumn in catalog API * add test for hasColumn git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@31884 20353a03-c40f-0410-a6d1-a30d3c3de9de --- product/ERP5Catalog/tests/testERP5Catalog.py | 17 ++++++++++++++--- product/ZSQLCatalog/Extensions/zsqlbrain.py | 15 +++++++++++++++ product/ZSQLCatalog/SQLCatalog.py | 3 +++ product/ZSQLCatalog/ZSQLCatalog.py | 6 ++++++ product/ZSQLCatalog/interfaces/query_catalog.py | 6 ++++++ product/ZSQLCatalog/tests/testSQLCatalog.py | 4 ++++ 6 files changed, 48 insertions(+), 3 deletions(-) diff --git a/product/ERP5Catalog/tests/testERP5Catalog.py b/product/ERP5Catalog/tests/testERP5Catalog.py index f14f8aa437..b72c8dc9bb 100644 --- a/product/ERP5Catalog/tests/testERP5Catalog.py +++ b/product/ERP5Catalog/tests/testERP5Catalog.py @@ -3932,17 +3932,28 @@ VALUES # Make sure that we are able to retrieve data directly from mysql # without retrieving real objects title="foo" - person = person_module.newContent(portal_type='Person',title=title) + description = "foobar" + person = person_module.newContent(portal_type='Person',title=title, + description=description) person_uid = person.getUid() person.immediateReindexObject() folder_object_list = person_module.searchFolder(uid=person_uid, select_dict={'title': None}) new_title = 'bar' + new_description = 'foobarfoo' person.setTitle(new_title) + person.setDescription(new_description) self.assertEquals(new_title, person.getTitle()) expected_sql_title_list = [title] - self.assertEquals([x.title for x in folder_object_list], expected_sql_title_list) + self.assertEquals([x.title for x in folder_object_list], + expected_sql_title_list) + self.assertEquals([x.getProperty('title') for x in + folder_object_list], expected_sql_title_list) + expected_sql_description_list = [new_description] + self.assertEquals([x.getProperty('description') for x in + folder_object_list], expected_sql_description_list) real_title_list = [new_title] - self.assertEquals([x.getTitle() for x in folder_object_list], real_title_list) + self.assertEquals([x.getTitle() for x in + folder_object_list], real_title_list) def test_suite(): suite = unittest.TestSuite() diff --git a/product/ZSQLCatalog/Extensions/zsqlbrain.py b/product/ZSQLCatalog/Extensions/zsqlbrain.py index 49f8a330cf..81427eed45 100644 --- a/product/ZSQLCatalog/Extensions/zsqlbrain.py +++ b/product/ZSQLCatalog/Extensions/zsqlbrain.py @@ -22,6 +22,8 @@ from AccessControl.SecurityInfo import allow_class from zLOG import LOG +_MARKER = [] + class ZSQLBrain(Acquisition.Implicit): security = ClassSecurityInfo() security.declareObjectPublic() @@ -69,6 +71,19 @@ class ZSQLBrain(Acquisition.Implicit): error=sys.exc_info() ) return None + def getProperty(self, name, d=_MARKER, **kw): + value = None + if hasattr(self, name): + value = getattr(self, name) + else: + if d is not _MARKER: + kw['d'] = d + document = self.getObject() + if document is None: + raise AttributeError(name) + value = document.getProperty(name, **kw) + return value + def absolute_url(self, relative=0): """ Default method used to return the path stored in the Catalog. diff --git a/product/ZSQLCatalog/SQLCatalog.py b/product/ZSQLCatalog/SQLCatalog.py index 6b99a185d6..d7f4918cfe 100644 --- a/product/ZSQLCatalog/SQLCatalog.py +++ b/product/ZSQLCatalog/SQLCatalog.py @@ -1868,6 +1868,9 @@ class Catalog(Folder, search_key = self.getSearchKey(key, 'RelatedKey') return search_key, related_key_definition + def hasColumn(self, column): + return self.getColumnSearchKey(column)[0] is not None + @profiler_decorator def getColumnDefaultSearchKey(self, key): """ diff --git a/product/ZSQLCatalog/ZSQLCatalog.py b/product/ZSQLCatalog/ZSQLCatalog.py index 8e0f8bcbbf..e4bf86953c 100644 --- a/product/ZSQLCatalog/ZSQLCatalog.py +++ b/product/ZSQLCatalog/ZSQLCatalog.py @@ -992,6 +992,12 @@ class ZCatalog(Folder, Persistent, Implicit): return catalog.getColumnIds() return [] + def hasColumn(self, column, sql_catalog_id=None): + catalog = self.getSQLCatalog(sql_catalog_id) + if catalog is not None: + return catalog.hasColumn(column) + return False + def getAttributesForColumn(self, column, sql_catalog_id=None): """ Return the attribute names as a single string diff --git a/product/ZSQLCatalog/interfaces/query_catalog.py b/product/ZSQLCatalog/interfaces/query_catalog.py index a2de4ab94f..7a4f04db53 100644 --- a/product/ZSQLCatalog/interfaces/query_catalog.py +++ b/product/ZSQLCatalog/interfaces/query_catalog.py @@ -174,6 +174,12 @@ class ISearchKeyCatalog(Interface): There is one comparison operator instance per possible string value. """ + def hasColumn(column): + """ + Check if the given column or virtual column (in case + of related keys) exists or not + """ + # TODO: add support for other operators (logical, ensemblist (?)) def searchResults(REQUEST=None, **kw): diff --git a/product/ZSQLCatalog/tests/testSQLCatalog.py b/product/ZSQLCatalog/tests/testSQLCatalog.py index b92136d190..ce099a5217 100644 --- a/product/ZSQLCatalog/tests/testSQLCatalog.py +++ b/product/ZSQLCatalog/tests/testSQLCatalog.py @@ -534,6 +534,10 @@ class TestSQLCatalog(unittest.TestCase): self.assertTrue('ambiguous_mapping' in select_dict, select_dict) self.assertTrue('bar' in select_dict['ambiguous_mapping'], select_dict['ambiguous_mapping']) + def test_hasColumn(self): + self.assertTrue(self._catalog.hasColumn('uid')) + self.assertFalse(self._catalog.hasColumn('foobar')) + ##return catalog(title=Query(title='a', operator='not')) #return catalog(title={'query': 'a', 'operator': 'not'}) #return catalog(title={'query': ['a', 'b'], 'operator': 'not'}) -- 2.30.9