[glom/boostpythonretry: 2/6] More compiling



commit d2d3b8f7ef8210dd31e49f234ebf14a9a0381752
Author: Murray Cumming <murrayc murrayc com>
Date:   Tue Feb 2 15:29:00 2010 +0100

    More compiling

 Makefile_glom.am                                   |    2 +-
 Makefile_libglom.am                                |    2 +-
 configure.ac                                       |    4 +-
 glom/libglom/python_embed/py_glom_record.cc        |   97 +++++------------
 glom/libglom/python_embed/py_glom_record.h         |   11 +-
 glom/libglom/python_embed/py_glom_related.cc       |  113 +++++++-------------
 glom/libglom/python_embed/py_glom_related.h        |    8 +-
 glom/libglom/python_embed/py_glom_relatedrecord.cc |   82 ++++----------
 glom/libglom/python_embed/py_glom_relatedrecord.h  |   14 +--
 glom/python_embed/glom_python.cc                   |   61 +++++------
 10 files changed, 132 insertions(+), 262 deletions(-)
---
diff --git a/Makefile_glom.am b/Makefile_glom.am
index fcb4fe3..aea4a43 100644
--- a/Makefile_glom.am
+++ b/Makefile_glom.am
@@ -351,7 +351,7 @@ endif
 
 glom_glom_LDADD = $(win_resfile) \
 	glom/libglom/libglom-$(GLOM_ABI_VERSION).la \
-	$(GLOM_LIBS) $(PYTHON_LIBS) $(INTLLIBS)
+	$(GLOM_LIBS) $(PYTHON_LIBS) $(BOOST_PYTHON_LIBS) $(INTLLIBS)
 if !GLOM_ENABLE_MAEMO
 glom_glom_LDADD += -lgettextpo
 endif
diff --git a/Makefile_libglom.am b/Makefile_libglom.am
index 6492249..a8aa118 100644
--- a/Makefile_libglom.am
+++ b/Makefile_libglom.am
@@ -167,7 +167,7 @@ glom_libglom_libglom_1_14_la_SOURCES +=				\
 	glom/libglom/connectionpool_backends/sqlite.cc		\
 	glom/libglom/connectionpool_backends/sqlite.h
 
-glom_libglom_libglom_1_14_la_LIBADD = $(LIBGLOM_LIBS) $(PYTHON_LIBS)
+glom_libglom_libglom_1_14_la_LIBADD = $(LIBGLOM_LIBS) $(PYTHON_LIBS) $(BOOST_PYTHON_LIBS)
 if HOST_WIN32
 glom_libglom_libglom_1_14_la_LIBADD += -lws2_32
 endif
diff --git a/configure.ac b/configure.ac
index bdbe58f..1c86f98 100644
--- a/configure.ac
+++ b/configure.ac
@@ -200,9 +200,9 @@ AC_CHECK_FUNCS([strptime])
 # For instance: PYTHON=python2.5
 MM_CHECK_MODULE_PYTHON
 
-BOOST_PYTHON_LIBS="-lboost_python-gcc43-mt-1_39"
+BOOST_PYTHON_LIBS="-lboost_python"
 #BOOST_PYTHON_LIBS="-lboost_python-mt-py25.so.1.39"
-BOOST_PYTHON_CFLAGS="-I/opt/gnome228/include/boost-1_39"
+BOOST_PYTHON_CFLAGS="-I/opt/gnome228/include/boost"
 AC_SUBST([BOOST_PYTHON_LIBS])
 AC_SUBST([BOOST_PYTHON_CFLAGS])
 
diff --git a/glom/libglom/python_embed/py_glom_record.cc b/glom/libglom/python_embed/py_glom_record.cc
index 6a4e0cb..f329516 100644
--- a/glom/libglom/python_embed/py_glom_record.cc
+++ b/glom/libglom/python_embed/py_glom_record.cc
@@ -36,77 +36,37 @@ namespace Glom
 
 //Set the object's member data, from the parameters supplied when creating the object:
 PyGlomRecord::PyGlomRecord()
