From ce22a3959aa2b11b82672cac23f7980eebcc17c3 Mon Sep 17 00:00:00 2001 From: Andrea Zagli Date: Sun, 26 Apr 2020 11:31:06 +0200 Subject: [PATCH] Added function GdaEx::data_model_copy_update. --- .gitignore | 2 +- src/gdaex.c | 139 ++++++++++++++++++ src/gdaex.h | 7 + tests/Makefile.am | 2 +- .../{copydminsert.c => copydminsertupdate.c} | 28 +++- 5 files changed, 169 insertions(+), 9 deletions(-) rename tests/{copydminsert.c => copydminsertupdate.c} (80%) diff --git a/.gitignore b/.gitignore index 0a148f4..7fac11f 100644 --- a/.gitignore +++ b/.gitignore @@ -44,7 +44,7 @@ po/libgdaex.pot *.bak intltool* libgdaex*tar* -tests/copydminsert +tests/copydminsertupdate tests/doubletosql tests/test_prefix* tests/query_editor diff --git a/src/gdaex.c b/src/gdaex.c index 8d44e9a..8f1012a 100644 --- a/src/gdaex.c +++ b/src/gdaex.c @@ -2839,6 +2839,145 @@ gdaex_data_model_copy_insert (GdaEx *src_gdaex, gdaex_sql_builder_execute (sqlb, dst_gdaex, NULL); } +/** + * gdaex_data_model_copy_update: + * @src_gdaex: + * @src_table: + * @src_ht_key + * @src_ht_exclude: + * @dst_gdaex: + * @dst_table: + * + * Update a copy of a datamodel row into another datamodel. + */ +void +gdaex_data_model_copy_update (GdaEx *src_gdaex, + const gchar *src_table, + GHashTable *src_ht_key, + GHashTable *src_ht_exclude, + GdaEx *dst_gdaex, + const gchar *dst_table) +{ + GdaDataModel *src_dm; + GdaExSqlBuilder *sqlb; + + gchar *_src_table; + gchar *_dst_table; + + GHashTableIter iter; + gpointer key; + gpointer value; + + guint cols; + guint col; + + const gchar *field_name; + GValue *gval; + + g_return_if_fail (IS_GDAEX (src_gdaex)); + g_return_if_fail (IS_GDAEX (dst_gdaex)); + g_return_if_fail (src_table != NULL); + g_return_if_fail (src_ht_key != NULL); + + _src_table = g_strstrip (g_strdup (src_table)); + + g_return_if_fail (g_strcmp0 (_src_table, "") != 0); + + g_return_if_fail (g_hash_table_size (src_ht_key) > 0); + + sqlb = gdaex_sql_builder_new (GDA_SQL_STATEMENT_SELECT); + + gdaex_sql_builder_from (sqlb, _src_table, ""); + + gdaex_sql_builder_field (sqlb, _src_table, "*", NULL, NULL); + + g_hash_table_iter_init (&iter, src_ht_key); + while (g_hash_table_iter_next (&iter, &key, &value)) + { + gdaex_sql_builder_where (sqlb, 0, + _src_table, (gchar *)key, "", + GDA_SQL_OPERATOR_TYPE_EQ, + (GValue *)value, + NULL); + } + + src_dm = gdaex_sql_builder_query (sqlb, src_gdaex, NULL); + if (gdaex_data_model_is_empty (src_dm)) + { + g_warning ("Nothing to copy."); + return; + } + + /* if dst_table is null or empty, we use the same name as source table */ + if (dst_table == NULL) + { + _dst_table = g_strdup (_src_table); + } + else + { + _dst_table = g_strstrip (g_strdup (dst_table)); + if (g_strcmp0 (_dst_table, "") == 0) + { + g_free (_dst_table); + _dst_table = g_strdup (_src_table); + } + } + + sqlb = gdaex_sql_builder_new (GDA_SQL_STATEMENT_UPDATE); + + gdaex_sql_builder_from (sqlb, _dst_table, ""); + + g_hash_table_iter_init (&iter, src_ht_key); + while (g_hash_table_iter_next (&iter, &key, &value)) + { + gdaex_sql_builder_where (sqlb, 0, + _dst_table, (gchar *)key, "", + GDA_SQL_OPERATOR_TYPE_EQ, + (GValue *)value, + NULL); + } + + cols = gda_data_model_get_n_columns (src_dm); + for (col = 0; col < cols; col++) + { + gval = NULL; + + field_name = gda_data_model_get_column_name (src_dm, col); + + /* exclude key fields */ + if (g_hash_table_lookup_extended (src_ht_key, + (gconstpointer)field_name, + NULL, + NULL)) + { + continue; + } + + if (src_ht_exclude != NULL) + { + if (g_hash_table_lookup_extended (src_ht_exclude, + (gconstpointer)field_name, + NULL, + &gval)) + { + if (gval == NULL) + { + continue; + } + } + } + + if (gval == NULL) + { + gval = gda_data_model_get_value_at (src_dm, col, 0, NULL); + } + + gdaex_sql_builder_field (sqlb, _dst_table, field_name, "", gval); + } + + gdaex_sql_builder_execute (sqlb, dst_gdaex, NULL); +} + /** * gdaex_begin: * @gdaex: a #GdaEx object. diff --git a/src/gdaex.h b/src/gdaex.h index dc92271..4167574 100644 --- a/src/gdaex.h +++ b/src/gdaex.h @@ -215,6 +215,13 @@ void gdaex_data_model_copy_insert (GdaEx *src_gdaex, GdaEx *dst_gdaex, const gchar *dst_table); +void gdaex_data_model_copy_update (GdaEx *src_gdaex, + const gchar *src_table, + GHashTable *src_ht_key, + GHashTable *src_ht_exclude, + GdaEx *dst_gdaex, + const gchar *dst_table); + gboolean gdaex_begin (GdaEx *gdaex); diff --git a/tests/Makefile.am b/tests/Makefile.am index 589b1c1..cc7124b 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -6,7 +6,7 @@ AM_CPPFLAGS = $(GDAEX_CFLAGS) \ -DTESTSDIR="\"@abs_builddir@\"" noinst_PROGRAMS = \ - copydminsert \ + copydminsertupdate \ doubletosql \ fill_liststore \ getsqlfromhashtable \ diff --git a/tests/copydminsert.c b/tests/copydminsertupdate.c similarity index 80% rename from tests/copydminsert.c rename to tests/copydminsertupdate.c index cd2d987..a561ca4 100644 --- a/tests/copydminsert.c +++ b/tests/copydminsertupdate.c @@ -22,6 +22,7 @@ #include +static gboolean update = FALSE; static gchar *src_cnc = NULL; static gchar *src_table = NULL; static gchar *key_name = NULL; @@ -33,6 +34,7 @@ static gchar *exclude_value = NULL; static GOptionEntry entries[] = { + { "update", 'u', 0, G_OPTION_ARG_NONE, &update, "Update instead of insert", NULL }, { "src-cnc-string", 0, 0, G_OPTION_ARG_STRING, &src_cnc, "Connection string for source db", NULL }, { "src-table", 0, 0, G_OPTION_ARG_STRING, &src_table, "Source table", NULL }, { "key-name", 0, 0, G_OPTION_ARG_STRING, &key_name, "Key field name", NULL }, @@ -56,7 +58,7 @@ main (int argc, char **argv) GHashTable *ht_key; GHashTable *ht_exclude; - context = g_option_context_new ("- test copy_insert"); + context = g_option_context_new ("- test copy_insert/update"); g_option_context_add_main_entries (context, entries, NULL); error = NULL; @@ -93,12 +95,24 @@ main (int argc, char **argv) g_hash_table_insert (ht_exclude, exclude_name, zak_utils_gvalue_new_string (exclude_value)); } - gdaex_data_model_copy_insert (src_gdaex, - src_table, - ht_key, - ht_exclude, - dst_gdaex, - dst_table); + if (update) + { + gdaex_data_model_copy_update (src_gdaex, + src_table, + ht_key, + ht_exclude, + dst_gdaex, + dst_table); + } + else + { + gdaex_data_model_copy_insert (src_gdaex, + src_table, + ht_key, + ht_exclude, + dst_gdaex, + dst_table); + } return 0; } -- 2.49.0