From: Andrea Zagli Date: Sun, 26 Apr 2020 09:16:32 +0000 (+0200) Subject: Added function GdaEx::data_model_copy_insert. X-Git-Url: https://saetta.ns0.it/gitweb?a=commitdiff_plain;h=8747921d63975ed0b3da0a3e42d4c9bd3bf6f8d4;p=libgdaex Added function GdaEx::data_model_copy_insert. --- diff --git a/.gitignore b/.gitignore index ba749cc..0a148f4 100644 --- a/.gitignore +++ b/.gitignore @@ -44,6 +44,7 @@ po/libgdaex.pot *.bak intltool* libgdaex*tar* +tests/copydminsert tests/doubletosql tests/test_prefix* tests/query_editor diff --git a/src/gdaex.c b/src/gdaex.c index 26cbf7a..8d44e9a 100644 --- a/src/gdaex.c +++ b/src/gdaex.c @@ -39,6 +39,7 @@ #include #include "gdaex.h" +#include "sqlbuilder.h" static guint debug; static gchar *log_file; @@ -2719,6 +2720,125 @@ GtkTreeStore return ret; } +/** + * gdaex_data_model_copy_insert: + * @src_gdaex: + * @src_table: + * @src_ht_key + * @src_ht_exclude: + * @dst_gdaex: + * @dst_table: + * + * Insert a copy of a datamodel row into another datamodel. + */ +void +gdaex_data_model_copy_insert (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_INSERT); + + gdaex_sql_builder_from (sqlb, _dst_table, ""); + + 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); + 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 373de42..dc92271 100644 --- a/src/gdaex.h +++ b/src/gdaex.h @@ -207,6 +207,15 @@ GtkListStore *gdaex_data_model_to_gtkliststore (GdaDataModel *dm, GtkTreeStore *gdaex_data_model_to_gtktreestore (GdaDataModel *dm, gboolean only_schema); + +void gdaex_data_model_copy_insert (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); gint gdaex_execute (GdaEx *gdaex, const gchar *sql); diff --git a/tests/Makefile.am b/tests/Makefile.am index 28f2b22..589b1c1 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -6,6 +6,7 @@ AM_CPPFLAGS = $(GDAEX_CFLAGS) \ -DTESTSDIR="\"@abs_builddir@\"" noinst_PROGRAMS = \ + copydminsert \ doubletosql \ fill_liststore \ getsqlfromhashtable \ diff --git a/tests/copydminsert.c b/tests/copydminsert.c new file mode 100644 index 0000000..cd2d987 --- /dev/null +++ b/tests/copydminsert.c @@ -0,0 +1,104 @@ +/* + * 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; +}