[glom] Python calculations: Really convert to expected types.
- From: Murray Cumming <murrayc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glom] Python calculations: Really convert to expected types.
- Date: Sun, 2 May 2010 22:30:38 +0000 (UTC)
commit af79b02df611d5324af80404be62b6cc43ccf114
Author: Murray Cumming <murrayc murrayc com>
Date: Sun May 2 23:36:52 2010 +0200
Python calculations: Really convert to expected types.
* glom/libglom/data_structure/glomconversions.cc:
get_double_for_gda_value_numeric(): Handle all numeric GTypes - not just
G_TYPE_INT..
convert_value(): Remove the special case for G_TYPE_INT (now handled in
get_double_for_gda_value_numeric instead). Make sure that all numeric GTypes
are converted to GDA_TYPE_NUMERIC, making it easier for callers to check.
ChangeLog | 13 +++-
glom/libglom/data_structure/glomconversions.cc | 76 ++++++++++++++------
.../test_python_execute_func_change_result_type.cc | 4 +-
3 files changed, 69 insertions(+), 24 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index b8e954f..259a4f9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2010-05-02 Murray Cumming <murrayc murrayc-x61>
+
+ Python calculations: Really convert to expected types.
+
+ * glom/libglom/data_structure/glomconversions.cc:
+ get_double_for_gda_value_numeric(): Handle all numeric GTypes - not just
+ G_TYPE_INT..
+ convert_value(): Remove the special case for G_TYPE_INT (now handled in
+ get_double_for_gda_value_numeric instead). Make sure that all numeric GTypes
+ are converted to GDA_TYPE_NUMERIC, making it easier for callers to check.
+
2010-05-01 Murray Cumming <murrayc murrayc com>
Add test of type conversion after python calculations.
@@ -9,7 +20,7 @@
2010-05-01 Murray Cumming <murrayc murrayc com>
- Python scripts and calcuations: Test buttons now show python errors.
+ Python scripts and calculations: Test buttons now show python errors.
* glom/python_embed/glom_python.[h|cc]:
glom_execute_python_function_implementation(),
diff --git a/glom/libglom/data_structure/glomconversions.cc b/glom/libglom/data_structure/glomconversions.cc
index 7bf57a9..ff4fe06 100644
--- a/glom/libglom/data_structure/glomconversions.cc
+++ b/glom/libglom/data_structure/glomconversions.cc
@@ -292,16 +292,32 @@ Glib::ustring Conversions::get_text_for_gda_value(Field::glom_field_type glom_ty
double Conversions::get_double_for_gda_value_numeric(const Gnome::Gda::Value& value)
{
- if(value.get_value_type() != GDA_TYPE_NUMERIC)
+ const GType vtype = value.get_value_type();
+ if(vtype != GDA_TYPE_NUMERIC)
{
// Note that in case the database system does not support GdaNumeric
// (such as sqlite) we fall back to double (see
// FieldTypes::get_string_name_for_gdavaluetype), so try this as well.
- if(value.get_value_type() == G_TYPE_DOUBLE)
- return value.get_double();
-
- std::cerr << "Conversions::get_double_for_gda_value_numeric(): expected NUMERIC but GdaValue type is: " << g_type_name(value.get_value_type()) << std::endl;
- return 0;
+ switch(vtype)
+ {
+ case G_TYPE_DOUBLE:
+ return value.get_double();
+ case G_TYPE_INT:
+ return value.get_int();
+ case G_TYPE_UINT:
+ return value.get_uint();
+ //case G_TYPE_LONG:
+ //TODO: Add this to libgdamm: return value.get_long();
+ case G_TYPE_ULONG:
+ return value.get_ulong();
+ case G_TYPE_INT64:
+ return value.get_int64();
+ case G_TYPE_UINT64:
+ return value.get_uint64();
+ default:
+ std::cerr << "Conversions::get_double_for_gda_value_numeric(): expected NUMERIC but GdaValue type is: " << g_type_name(value.get_value_type()) << std::endl;
+ return 0;
+ }
}
const GdaNumeric* gda_numeric = value.get_numeric();
@@ -972,29 +988,47 @@ Gnome::Gda::Value Conversions::get_example_value(Field::glom_field_type field_ty
}
}
-Gnome::Gda::Value Conversions::convert_value(const Gnome::Gda::Value& value, Field::glom_field_type target_glom_type)
+static bool vtype_is_numeric(GType vtype)
{
- const GType gvalue_type = value.get_value_type();
-
- //A special case (only used for serial keys)
- //Always convert these.
- if(gvalue_type == G_TYPE_INT)
+ switch(vtype)
{
- const gint num = value.get_int();
- return parse_value(num);
+ case G_TYPE_DOUBLE:
+ case G_TYPE_INT:
+ case G_TYPE_UINT:
+ case G_TYPE_LONG:
+ case G_TYPE_ULONG:
+ case G_TYPE_INT64:
+ case G_TYPE_UINT64:
+ return true;
+ default:
+ return false;
}
+}
- const Field::glom_field_type source_glom_type = Field::get_glom_type_for_gda_type(gvalue_type);
+Gnome::Gda::Value Conversions::convert_value(const Gnome::Gda::Value& value, Field::glom_field_type target_glom_type)
+{
+ const GType gvalue_type_target = Field::get_gda_type_for_glom_type(target_glom_type);
+ const GType gvalue_type_source = value.get_value_type();
+ if(gvalue_type_source == gvalue_type_target)
+ return value; //No conversion necessary, and no loss of precision.
+
+ const Field::glom_field_type source_glom_type = Field::get_glom_type_for_gda_type(gvalue_type_source);
if(source_glom_type == target_glom_type)
- return value; //No conversion necessary.
- else
{
- const Glib::ustring text = get_text_for_gda_value(source_glom_type, value);
- bool test = false;
- return parse_value(target_glom_type, text, test, true /* iso_format */);
+ //Try to return the canonical type,
+ //instead of just something of a similar GType:
+ if((target_glom_type == Field::TYPE_NUMERIC) &&
+ (vtype_is_numeric(gvalue_type_source)))
+ {
+ const double number = get_double_for_gda_value_numeric(value);
+ return parse_value(number);
+ }
}
- return value;
+ //Fallback for other conversions:
+ const Glib::ustring text = get_text_for_gda_value(source_glom_type, value);
+ bool test = false;
+ return parse_value(target_glom_type, text, test, true /* iso_format */);
}
} //namespace Glom
diff --git a/tests/test_python_execute_func_change_result_type.cc b/tests/test_python_execute_func_change_result_type.cc
index 2d32f8a..720cd14 100644
--- a/tests/test_python_execute_func_change_result_type.cc
+++ b/tests/test_python_execute_func_change_result_type.cc
@@ -37,7 +37,7 @@ int main()
return EXIT_FAILURE;
}
- std::cout << "type=" << g_type_name(value.get_value_type()) << std::endl;
+ //std::cout << "type=" << g_type_name(value.get_value_type()) << std::endl;
//Check that there was no python error:
g_assert(error_message.empty());
@@ -47,7 +47,7 @@ int main()
//Check that the return value is of the expected value:
const Glib::ustring text = value.get_string();
- std::cout << "text=" << text << std::endl;
+ //std::cout << "text=" << text << std::endl;
g_assert(text == "4950"); //This should always be as per ISO, not according to the user's locale, because it's generally passed to the database. Presentation is separate to calculation or storage.
//std::cout << "value=" << value.to_string() << std::endl;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]