[glom] Handle GdaBlob in query results instead of just GdaBinary.



commit daed2f59742856cd0dbfe5a82f893f976cbdc2f9
Author: Murray Cumming <murrayc murrayc com>
Date:   Fri Nov 4 22:37:53 2011 +0100

    Handle GdaBlob in query results instead of just GdaBinary.
    
    	* glom/libglom/data_structure/field.cc: to_file_format():
    	The Value might have a GdaBlob that needs to be read first, to get the
    	GdaBinary. This can happen with SQLite.
    	* glom/libglom/python_embed/pygdavalue_conversions.cc:
    	glom_pygda_value_as_boost_pyobject(): Handle GdaBlob too, though neither
    	this or the GdaBinary case use the data length, so this code is doomed
    	if it is ever used. I need to find out if Python can really represent
    	binary data, or if this should just not be handled here.
    	* glom/utility_widgets/imageglom.cc: get_binary(): Handle GdaBlob
    	too in the original data.
    	* tests/test_selfhosting_new_then_image.cc: Handle GdaBlob in the
    	data that is read back, for SQLite. Uncomment the SQLite test, fixing
    	make check with the latest libgda.

 ChangeLog                                          |   18 ++++++
 glom/libglom/data_structure/field.cc               |   58 ++++++++++++++------
 .../libglom/python_embed/pygdavalue_conversions.cc |   14 ++++-
 glom/utility_widgets/imageglom.cc                  |    7 +++
 tests/test_selfhosting_new_then_image.cc           |   35 +++++++++++--
 5 files changed, 107 insertions(+), 25 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index f1e6959..eb4341f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+2011-11-04  Murray Cumming  <murrayc murrayc com>
+
+	Handle GdaBlob in query results instead of just GdaBinary.
+
+	* glom/libglom/data_structure/field.cc: to_file_format():
+	The Value might have a GdaBlob that needs to be read first, to get the 
+	GdaBinary. This can happen with SQLite.
+	* glom/libglom/python_embed/pygdavalue_conversions.cc:
+	glom_pygda_value_as_boost_pyobject(): Handle GdaBlob too, though neither 
+	this or the GdaBinary case use the data length, so this code is doomed 
+	if it is ever used. I need to find out if Python can really represent 
+	binary data, or if this should just not be handled here.
+	* glom/utility_widgets/imageglom.cc: get_binary(): Handle GdaBlob 
+	too in the original data.
+	* tests/test_selfhosting_new_then_image.cc: Handle GdaBlob in the 
+	data that is read back, for SQLite. Uncomment the SQLite test, fixing 
+	make check with the latest libgda.
+
 1.19.17:
 
 2011-11-04  Murray Cumming  <murrayc murrayc com>
diff --git a/glom/libglom/data_structure/field.cc b/glom/libglom/data_structure/field.cc
index 9458e99..33beabc 100644
--- a/glom/libglom/data_structure/field.cc
+++ b/glom/libglom/data_structure/field.cc
@@ -22,6 +22,7 @@
 #include <libglom/connectionpool.h>
 #include <libglom/data_structure/glomconversions.h>
 #include <libglom/utils.h>
+#include <libgda/gda-blob-op.h>
 #include <glibmm/i18n.h>
 
 #include <iostream>