+: m_document(0)
 {
-  PyGlomRecord *self_record = this;
-
-  //static char *kwlist[] = {"test", 0};
-
-  //if(!PyArg_ParseTupleAndKeywords(args, kwds, "|i", kwlist,
-   //                                 &self->m_test))
-   // return -1;
-
-  if(self_record)
-  {
-    self_record->m_related = 0;
-    self_record->m_pMap_field_values = new PyGlomRecord::type_map_field_values();
-  }
 }
 
 PyGlomRecord::~PyGlomRecord()
 {
-  PyGlomRecord *self_record = this;
-
-  if(self_record->m_pMap_field_values)
-  {
-    delete self_record->m_pMap_field_values;
-    self_record->m_pMap_field_values = 0;
-  }
-
-  if(self_record->m_table_name)
-  {
-    delete self_record->m_table_name;
-    self_record->m_table_name = 0;
-  }
-
-  if(self_record->m_connection)
-  {
-    delete self_record->m_connection;
-    self_record->m_connection = 0;
-  }
 }
 
 boost::python::object PyGlomRecord::get_connection()
 {
-  PyGlomRecord *self_record = this;
-
-  if( !self_record->m_connection || !(*(self_record->m_connection)) )
+  boost::python::object result;
+  
+  if(m_connection)
   {
-    PyObject* cobject = Py_None;
-
-    //TODO: Is there some way to take the extra reference with boost::python, withour using borrowed()?
-    Py_INCREF(cobject);
-    return boost::python::object( boost::python::borrowed(cobject) );
-  }
-  else
-  {
-    PyObject* cobject = pygobject_new( G_OBJECT( (*(self_record->m_connection))->gobj()) ); //Creates a pygda Connection object.
-    return boost::python::object( boost::python::borrowed(cobject) );
+    PyObject* cobject = pygobject_new( G_OBJECT(m_connection->gobj()) ); //Creates a pygda Connection object.
+    result = boost::python::object( boost::python::borrowed(cobject) );
   }
+  
+  return result;
 }
 
