[glom] Python: Prevent field calculations from changing the data in other fields.



commit d5af1b52376b2b26e34e3ae14dc8705a4d500639
Author: Murray Cumming <murrayc murrayc com>
Date:   Sat Feb 27 15:39:40 2010 +0100

    Python: Prevent field calculations from changing the data in other fields.
    
    * glom/libglom/python_embed/py_glom_record.[h|cc]: Added set_read_only().
    * glom/python_embed/glom_python.[h|cc]:
    glom_evaluate_python_function_implementation(): Add a bool read_only
    parameter that defaults to true.
    glom_execute_python_function_implementation(): Pass read_only=false so
    scripts can write data to the database via the record object.

 ChangeLog                                   |   11 +++++++++++
 glom/libglom/python_embed/py_glom_record.cc |   15 +++++++++++++--
 glom/libglom/python_embed/py_glom_record.h  |    8 ++++++++
 glom/python_embed/glom_python.cc            |    7 +++++--
 glom/python_embed/glom_python.h             |    9 ++++++++-
 5 files changed, 45 insertions(+), 5 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index d589430..0761c41 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,16 @@
 2010-02-27  Murray Cumming  <murrayc murrayc com>
 
+  Python: Prevent field calculations from changing the data in other fields.
+  
+	* glom/libglom/python_embed/py_glom_record.[h|cc]: Added set_read_only().
+	* glom/python_embed/glom_python.[h|cc]: 
+	glom_evaluate_python_function_implementation(): Add a bool read_only 
+	parameter that defaults to true.
+	glom_execute_python_function_implementation(): Pass read_only=false so 
+	scripts can write data to the database via the record object.
+
+2010-02-27  Murray Cumming  <murrayc murrayc com>
+
   Increase required version of libgdamm.
   
 	* configure.ac: Increase libgdamm dependency to the last one that doesn't 
diff --git a/glom/libglom/python_embed/py_glom_record.cc b/glom/libglom/python_embed/py_glom_record.cc
index a989659..9affd43 100644
--- a/glom/libglom/python_embed/py_glom_record.cc
+++ b/glom/libglom/python_embed/py_glom_record.cc
@@ -37,7 +37,8 @@ namespace Glom
 
 //Set the object's member data, from the parameters supplied when creating the object:
 PyGlomRecord::PyGlomRecord()
-: m_document(0)
+: m_document(0),
+  m_read_only(false)
 {
 }
 
@@ -45,6 +46,11 @@ PyGlomRecord::~PyGlomRecord()
 {
 }
 