@@ -284,32 +285,52 @@ Glib::ustring Field::to_file_format(const Gnome::Gda::Value& value) const
 
 Glib::ustring Field::to_file_format(const Gnome::Gda::Value& value, glom_field_type glom_type)
 {
+  //Handle TYPE_IMAGE specially:
   if(glom_type == TYPE_IMAGE)
   {
-    if(!value.gobj() || (value.get_value_type() != GDA_TYPE_BINARY))
+    if(!value.gobj())
       return Glib::ustring();
  
-    const GdaBinary* gdabinary = gda_value_get_binary(value.gobj());
-    if(!gdabinary)
-      return Glib::ustring();
-    else
+    gchar* str = 0;
+    const GType value_type = value.get_value_type();
+    if(value_type == GDA_TYPE_BINARY)
+    {
+      const GdaBinary* gdabinary = gda_value_get_binary(value.gobj());
+      if(!gdabinary)
+        return Glib::ustring();
+      else
+      {
+        str = gda_binary_to_string(gdabinary, 0);
+      }
+    }
+    else if(value_type == GDA_TYPE_BLOB)
     {
-      gchar* str = gda_binary_to_string(gdabinary, 0);
-      Glib::ustring result = (str) ? 
-        Glib::ustring(Glib::ScopedPtr<char>(str).get()) : Glib::ustring();
+      const GdaBlob* gdablob = gda_value_get_blob(value.gobj());
+      if(!gdablob)
+        return Glib::ustring();
+      else
+      {
+        str = gda_blob_to_string(const_cast<GdaBlob*>(gdablob), 0);
+      }
+    }
 
-      //Avoid arbitrary newlines in this text.
-      //See libgda bug: https://bugzilla.gnome.org/show_bug.cgi?id=597390
-      result = Utils::string_replace(result, "\n", "\\012");
+    if(!str)
+      return Glib::ustring();
 
-      //Avoid arbitrary newlines in this text.
-      //See libgda bug: https://bugzilla.gnome.org/show_bug.cgi?id=597390
-      result = Utils::string_replace(result, "\r", "\\015");
+    Glib::ustring result = (str) ? 
+      Glib::ustring(Glib::ScopedPtr<char>(str).get()) : Glib::ustring();
 
-      //Escape any quotes in this text:
-      //See libgda bug: https://bugzilla.gnome.org/show_bug.cgi?id=597390
-      return Utils::string_replace(result, "\"", "\\042");
-    }
+    //Avoid arbitrary newlines in this text.
+    //See libgda bug: https://bugzilla.gnome.org/show_bug.cgi?id=597390
+    result = Utils::string_replace(result, "\n", "\\012");
+
+    //Avoid arbitrary newlines in this text.
+    //See libgda bug: https://bugzilla.gnome.org/show_bug.cgi?id=597390
+    result = Utils::string_replace(result, "\r", "\\015");
+
+    //Escape any quotes in this text:
+    //See libgda bug: https://bugzilla.gnome.org/show_bug.cgi?id=597390
+    return Utils::string_replace(result, "\"", "\\042");
   }
   
   NumericFormat format_ignored; //Because we use ISO format.
@@ -544,6 +565,7 @@ Glib::RefPtr<Gnome::Gda::Holder> Field::get_holder(const Gnome::Gda::Value& valu
     // investigate why the field type is not GdaBinary as well.
     // Maybe get_gda_type_for_glom_type() should already return fallback
     // types if necessary.
+    // Reply from murray: sqlite returns GdaBlob by default, and that should be OK. Is this causing a problem?
     std::cout << "debug: " << G_STRFUNC << ": Field type " << g_type_name(field_type) << " and value type " << g_type_name(gtype) << " don't match." << std::endl;
   }
   */
diff --git a/glom/libglom/python_embed/pygdavalue_conversions.cc b/glom/libglom/python_embed/pygdavalue_conversions.cc
index 2bb5a72..76d1ecd 100644
--- a/glom/libglom/python_embed/pygdavalue_conversions.cc
+++ b/glom/libglom/python_embed/pygdavalue_conversions.cc
@@ -7,6 +7,7 @@
 #include <boost/python.hpp>
 
 #include "pygdavalue_conversions.h"
+#include <libgda/gda-blob-op.h>
 #include <iostream>
 
 
@@ -179,10 +180,17 @@ boost::python::object glom_pygda_value_as_boost_pyobject(const Glib::ValueBase&
         ret = boost::python::object(g_value_get_uint64(boxed));
     } else if (value_type == GDA_TYPE_BINARY) {
         const GdaBinary* gdabinary = gda_value_get_binary(boxed);
-        ret = boost::python::object((const char*)gdabinary->data); /* TODO: Use the size. TODO: Check for null GdaBinary. */
+        if(gdabinary)
+          ret = boost::python::object((const char*)gdabinary->data); /* TODO: Use the size. TODO: Check for null GdaBinary. */
     } else if (value_type == GDA_TYPE_BLOB) {
-        /* const GdaBlob* val = gda_value_get_blob (boxed; */
-        /* TODO: This thing has a whole read/write API. */
+        const GdaBlob* gdablob = gda_value_get_blob (boxed);
+        if(gdablob && gdablob->op)
+        {
+          if(gda_blob_op_read_all(const_cast<GdaBlobOp*>(gdablob->op), const_cast<GdaBlob*>(gdablob)))
+          {
+            ret = boost::python::object((const char*)gdablob->data.data); /* TODO: Use the size. TODO: Check for null GdaBinary. */
+          }
+        }
     } else if (value_type == G_TYPE_BOOLEAN) {
         ret = boost::python::object((bool)g_value_get_boolean(boxed));
 #if PY_VERSION_HEX >= 0x02040000
diff --git a/glom/utility_widgets/imageglom.cc b/glom/utility_widgets/imageglom.cc
index 9ae46dc..0e464c0 100644
--- a/glom/utility_widgets/imageglom.cc
+++ b/glom/utility_widgets/imageglom.cc
@@ -31,6 +31,7 @@
 #include <gtkmm/stock.h>
 #include <giomm/file.h>
 #include <giomm/contenttype.h>
+#include <libgda/gda-blob-op.h>
 #include <glibmm/convert.h>
 
 #include <iostream>   // for cout, endl
@@ -233,6 +234,12 @@ const GdaBinary* ImageGlom::get_binary() const
   const GdaBinary* gda_binary = 0;
   if(m_original_data.get_value_type() == GDA_TYPE_BINARY)
     gda_binary = gda_value_get_binary(m_original_data.gobj());
+  else if(m_original_data.get_value_type() == GDA_TYPE_BLOB)
+  {
+    const GdaBlob* gda_blob = gda_value_get_blob(m_original_data.gobj());
+    if(gda_blob && gda_blob_op_read_all(const_cast<GdaBlobOp*>(gda_blob->op), const_cast<GdaBlob*>(gda_blob)))
+      gda_binary = &(gda_blob->data);
+  }
   
   return gda_binary;
 }
