From: Andrea Zagli Date: Sun, 26 Apr 2020 09:31:06 +0000 (+0200) Subject: Added function GdaEx::data_model_copy_update. X-Git-Url: https://saetta.ns0.it/gitweb?a=commitdiff_plain;h=ce22a3959aa2b11b82672cac23f7980eebcc17c3;p=libgdaex Added function GdaEx::data_model_copy_update. --- 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/copydminsert.c deleted file mode 100644 index cd2d987..0000000 --- a/tests/copydminsert.c +++ /dev/null @@ -1,104 +0,0 @@ -/* - * 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 - -#include - -static gchar *src_cnc = NULL; -static gchar *src_table = NULL; -static gchar *key_name = NULL; -static guint key_value = 0; -static gchar *dst_cnc = NULL; -static gchar *dst_table = NULL; -static gchar *exclude_name = NULL; -static gchar *exclude_value = NULL; - -static GOptionEntry entries[] = -{ - { "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 }, - { "key-value", 0, 0, G_OPTION_ARG_INT, &key_value, "Key field value", NULL }, - { "dst-cnc-string", 0, 0, G_OPTION_ARG_STRING, &dst_cnc, "Connection string for destination db", NULL }, - { "dst-table", 0, 0, G_OPTION_ARG_STRING, &dst_table, "Destination table", NULL }, - { "exclude-name", 0, 0, G_OPTION_ARG_STRING, &exclude_name, "Field name to exclude", NULL }, - { "exclude-value", 0, 0, G_OPTION_ARG_STRING, &exclude_value, "Field value to replace", NULL }, - { NULL } -}; - -int -main (int argc, char **argv) -{ - GError *error; - GOptionContext *context; - - GdaEx *src_gdaex; - GdaEx *dst_gdaex; - - GHashTable *ht_key; - GHashTable *ht_exclude; - - context = g_option_context_new ("- test copy_insert"); - g_option_context_add_main_entries (context, entries, NULL); - - error = NULL; - if (!g_option_context_parse (context, &argc, &argv, &error) - || error != NULL) - { - g_error ("Option parsing failed: %s.", error != NULL && error->message != NULL ? error->message : "no details"); - return 0; - } - - src_gdaex = gdaex_new_from_string (src_cnc); - if (src_gdaex == NULL) - { - g_error ("Unable to connect to the source db."); - } - - dst_gdaex = gdaex_new_from_string (dst_cnc); - if (dst_gdaex == NULL) - { - g_error ("Unable to connect to the destination db."); - } - - ht_key = g_hash_table_new (g_str_hash, g_str_equal); - - g_hash_table_insert (ht_key, - g_strdup (key_name), - zak_utils_gvalue_new_int (key_value)); - - ht_exclude = NULL; - if (exclude_name != NULL) - { - ht_exclude = g_hash_table_new (g_str_hash, g_str_equal); - - 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); - - return 0; -} diff --git a/tests/copydminsertupdate.c b/tests/copydminsertupdate.c new file mode 100644 index 0000000..a561ca4 --- /dev/null +++ b/tests/copydminsertupdate.c @@ -0,0 +1,118 @@ +/* + * 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 + +#include + +static gboolean update = FALSE; +static gchar *src_cnc = NULL; +static gchar *src_table = NULL; +static gchar *key_name = NULL; +static guint key_value = 0; +static gchar *dst_cnc = NULL; +static gchar *dst_table = NULL; +static gchar *exclude_name = NULL; +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 }, + { "key-value", 0, 0, G_OPTION_ARG_INT, &key_value, "Key field value", NULL }, + { "dst-cnc-string", 0, 0, G_OPTION_ARG_STRING, &dst_cnc, "Connection string for destination db", NULL }, + { "dst-table", 0, 0, G_OPTION_ARG_STRING, &dst_table, "Destination table", NULL }, + { "exclude-name", 0, 0, G_OPTION_ARG_STRING, &exclude_name, "Field name to exclude", NULL }, + { "exclude-value", 0, 0, G_OPTION_ARG_STRING, &exclude_value, "Field value to replace", NULL }, + { NULL } +}; + +int +main (int argc, char **argv) +{ + GError *error; + GOptionContext *context; + + GdaEx *src_gdaex; + GdaEx *dst_gdaex; + + GHashTable *ht_key; + GHashTable *ht_exclude; + + context = g_option_context_new ("- test copy_insert/update"); + g_option_context_add_main_entries (context, entries, NULL); + + error = NULL; + if (!g_option_context_parse (context, &argc, &argv, &error) + || error != NULL) + { + g_error ("Option parsing failed: %s.", error != NULL && error->message != NULL ? error->message : "no details"); + return 0; + } + + src_gdaex = gdaex_new_from_string (src_cnc); + if (src_gdaex == NULL) + { + g_error ("Unable to connect to the source db."); + } + + dst_gdaex = gdaex_new_from_string (dst_cnc); + if (dst_gdaex == NULL) + { + g_error ("Unable to connect to the destination db."); + } + + ht_key = g_hash_table_new (g_str_hash, g_str_equal); + + g_hash_table_insert (ht_key, + g_strdup (key_name), + zak_utils_gvalue_new_int (key_value)); + + ht_exclude = NULL; + if (exclude_name != NULL) + { + ht_exclude = g_hash_table_new (g_str_hash, g_str_equal); + + g_hash_table_insert (ht_exclude, exclude_name, zak_utils_gvalue_new_string (exclude_value)); + } + + 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; +}