+void PyGlomRecord::set_read_only()
+{
+  m_read_only = true;
+}
+
 std::string PyGlomRecord::get_table_name() const
 {
   return m_table_name;
@@ -115,7 +121,12 @@ boost::python::object PyGlomRecord::getitem(const boost::python::object& cppitem
 //TODO: Stop this from being used in field calculations, by making the record somehow read-only.
 void PyGlomRecord::setitem(const boost::python::object& key, const boost::python::object& value)
 {
-  //Get the specificd field name (and details) and value:
+  if(m_read_only)
+  {
+    std::cerr << "PyGlomRecord::setitem(): Failed to set a value because the record object is read-only."<< std::endl;
+    return;
+  }
+  //Get the specified field name (and details) and value:
 
   std::string field_name;
   boost::python::extract<std::string> extractor(key);
diff --git a/glom/libglom/python_embed/py_glom_record.h b/glom/libglom/python_embed/py_glom_record.h
index c94188f..e3e7f84 100644
--- a/glom/libglom/python_embed/py_glom_record.h
+++ b/glom/libglom/python_embed/py_glom_record.h
@@ -37,6 +37,13 @@ class PyGlomRecord
 public:
   PyGlomRecord();
   ~PyGlomRecord();
+  
+  /* Prevent python code from changing data in the database via this object.
+   * For instance, this should be used in a field calculation, 
+   * though changing data would be OK from a script.
+   * This is not exposed via Python.
+   */
+  void set_read_only();
 
   std::string get_table_name() const;
 
@@ -63,6 +70,7 @@ public:
   type_map_field_values m_map_field_values;
 
   Glib::RefPtr<Gnome::Gda::Connection> m_connection;
+  bool m_read_only;
 };
 
 void PyGlomRecord_SetFields(PyGlomRecord* self,
diff --git a/glom/python_embed/glom_python.cc b/glom/python_embed/glom_python.cc
index 44971cd..44bd9a3 100644
--- a/glom/python_embed/glom_python.cc
+++ b/glom/python_embed/glom_python.cc
@@ -176,7 +176,7 @@ void glom_execute_python_function_implementation(const Glib::ustring& func_impl,
   glom_evaluate_python_function_implementation(Field::TYPE_TEXT, func_impl,
      field_values, pDocument,
      table_name, key_field, key_field_value,
-     opened_connection);
+     opened_connection, false /* not read-only */);
 }
 
 Gnome::Gda::Value glom_evaluate_python_function_implementation(Field::glom_field_type result_type,
@@ -186,7 +186,8 @@ Gnome::Gda::Value glom_evaluate_python_function_implementation(Field::glom_field
   const Glib::ustring& table_name,
   const sharedptr<const Field>& key_field,
   const Gnome::Gda::Value& key_field_value,
-  const Glib::RefPtr<Gnome::Gda::Connection>& opened_connection)
+  const Glib::RefPtr<Gnome::Gda::Connection>& opened_connection,
+  bool read_only)
 {
   //std::cout << "glom_evaluate_python_function_implementation()" << std::endl;
   //for(type_map_fields::const_iterator iter = field_values.begin(); iter != field_values.end(); ++iter)
@@ -353,6 +354,8 @@ Gnome::Gda::Value glom_evaluate_python_function_implementation(Field::glom_field
     {
       //Fill the record's details:
       PyGlomRecord_SetFields(pParam, field_values, pDocument, table_name, key_field, key_field_value, opened_connection);
+      if(read_only)
+        pParam->set_read_only();
 
       //Call the function with this parameter:
        boost::python::object pyResultCpp;
diff --git a/glom/python_embed/glom_python.h b/glom/python_embed/glom_python.h
index 60f65ea..525b68c 100644
--- a/glom/python_embed/glom_python.h
+++ b/glom/python_embed/glom_python.h
@@ -40,6 +40,9 @@ bool gda_python_module_is_available();
 
 typedef std::map<Glib::ustring, Gnome::Gda::Value> type_map_fields;
 
+/** Run a script, ignoring the python return value.
+ * The record object will be writable.
+ */
 void glom_execute_python_function_implementation(const Glib::ustring& func_impl,
   const type_map_fields& field_values,
   Document* pDocument,
@@ -48,6 +51,9 @@ void glom_execute_python_function_implementation(const Glib::ustring& func_impl,
   const Gnome::Gda::Value& key_field_value,
   const Glib::RefPtr<Gnome::Gda::Connection>& opened_connection);
 
+/** Run a python calculation, returning the python return value.
+ * The record object will be read only unless @a read_only=false.
+ */
 Gnome::Gda::Value glom_evaluate_python_function_implementation(Field::glom_field_type result_type,
   const Glib::ustring& func_impl,
   const type_map_fields& field_values,
@@ -55,7 +61,8 @@ Gnome::Gda::Value glom_evaluate_python_function_implementation(Field::glom_field
   const Glib::ustring& table_name,
   const sharedptr<const Field>& key_field,
   const Gnome::Gda::Value& key_field_value,
-  const Glib::RefPtr<Gnome::Gda::Connection>& opened_connection);
+  const Glib::RefPtr<Gnome::Gda::Connection>& opened_connection, 
+  bool read_only = true);
 
 } //namespace Glom
 



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