From 626208e23a871569f2dc6fe11d9521c34c4ea3ae Mon Sep 17 00:00:00 2001 From: Andrea Zagli Date: Fri, 28 Aug 2020 16:40:00 +0200 Subject: [PATCH] Added functions ::data_model_to_json* (with test). --- .gitignore | 1 + configure.ac | 3 +- src/gdaex.c | 156 +++++++++++++++++++++++++++++++++++++++++ src/gdaex.h | 8 +++ tests/Makefile.am | 1 + tests/dm_2_json.c | 74 +++++++++++++++++++ tests/fill_liststore.c | 2 +- 7 files changed, 243 insertions(+), 2 deletions(-) create mode 100644 tests/dm_2_json.c diff --git a/.gitignore b/.gitignore index 7fac11f..a052ce4 100644 --- a/.gitignore +++ b/.gitignore @@ -46,6 +46,7 @@ intltool* libgdaex*tar* tests/copydminsertupdate tests/doubletosql +tests/dm_2_json tests/test_prefix* tests/query_editor tests/*.gdaexxml diff --git a/configure.ac b/configure.ac index 3bed8c3..c263a5a 100644 --- a/configure.ac +++ b/configure.ac @@ -53,7 +53,8 @@ PKG_CHECK_MODULES(GDAEX, [gmodule-2.0 >= 2 gio-2.0 >= 2.36 gtk+-3.0 >= 3 libxml-2.0 >= 2 - libzakutils]) + libzakutils + libzakutilsjsonxml]) AC_SUBST(GDAEX_CFLAGS) AC_SUBST(GDAEX_LIBS) diff --git a/src/gdaex.c b/src/gdaex.c index fc1ffe7..fe73fff 100644 --- a/src/gdaex.c +++ b/src/gdaex.c @@ -38,6 +38,8 @@ #include #include +#include + #include "gdaex.h" #include "sqlbuilder.h" @@ -4340,6 +4342,160 @@ gchar return ret; } +JsonNode +*gdaex_data_model_to_json (GdaDataModel *dm, GdaExColsFormatFunc format_func, gpointer user_data) +{ + JsonNode *ret; + + guint cols; + guint col; + + guint rows; + + GdaDataModelIter *gda_iter; + + GdaColumn *gdacolumn; + + gchar **gcol_names; + GType *gcol_gtypes; + + gint ival; + gdouble dval; + GDateTime *gdatetime; + + gchar *formatted; + + g_return_val_if_fail (GDA_IS_DATA_MODEL (dm), NULL); + + gda_iter = gda_data_model_create_iter (dm); + if (gda_iter == NULL) + { + return NULL; + } + + cols = gda_data_model_get_n_columns (dm); + rows = gda_data_model_get_n_rows (dm); + + gcol_names = (gchar **)g_new0 (gchar *, cols); + gcol_gtypes = (GType *)g_new0 (GType, cols); + + /* caching of columns types */ + for (col = 0; col < cols; col++) + { + gdacolumn = gda_data_model_describe_column (dm, col); + if (gdacolumn == NULL) + { + gcol_names[col] = NULL; + gcol_gtypes[col] = 0; + } + else + { + gcol_names[col] = g_strdup (gda_column_get_name (gdacolumn)); + gcol_gtypes[col] = gda_column_get_g_type (gdacolumn); + } + } + + if (rows > 1) + { + ret = zak_utils_json_node_new_array (); + } + + while (gda_data_model_iter_move_next (gda_iter)) + { + JsonNode *jnode_row; + JsonObject *jnode_obj; + + jnode_row = zak_utils_json_node_new_object (); + + for (col = 0; col < cols; col++) + { + GValue gval = {0}; + g_value_init (&gval, G_TYPE_STRING); + + formatted = NULL; + + if (format_func != NULL) + { + formatted = (*format_func) (gda_iter, col, user_data); + if (formatted != NULL) + { + g_value_set_string (&gval, formatted); + } + } + + if (formatted == NULL) + { + switch (gcol_gtypes[col]) + { + case G_TYPE_STRING: + g_value_set_string (&gval, gdaex_data_model_iter_get_value_stringify_at (gda_iter, col)); + break; + + case G_TYPE_BOOLEAN: + g_value_set_string (&gval, gdaex_data_model_iter_get_value_boolean_at (gda_iter, col) ? "X" : ""); + break; + + case G_TYPE_INT: + ival = gdaex_data_model_iter_get_value_integer_at (gda_iter, col); + g_value_set_string (&gval, gdaex_format_money ((gdouble)ival, 0, FALSE)); + break; + + case G_TYPE_FLOAT: + case G_TYPE_DOUBLE: + dval = gdaex_data_model_iter_get_value_double_at (gda_iter, col); + g_value_set_string (&gval, gdaex_format_money (dval, -1, FALSE)); + break; + + default: + { + if (gcol_gtypes[col] == G_TYPE_DATE + || gcol_gtypes[col] == GDA_TYPE_TIMESTAMP + || gcol_gtypes[col] == G_TYPE_DATE_TIME) + { + gdatetime = gdaex_data_model_iter_get_value_gdatetime_at (gda_iter, col); + /* TODO find default format from locale */ + g_value_set_string (&gval, g_date_time_format (gdatetime, gcol_gtypes[col] == G_TYPE_DATE ? "%d/%m/%Y" : "%d/%m/%Y %H.%M.%S")); + } + else + { + g_value_set_string (&gval, gda_value_stringify (gda_data_model_iter_get_value_at (gda_iter, col))); + } + break; + } + } + } + + jnode_obj = json_node_get_object (jnode_row); + json_object_set_string_member (jnode_obj, gcol_names[col], g_value_get_string (&gval)); + + } + + if (rows > 1) + { + JsonArray *ar; + + ar = json_node_get_array (ret); + json_array_add_element (ar, jnode_row); + } + else + { + ret = jnode_row; + } + } + + return ret; +} + +JsonNode +*gdaex_data_model_to_json_from_sql (GdaEx *gdaex, const gchar *sql, GdaExColsFormatFunc format_func, gpointer user_data) +{ + GdaDataModel *dm; + + dm = gdaex_query (gdaex, sql); + + return gdaex_data_model_to_json (dm, format_func, user_data); +} + /* PRIVATE */ static void gdaex_create_connection_parser (GdaEx *gdaex) diff --git a/src/gdaex.h b/src/gdaex.h index 02f73c3..af559ae 100644 --- a/src/gdaex.h +++ b/src/gdaex.h @@ -30,9 +30,13 @@ #include +#include + + #ifndef __GDAEX_H__ #define __GDAEX_H__ + G_BEGIN_DECLS @@ -346,7 +350,11 @@ GdaDataModel *gdaex_meta_store_get_table_fields (GdaEx *gdaex, const gchar *tabl gchar *gdaex_double_to_sql (gdouble number); +JsonNode *gdaex_data_model_to_json (GdaDataModel *dm, GdaExColsFormatFunc format_func, gpointer user_data); +JsonNode *gdaex_data_model_to_json_from_sql (GdaEx *gdaex, const gchar *sql, GdaExColsFormatFunc format_func, gpointer user_data); + G_END_DECLS + #endif /* __GDAEX_H__ */ diff --git a/tests/Makefile.am b/tests/Makefile.am index cc7124b..a6fa781 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -7,6 +7,7 @@ AM_CPPFLAGS = $(GDAEX_CFLAGS) \ noinst_PROGRAMS = \ copydminsertupdate \ + dm_2_json \ doubletosql \ fill_liststore \ getsqlfromhashtable \ diff --git a/tests/dm_2_json.c b/tests/dm_2_json.c new file mode 100644 index 0000000..a26a426 --- /dev/null +++ b/tests/dm_2_json.c @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2020 Andrea Zagli + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include + +gchar +*format_func (GdaDataModelIter *iter, guint col, gpointer user_data) +{ + if (col == 6) + { + gboolean val; + + val = gdaex_data_model_iter_get_value_boolean_at (iter, col); + + if (val) + { + return "Yes"; + } + else + { + return "No"; + } + } + else + { + return NULL; + } +} + +int +main (int argc, char **argv) +{ + GdaEx *gdaex; + + gchar *sql; + + JsonGenerator *generator; + JsonNode *jnode; + + gtk_init (&argc, &argv); + + gdaex = gdaex_new_from_string (g_strdup_printf ("SQLite://DB_DIR=%s;DB_NAME=grid.db", TESTSDIR)); + if (gdaex == NULL) + { + g_error ("Unable to connect to the db."); + } + + sql = g_strdup_printf ("SELECT * FROM clients"); + jnode = gdaex_data_model_to_json_from_sql (gdaex, sql, format_func, NULL); + g_free (sql); + + generator = json_generator_new (); + json_generator_set_root (generator, jnode); + + g_warning ("%s", json_generator_to_data (generator, NULL)); + + return 0; +} diff --git a/tests/fill_liststore.c b/tests/fill_liststore.c index cc8bcc3..704edf4 100644 --- a/tests/fill_liststore.c +++ b/tests/fill_liststore.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 Andrea Zagli + * Copyright (C) 2011-2020 Andrea Zagli * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by -- 2.49.0