-/*
 boost::python::object PyGlomRecord::get_related()
 {
-  PyGlomRecord *self_record = this;
-
   //We initialize it here, so that this work never happens if it's not needed:
-  if(!(self_record->m_related))
+  if(!m_related)
   {
     //Return a new RelatedRecord:
-    self_record->m_related = new PyGlomRelated();
+    m_related =  boost::python::object(new PyGlomRelated()); //TODO_NotSure
 
     //Fill it:
-    Document::type_vec_relationships vecRelationships = self_record->m_document->get_relationships(*(self_record->m_table_name));
+    Document::type_vec_relationships vecRelationships = m_document->get_relationships(m_table_name);
     PyGlomRelated::type_map_relationships map_relationships;
     for(Document::type_vec_relationships::const_iterator iter = vecRelationships.begin(); iter != vecRelationships.end(); ++iter)
     {
@@ -114,33 +74,30 @@ boost::python::object PyGlomRecord::get_related()
         map_relationships[(*iter)->get_name()] = *iter;
     }
 
-    PyGlomRelated_SetRelationships(self_record->m_related, map_relationships);
+    boost::python::extract<PyGlomRelated*> extractor(m_related);
+    if(extractor.check())
+    {
+      PyGlomRelated* related_cpp = extractor;
+      PyGlomRelated_SetRelationships(related_cpp, map_relationships);
 
-    self_record->m_related->m_record = self_record;
-    Py_XINCREF(self_record); //unreffed in the self->m_related's _dealloc. //TODO: Is this a circular reference?
+      related_cpp->m_record = boost::python::object(this); //TODO_NotSure
+    }
   }
 
-  Py_INCREF(self_record->m_related); //Should we do this?
-  return self_record->m_related;
+  return m_related;
 }
-*/
 
 long PyGlomRecord::len() const
 {
-  if(!m_pMap_field_values)
-     return 0;
-     
-  return m_pMap_field_values->size();
+  return m_map_field_values.size();
 }
 
 boost::python::object PyGlomRecord::getitem(boost::python::object cppitem)
 {
   const std::string key = boost::python::extract<std::string>(cppitem);
-  if(!m_pMap_field_values)
-    return boost::python::object();
     
-  PyGlomRecord::type_map_field_values::const_iterator iterFind = m_pMap_field_values->find(key);
-  if(iterFind != m_pMap_field_values->end())
+  PyGlomRecord::type_map_field_values::const_iterator iterFind = m_map_field_values.find(key);
+  if(iterFind != m_map_field_values.end())
   {
     return glom_pygda_value_as_boost_pyobject(iterFind->second);
   }
@@ -150,16 +107,14 @@ boost::python::object PyGlomRecord::getitem(boost::python::object cppitem)
 
 void PyGlomRecord_SetFields(PyGlomRecord* self, const PyGlomRecord::type_map_field_values& field_values, Document* document, const Glib::ustring& table_name, const Glib::RefPtr<Gnome::Gda::Connection>& opened_connection)
 {
-  *(self->m_pMap_field_values) = field_values; //This was allocated in Record_new().
-
-  if(self->m_table_name == 0)
-    self->m_table_name = new Glib::ustring(table_name); //Deleted in Record_dealloc().
+  self->m_map_field_values = field_values; //This was allocated in Record_new().
 
+  self->m_table_name = table_name;
+  
   if(self->m_document == 0)
     self->m_document = document;
 
-  if(self->m_connection == 0)
-    self->m_connection = new Glib::RefPtr<Gnome::Gda::Connection>(opened_connection);  //Deleted in Record_dealloc().
+  self->m_connection = opened_connection;
 
   /*
   if(self->m_fields_dict == 0)
diff --git a/glom/libglom/python_embed/py_glom_record.h b/glom/libglom/python_embed/py_glom_record.h
index cf10f6f..2f7ea3b 100644
--- a/glom/libglom/python_embed/py_glom_record.h
+++ b/glom/libglom/python_embed/py_glom_record.h
@@ -21,6 +21,7 @@
 #ifndef GLOM_PYTHON_GLOM_RECORD_H
 #define GLOM_PYTHON_GLOM_RECORD_H
 
+#define NO_IMPORT_PYGOBJECT
 #define NO_IMPORT_PYGTK //To avoid a multiple definition in pygtk.
 #include <pygtk/pygtk.h> //For the PyGObject and PyGBoxed struct definitions.
 
@@ -49,7 +50,6 @@ public:
   boost::python::object get_related();
 
   //[] notation:
-
   long len() const;
   boost::python::object getitem(boost::python::object item);
 
@@ -57,16 +57,15 @@ public:
   //PyObject* m_fields_dict; //Dictionary (map) of field names (string) to field values (Gnome::Gda::Value).
   //PyGObject* m_py_gda_connection; //"derived" from PyObject.
   Document* m_document;
-  Glib::ustring* m_table_name;
+  Glib::ustring m_table_name;
 
-  PyGlomRelated* m_related;
+  boost::python::object m_related; //Actually a PyGlomRelated
 
   //Available, for instance, in python via record["name_first"]
   typedef std::map<Glib::ustring, Gnome::Gda::Value> type_map_field_values;
-  //We use a pointer because python will not run the class/struct's default constructor.
-  type_map_field_values* m_pMap_field_values;
+  type_map_field_values m_map_field_values;
 
-  Glib::RefPtr<Gnome::Gda::Connection>* m_connection;
+  Glib::RefPtr<Gnome::Gda::Connection> m_connection;
 };
 
 void PyGlomRecord_SetFields(PyGlomRecord* self, const PyGlomRecord::type_map_field_values& field_values, Document* document, const Glib::ustring& table_name, const Glib::RefPtr<Gnome::Gda::Connection>& opened_connection);
diff --git a/glom/libglom/python_embed/py_glom_related.cc b/glom/libglom/python_embed/py_glom_related.cc
index 5146979..6ffc240 100644
--- a/glom/libglom/python_embed/py_glom_related.cc
+++ b/glom/libglom/python_embed/py_glom_related.cc
@@ -38,81 +38,39 @@ namespace Glom
 
 PyGlomRelated::PyGlomRelated()
 {
-  PyGlomRelated *self  = this;
-  if(self)
-  {
-    self->m_record = 0;
-
-    self->m_pMap_relationships = new PyGlomRelated::type_map_relationships();
-    self->m_pMap_relatedrecords = new PyGlomRelated::type_map_relatedrecords();
-  }
 }
 
 PyGlomRelated::~PyGlomRelated()
 {
-  PyGlomRelated *self_related = this;
-
-  if(self_related->m_pMap_relationships)
-  {
-    delete self_related->m_pMap_relationships;
-    self_related->m_pMap_relationships = 0;
-  }
-
-  if(self_related->m_record)
-  {
-    Py_XDECREF( (PyObject*)self_related->m_record );
-    self_related->m_record = 0;
-  }
-
-  if(self_related->m_pMap_relatedrecords)
-  {
-    //Unref each item:
-    for(PyGlomRelated::type_map_relatedrecords::iterator iter = self_related->m_pMap_relatedrecords->begin(); iter != self_related->m_pMap_relatedrecords->end(); ++iter)
-    {
-      Py_XDECREF( (PyObject*)(iter->second) );
-    }
-
-    delete self_related->m_pMap_relatedrecords;
-    self_related->m_pMap_relatedrecords = 0;
-  }
 }
 
 
 long PyGlomRelated::len() const
 {
-  const PyGlomRelated *self_related = this;
-  return self_related->m_pMap_relationships->size();
+  return m_map_relationships.size();
 }
 
 boost::python::object PyGlomRelated::getitem(boost::python::object cppitem)
 {
-  PyGlomRelated *self_related = this;
-
-  PyObject* item = cppitem.ptr(); //TODO: Just use the C++ object.
-
-  if(PyString_Check(item))
+  boost::python::extract<std::string> extractor(cppitem);
+  if(extractor.check())
   {
-    const char* pchKey = PyString_AsString(item);
-    if(pchKey)
+    const std::string key = extractor;
+    if(!key.empty())
     {
-      const Glib::ustring key(pchKey);
-
       //Return a cached item if possible:
-      PyGlomRelated::type_map_relatedrecords::iterator iterCacheFind = self_related->m_pMap_relatedrecords->find(key);
-      if(iterCacheFind != self_related->m_pMap_relatedrecords->end())
+      PyGlomRelated::type_map_relatedrecords::iterator iterCacheFind = m_map_relatedrecords.find(key);
+      if(iterCacheFind != m_map_relatedrecords.end())
       {
         //Return a reference to the cached item:
-        PyGlomRelatedRecord* pyRelatedRecord = iterCacheFind->second;
-
-        PyObject* cobject = (PyObject*)pyRelatedRecord;
-        Py_INCREF((PyObject*)pyRelatedRecord);
-        return boost::python::object(boost::python::borrowed(cobject));
+        boost::python::object objectRelatedRecord = iterCacheFind->second;
+        return objectRelatedRecord;
       }
       else
       {
         //If the relationship exists:
-        PyGlomRelated::type_map_relationships::const_iterator iterFind = self_related->m_pMap_relationships->find(key);
-        if(iterFind != self_related->m_pMap_relationships->end())
+        PyGlomRelated::type_map_relationships::const_iterator iterFind = m_map_relationships.find(key);
+        if(iterFind != m_map_relationships.end())
         {
           //Return a new RelatedRecord:
           PyGlomRelatedRecord* pyRelatedRecord = new PyGlomRelatedRecord();
@@ -122,32 +80,36 @@ boost::python::object PyGlomRelated::getitem(boost::python::object cppitem)
           //Get the value of the from_key in the parent record.
           sharedptr<Relationship> relationship = iterFind->second;
           const Glib::ustring from_key = relationship->get_from_field();
-          PyGlomRecord::type_map_field_values::const_iterator iterFromKey = self_related->m_record->m_pMap_field_values->find(from_key);
-          if(iterFromKey != self_related->m_record->m_pMap_field_values->end())
+          
+          boost::python::extract<PyGlomRecord*> extractor(m_record);
+          if(extractor.check())
           {
-            const Gnome::Gda::Value from_key_value = iterFromKey->second;
-
-            //TODO_Performance:
-            //Get the full field details so we can sqlize its value:
-            sharedptr<Field> from_key_field;
-            from_key_field = self_related->m_record->m_document->get_field(*(self_related->m_record->m_table_name), from_key);
-            if(from_key_field)
+            PyGlomRecord* record = extractor;
+            PyGlomRecord::type_map_field_values::const_iterator iterFromKey = record->m_map_field_values.find(from_key);
+            if(iterFromKey != record->m_map_field_values.end())
             {
-              Glib::ustring key_value_sqlized;
-              //std::cout << "from_key_field=" << from_key_field->get_name() << ", from_key_value=" << from_key_value.to_string() << std::endl;
+              const Gnome::Gda::Value from_key_value = iterFromKey->second;
+
+              //TODO_Performance:
+              //Get the full field details so we can sqlize its value:
+              sharedptr<Field> from_key_field;
+              from_key_field = record->m_document->get_field(record->m_table_name, from_key);
+              if(from_key_field)
+              {
+                Glib::ustring key_value_sqlized;
+                //std::cout << "from_key_field=" << from_key_field->get_name() << ", from_key_value=" << from_key_value.to_string() << std::endl;
 
-              if(!Conversions::value_is_empty(from_key_value)) //Do not link on null-values. That would cause us to link on 0, or "0".
-                key_value_sqlized = from_key_field->sql(from_key_value);
+                if(!Conversions::value_is_empty(from_key_value)) //Do not link on null-values. That would cause us to link on 0, or "0".
+                  key_value_sqlized = from_key_field->sql(from_key_value);
 
-              PyGlomRelatedRecord_SetRelationship(pyRelatedRecord, iterFind->second, key_value_sqlized, self_related->m_record->m_document);
+                PyGlomRelatedRecord_SetRelationship(pyRelatedRecord, iterFind->second, key_value_sqlized, record->m_document);
 
-              //Store it in the cache:
-              Py_INCREF((PyObject*)pyRelatedRecord); //Dereferenced in _dealloc().
-              (*(self_related->m_pMap_relatedrecords))[key] = pyRelatedRecord;
+                //Store it in the cache:
+                boost::python::object objectRelatedRecord(pyRelatedRecord);
+                m_map_relatedrecords[key] = objectRelatedRecord;
 
-              PyObject* cobject = (PyObject*)pyRelatedRecord;
-              Py_INCREF((PyObject*)cobject);
-              return boost::python::object(boost::python::borrowed(cobject));
+                return objectRelatedRecord;
+              }
             }
           }
         }
@@ -156,7 +118,8 @@ boost::python::object PyGlomRelated::getitem(boost::python::object cppitem)
   }
 
   PyErr_SetString(PyExc_IndexError, "relationship not found");
-  return boost::python::object(); //TODO_Hack
+  boost::python::throw_error_already_set(); //TODO: Find a simpler way to throw a python exception/error.
+  return boost::python::object();
 }
 
 
@@ -171,7 +134,7 @@ static void Related_HandlePythonError()
 
 void PyGlomRelated_SetRelationships(PyGlomRelated* self, const PyGlomRelated::type_map_relationships& relationships)
 {
-  *(self->m_pMap_relationships) = relationships;
+  self->m_map_relationships = relationships;
 }
 
 } //namespace Glom
diff --git a/glom/libglom/python_embed/py_glom_related.h b/glom/libglom/python_embed/py_glom_related.h
index 7190113..65f8dde 100644
--- a/glom/libglom/python_embed/py_glom_related.h
+++ b/glom/libglom/python_embed/py_glom_related.h
@@ -43,15 +43,15 @@ public:
   friend class PyGlomRecord;
 
   typedef std::map<Glib::ustring, sharedptr<Relationship> > type_map_relationships;
-  typedef std::map<Glib::ustring, PyGlomRelatedRecord*> type_map_relatedrecords;
+  typedef std::map<Glib::ustring, boost::python::object /* Actually PyGlomRelatedRecord* */> type_map_relatedrecords;
 
 //TODO: protected:
-  PyGlomRecord* m_record; //A reference to the parent record.
+  boost::python::object m_record; //Actually PyGlomRecord. A reference to the parent record.
 
  
-  type_map_relationships* m_pMap_relationships;
+  type_map_relationships m_map_relationships;
 
-  type_map_relatedrecords* m_pMap_relatedrecords;
+  type_map_relatedrecords m_map_relatedrecords;
 };
 
 void PyGlomRelated_SetRelationships(PyGlomRelated* self, const PyGlomRelated::type_map_relationships& relationships);
diff --git a/glom/libglom/python_embed/py_glom_relatedrecord.cc b/glom/libglom/python_embed/py_glom_relatedrecord.cc
index 329aaf8..4537265 100644
--- a/glom/libglom/python_embed/py_glom_relatedrecord.cc
+++ b/glom/libglom/python_embed/py_glom_relatedrecord.cc
@@ -38,39 +38,11 @@ namespace Glom
 {
 
 PyGlomRelatedRecord::PyGlomRelatedRecord()
-: m_py_gda_connection(0),
-  m_document(0),
-  m_relationship(0),
-  m_from_key_value_sqlized(0)
 {
-  m_pMap_field_values = new PyGlomRelatedRecord::type_map_field_values();
 }
 
 PyGlomRelatedRecord::~PyGlomRelatedRecord()
 {
-  if(m_pMap_field_values)
-  {
-    delete m_pMap_field_values;
-    m_pMap_field_values = 0;
-  }
-
-  if(m_relationship)
-  {
-    delete m_relationship;
-    m_relationship = 0;
-  }
-
-  if(m_from_key_value_sqlized)
-  {
-    delete m_from_key_value_sqlized;
-    m_from_key_value_sqlized = 0;
-  }
-
-  if(m_py_gda_connection)
-  {
-    Py_XDECREF( (PyObject*)(m_py_gda_connection));
-    m_py_gda_connection = 0;
-  }
 }
 
 
@@ -82,33 +54,28 @@ static void RelatedRecord_HandlePythonError()
 
 long PyGlomRelatedRecord::len() const
 {
-  if(!m_pMap_field_values)
-     return 0;
-     
-  return m_pMap_field_values->size();
+  return m_map_field_values.size();
 }
 
 boost::python::object PyGlomRelatedRecord::getitem(boost::python::object cppitem)
 {
   const std::string field_name = boost::python::extract<std::string>(cppitem);
-  if(!m_pMap_field_values)
-    return boost::python::object();
-    
-  PyGlomRelatedRecord::type_map_field_values::const_iterator iterFind = m_pMap_field_values->find(field_name);
-  if(iterFind != m_pMap_field_values->end())
+ 
+  PyGlomRelatedRecord::type_map_field_values::const_iterator iterFind = m_map_field_values.find(field_name);
+  if(iterFind != m_map_field_values.end())
   {
     //If the value has already been stored, then just return it again:
     return glom_pygda_value_as_boost_pyobject(iterFind->second);
   }
   else
   {
-    const Glib::ustring related_table = (*m_relationship)->get_to_table();
+    const Glib::ustring related_table = m_relationship->get_to_table();
 
     //Check whether the field exists in the table.
     //TODO_Performance: Do this without the useless Field information?
-    sharedptr<Field> field = m_document->get_field((*m_relationship)->get_to_table(), field_name);
+    sharedptr<Field> field = m_document->get_field(m_relationship->get_to_table(), field_name);
     if(!field)
-      g_warning("RelatedRecord_tp_as_mapping_getitem: field %s not found in table %s", field_name.c_str(), (*m_relationship)->get_to_table().c_str());
+      g_warning("RelatedRecord_tp_as_mapping_getitem: field %s not found in table %s", field_name.c_str(), m_relationship->get_to_table().c_str());
     else
     {
       //Try to get the value from the database:
@@ -124,15 +91,15 @@ boost::python::object PyGlomRelatedRecord::getitem(boost::python::object cppitem
       {
         Glib::RefPtr<Gnome::Gda::Connection> gda_connection = sharedconnection->get_gda_connection();
 
-        const Glib::ustring related_key_name = (*m_relationship)->get_to_field();
+        const Glib::ustring related_key_name = m_relationship->get_to_field();
 
         //Do not try to get a value based on a null key value:
-        if(!(m_from_key_value_sqlized))
+        if(m_from_key_value_sqlized.empty())
           return boost::python::object();
        
         //Get the single value from the related records:
-        Glib::ustring sql_query = "SELECT \"" + related_table + "\".\"" + field_name + "\" FROM \"" + related_table + "\""
-          + " WHERE \"" + related_table + "\".\"" + related_key_name + "\" = " + *(m_from_key_value_sqlized);
+        const Glib::ustring sql_query = "SELECT \"" + related_table + "\".\"" + field_name + "\" FROM \"" + related_table + "\""
+          + " WHERE \"" + related_table + "\".\"" + related_key_name + "\" = " + m_from_key_value_sqlized;
 
         /* TODO: Fix linking problems
         const App_Glom* app = App_Glom::get_application();
@@ -166,7 +133,7 @@ boost::python::object PyGlomRelatedRecord::getitem(boost::python::object cppitem
           //g_warning("RelatedRecord_tp_as_mapping_getitem(): value from datamodel = %s", value.to_string().c_str());
 
           //Cache it, in case it's asked-for again.
-          (*(m_pMap_field_values))[field_name] = value;
+          m_map_field_values[field_name] = value;
           return glom_pygda_value_as_boost_pyobject(value);
         }
         else if(!datamodel)
@@ -177,7 +144,7 @@ boost::python::object PyGlomRelatedRecord::getitem(boost::python::object cppitem
         }
         else
         {
-          g_warning("RelatedRecord_tp_as_mapping_getitem(): No related records exist yet for relationship %s.",  (*m_relationship)->get_name().c_str());
+          g_warning("RelatedRecord_tp_as_mapping_getitem(): No related records exist yet for relationship %s.",  m_relationship->get_name().c_str());
         }
       }
     }
@@ -190,14 +157,14 @@ boost::python::object PyGlomRelatedRecord::getitem(boost::python::object cppitem
 
 boost::python::object PyGlomRelatedRecord::generic_aggregate(const std::string& field_name, const std::string& aggregate) const
 {
-  const Glib::ustring related_table = (*m_relationship)->get_to_table();
+  const Glib::ustring related_table = m_relationship->get_to_table();
 
   //Check whether the field exists in the table.
   //TODO_Performance: Do this without the useless Field information?
-  sharedptr<Field> field = m_document->get_field((*(m_relationship))->get_to_table(), field_name);
+  sharedptr<Field> field = m_document->get_field(m_relationship->get_to_table(), field_name);
   if(!field)
   {
-    g_warning("RelatedRecord_sum: field %s not found in table %s", field_name.c_str(), (*(m_relationship))->get_to_table().c_str());
+    g_warning("RelatedRecord_sum: field %s not found in table %s", field_name.c_str(), m_relationship->get_to_table().c_str());
     return boost::python::object();
   }
 
@@ -218,17 +185,17 @@ boost::python::object PyGlomRelatedRecord::generic_aggregate(const std::string&
   
   Glib::RefPtr<Gnome::Gda::Connection> gda_connection = sharedconnection->get_gda_connection();
 
-  const Glib::ustring related_key_name = (*m_relationship)->get_to_field();
+  const Glib::ustring related_key_name = m_relationship->get_to_field();
 
   //Do not try to get a value based on a null key value:
-  if(!(m_from_key_value_sqlized))
+  if(m_from_key_value_sqlized.empty())
   {
     return boost::python::object();
   }
        
   //Get the aggregate value from the related records:
   const Glib::ustring sql_query = "SELECT " + aggregate + "(\"" + related_table + "\".\"" + field_name + "\") FROM \"" + related_table + "\""
-    + " WHERE \"" + related_table + "\".\"" + related_key_name + "\" = " + *m_from_key_value_sqlized;
+    + " WHERE \"" + related_table + "\".\"" + related_key_name + "\" = " + m_from_key_value_sqlized;
         
   //std::cout << "PyGlomRelatedRecord: Executing:  " << sql_query << std::endl;
 #ifdef GLIBMM_EXCEPTIONS_ENABLED
@@ -250,7 +217,7 @@ boost::python::object PyGlomRelatedRecord::generic_aggregate(const std::string&
     //g_warning("RelatedRecord_generic_aggregate(): value from datamodel = %s", value.to_string().c_str());
 
     //Cache it, in case it's asked-for again.
-    (*m_pMap_field_values)[field_name] = value;
+    m_map_field_values[field_name] = value;
     return glom_pygda_value_as_boost_pyobject(value);
   }
   else if(!datamodel)
@@ -261,7 +228,7 @@ boost::python::object PyGlomRelatedRecord::generic_aggregate(const std::string&
   }
   else
   {
-    g_warning("RelatedRecord_generic_aggregate(): No related records exist yet for relationship %s.",  (*m_relationship)->get_name().c_str());
+    g_warning("RelatedRecord_generic_aggregate(): No related records exist yet for relationship %s.",  m_relationship->get_name().c_str());
   }
 
   return boost::python::object();
@@ -289,12 +256,9 @@ boost::python::object PyGlomRelatedRecord::max(const std::string& field_name) co
 
 void PyGlomRelatedRecord_SetRelationship(PyGlomRelatedRecord* self, const sharedptr<const Relationship>& relationship, const Glib::ustring& from_key_value_sqlized,  Document* document)
 {
-  self->m_relationship = new sharedptr<const Relationship>(relationship);
+  self->m_relationship = relationship;
 
-  if(!from_key_value_sqlized.empty())
-    self->m_from_key_value_sqlized = new Glib::ustring(from_key_value_sqlized);
-  else
-    self->m_from_key_value_sqlized = 0;
+  self->m_from_key_value_sqlized = from_key_value_sqlized;
 
   self->m_document = document;
 }
diff --git a/glom/libglom/python_embed/py_glom_relatedrecord.h b/glom/libglom/python_embed/py_glom_relatedrecord.h
index 651fa95..818dcce 100644
--- a/glom/libglom/python_embed/py_glom_relatedrecord.h
+++ b/glom/libglom/python_embed/py_glom_relatedrecord.h
@@ -21,8 +21,9 @@
 #ifndef GLOM_PYTHON_GLOM_RELATEDRECORD_H
 #define GLOM_PYTHON_GLOM_RELATEDRECORD_H
 
-#define NO_IMPORT_PYGTK //To avoid a multiple definition in pygtk.
 #include <boost/python.hpp>
+#define NO_IMPORT_PYGOBJECT
+#define NO_IMPORT_PYGTK //To avoid a multiple definition in pygtk.
 #include <pygtk/pygtk.h> //For the PyGObject and PyGBoxed struct definitions.
 
 #include <libglom/document/document.h>
@@ -54,22 +55,17 @@ public:
   boost::python::object generic_aggregate(const std::string& field_name, const std::string& aggregate) const;
 
   //PyObject* m_fields_dict; //Dictionary (map) of field names (string) to field values (Gnome::Gda::Value).
-  PyGObject* m_py_gda_connection; //"derived" from PyObject.
   //PyGlomRecord* m_record_parent;
   Document* m_document;
 
-  sharedptr<const Relationship>* m_relationship;
-  Glib::ustring* m_from_key_value_sqlized;
+  sharedptr<const Relationship> m_relationship;
+  Glib::ustring m_from_key_value_sqlized;
 
   //Available, for instance, in python via record["name_first"]
   typedef std::map<Glib::ustring, Gnome::Gda::Value> type_map_field_values;
-  //We use a pointer because python will not run the class/struct's default constructor.
-  type_map_field_values* m_pMap_field_values; 
+  mutable type_map_field_values m_map_field_values; //A cache.
 };
 
-PyTypeObject* PyGlomRelatedRecord_GetPyType();
-
-
 void PyGlomRelatedRecord_SetRelationship(PyGlomRelatedRecord* self, const sharedptr<const Relationship>& relationship, const Glib::ustring& from_key_value_sqlized, Document* document);
 
 /*
diff --git a/glom/python_embed/glom_python.cc b/glom/python_embed/glom_python.cc
index 444e2b3..aefef52 100644
--- a/glom/python_embed/glom_python.cc
+++ b/glom/python_embed/glom_python.cc
@@ -137,7 +137,7 @@ void ShowTrace()
 bool glom_python_module_is_available()
 {
   const gchar* name = "glom_" GLOM_ABI_VERSION_UNDERLINED;
-  PyObject* module_glom = PyImport_ImportModule((char*)name); //TODO: unref this?
+  boost::python::object module_glom = boost::python::import(name);
 
   if(!module_glom)
   {
@@ -150,7 +150,7 @@ bool glom_python_module_is_available()
 bool gda_python_module_is_available()
 {
   const gchar* name = "gda";
-  PyObject* module_glom = PyImport_ImportModule((char*)name); //TODO: unref this?
+  boost::python::object module_glom = boost::python::import(name); //TODO: unref this?
 
   if(!module_glom)
   {
@@ -212,65 +212,58 @@ Gnome::Gda::Value glom_evaluate_python_function_implementation(Field::glom_field
       if(!name.empty() && !script.empty())
       {
         //TODO: Is there a boost::python equivalent for Py_CompileString()?
-        PyObject* objectCompiled = Py_CompileString(script.c_str(), name.c_str() /* "filename", for debugging info */,  Py_file_input /* "start token" for multiple lines of code. */); //Returns a reference.
-  
+        PyObject* cObject = Py_CompileString(script.c_str(), name.c_str() /* "filename", for debugging info */,  Py_file_input /* "start token" for multiple lines of code. */); //Returns a reference.
+        boost::python::handle<> objectCompiled(cObject);
+
         if(!objectCompiled)
           HandlePythonError();
+          
+      
+        cObject = PyImport_ExecCodeModule(const_cast<char*>(name.c_str()), cObject); //Returns a reference. //This should make it importable.
+        boost::python::handle<> object(cObject);
 
-        PyObject* pObject = PyImport_ExecCodeModule(const_cast<char*>(name.c_str()), objectCompiled); //Returns a reference. //This should make it importable.
-
-        if(!pObject)
-         HandlePythonError();
+        if(!object)
+          HandlePythonError();
 
-        Py_DECREF(pObject);
-        Py_DECREF(objectCompiled);
         //TODO: When do these stop being importable? Should we unload them somehow later?
       }
     }
   }
 
-
-  PyObject* module_glom = PyImport_ImportModule((char*)"glom_" GLOM_ABI_VERSION_UNDERLINED);
+  boost::python::object module_glom = boost::python::import("glom_" GLOM_ABI_VERSION_UNDERLINED);
   if(!module_glom)
   {
     g_warning("Could not import python glom module.");
     return valueResult; // don't crash
   }
 
-  PyObject* module_glom_dict = PyModule_GetDict(module_glom);
+  //TODO: Complain that boost::python has no PyModule_GetDict() equivalent.
+  boost::python::object module_glom_dict = module_glom.attr("__dict__");
+  //PyObject* module_glom_dict = PyModule_GetDict(module_glom);
+  
   //This seems to be different to PyGlomRecord_GetPyType() - we can PyObject_Call() this one to instantiate it.
-  PyObject* pyTypeGlomRecord = PyDict_GetItemString(module_glom_dict, (char*)"Record"); //TODO: Unref this?
-  if(!pyTypeGlomRecord || !PyType_Check(pyTypeGlomRecord))
+  PyObject* module_glom_dictC = boost::python::extract<PyObject*>(module_glom_dict);
+  PyObject* pyTypeGlomRecordC = PyDict_GetItemString(module_glom_dictC, (char*)"Record"); //TODO: Unref this?
+  if(!pyTypeGlomRecordC || !PyType_Check(pyTypeGlomRecordC))
   {
     g_warning("Could not get glom.Record from glom_module.");
     return valueResult; // don't crash
   }
+  
+  boost::python::handle<> ref(pyTypeGlomRecordC);
+  boost::python::object pyTypeGlomRecord(ref);
 
-
-  PyObject* module_gda = PyImport_ImportModule((char*)"gda");
+  boost::python::object module_gda = boost::python::import("gda");
   if(!module_gda)
   {
     g_warning("Could not import python gda module.");
     return valueResult;
   }
 
-  // Gda.Value does not exist anymore in pygda-3.0
-#if 0
-  PyObject* module_gda_dict = PyModule_GetDict(module_gda);
-  PyObject* pyTypeGdaValue = PyDict_GetItemString(module_gda_dict, "Value"); //TODO: Unref this?
-  if(!pyTypeGdaValue || !PyType_Check(pyTypeGdaValue))
-    g_warning("Could not get gda.Value from gda_module.");
-#endif
-
-
   //Create the function definition:
-  PyObject* pyValue = PyRun_String(func_def.c_str(), Py_file_input, pDict.ptr(), pDict.ptr());
-  if(pyValue)
-  {
-    Py_DECREF(pyValue);
-    pyValue = 0;
-  }
-  else
+  //PyObject* pyValue = PyRun_String(func_def.c_str(), Py_file_input, pDict.ptr(), pDict.ptr());
+  boost::python::object pyValue = boost::python::eval(func_def.c_str(), pDict, pDict);
+  if(!pyValue)
   {
     ShowTrace();
   }
@@ -295,7 +288,7 @@ Gnome::Gda::Value glom_evaluate_python_function_implementation(Field::glom_field
     //PyObject* pParam = PyString_FromString("test value"); //This test did not need the extra ref.
 
     PyObject* new_args = PyTuple_New(0);
-    PyGlomRecord* pParam = (PyGlomRecord*)PyObject_Call((PyObject*)pyTypeGlomRecord, new_args, 0);
+    PyGlomRecord* pParam = (PyGlomRecord*)PyObject_Call((PyObject*)pyTypeGlomRecordC, new_args, 0);
     //PyGlomRecord* pParam = (PyGlomRecord*)PyObject_Call((PyObject*)PyGlomRecord_GetPyType(), new_args, 0);
     Py_DECREF(new_args);
     new_args = 0;



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]