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