diff --git a/tests/test_selfhosting_new_then_image.cc b/tests/test_selfhosting_new_then_image.cc
index 429ad02..9367052 100644
--- a/tests/test_selfhosting_new_then_image.cc
+++ b/tests/test_selfhosting_new_then_image.cc
@@ -24,9 +24,11 @@
 #include <libglom/db_utils.h>
 #include <glibmm/fileutils.h>
 #include <glibmm/miscutils.h>
+#include <libgda/gda-blob-op.h>
 #include <glib.h> //For g_assert()
 #include <iostream>
 #include <cstdlib> //For EXIT_SUCCESS and EXIT_FAILURE
+#include <cstring> //For memcmp().
 
 static bool test(Glom::Document::HostingMode hosting_mode)
 {
@@ -114,13 +116,40 @@ static bool test(Glom::Document::HostingMode hosting_mode)
   }
   
   const Gnome::Gda::Value value_read = data_model->get_value_at(0, 0);
-  if(value_read.get_value_type() != GDA_TYPE_BINARY)
+  const GType value_read_type = value_read.get_value_type();
+  if( (value_read_type != GDA_TYPE_BINARY) &&
+    (value_read_type != GDA_TYPE_BLOB))
   {
     std::cerr << "Failure: The value read was not of the expected type: " << g_type_name( value_read.get_value_type() ) << std::endl;
     return false;
   }
 
-  if(value_set != value_read)
+  //Make sure that we have a GdaBinary,
+  //even if (as with SQLite) it's actually a GdaBlob that we get back:
+  const GdaBinary* binary_read = 0;
+  if(value_read_type == GDA_TYPE_BINARY)
+    binary_read = gda_value_get_binary(value_read.gobj());
+  else if(value_read_type == GDA_TYPE_BLOB)
+  {
+    const GdaBlob* blob = gda_value_get_blob(value_read.gobj());
+    const bool read_all = gda_blob_op_read_all(const_cast<GdaBlobOp*>(blob->op), const_cast<GdaBlob*>(blob));
+    if(!read_all)
+    {
+      std::cerr << "Failure: gda_blob_op_read_all() failed." << std::endl;
+      return false;
+    }
+
+    binary_read = &(blob->data);
+  }
+
+  const GdaBinary* binary_set = gda_value_get_binary(value_set.gobj());
+  if(binary_set->binary_length != binary_read->binary_length)
+  {
+    std::cerr << "Failure: The value read's data length was not equal to that of the value set." << std::endl;
+    return false;
+  }
+
+  if(memcmp(binary_set->data, binary_read->data, binary_set->binary_length) != 0)
   {
     std::cerr << "Failure: The value read was not equal to the value set." << std::endl;
     return false;
@@ -142,14 +171,12 @@ int main()
     return EXIT_FAILURE;
   }
   
-  /** TODO: Investigate why this does not work.
   if(!test(Glom::Document::HOSTING_MODE_SQLITE))
   {
     std::cerr << "Failed with SQLite" << std::endl;
     test_selfhosting_cleanup();
     return EXIT_FAILURE;
   }
-  */
 
   Glom::libglom_deinit();
 



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