From b0a6728ecdbf42e9506e6b6bfab15b2a0d5bb11e Mon Sep 17 00:00:00 2001 From: Andrea Zagli Date: Mon, 6 Jan 2020 10:09:16 +0100 Subject: [PATCH] Added function ::get_changes_datamodel and refactored method of getting changes from db. --- src/audit.c | 437 +++++++++++++++++++++++++++------------------- src/libzakaudit.h | 7 +- 2 files changed, 263 insertions(+), 181 deletions(-) diff --git a/src/audit.c b/src/audit.c index 220ee67..834bcb9 100644 --- a/src/audit.c +++ b/src/audit.c @@ -1,7 +1,7 @@ /* * audit.c * - * Copyright (C) 2005-2019 Andrea Zagli + * Copyright (C) 2005-2020 Andrea Zagli * * This file is part of libzakaudit. * @@ -35,6 +35,7 @@ #include #include +#include #include "libzakaudit.h" @@ -52,19 +53,12 @@ enum { COL_CHANGES_ID, COL_CHANGES_DATE, + COL_CHANGES_ID_OPERATION, COL_CHANGES_OPERATION, COL_CHANGES_USER, CHANGES_STATIC_COLUMNS }; -typedef struct -{ - guint col; - gchar *field_name; - gchar *field_long_name; - gchar *field_value; -} ChangesColumn; - typedef struct { gchar **values; @@ -1761,7 +1755,7 @@ zak_audit_action_from_gdastatement (ZakAudit *zak_audit, } /** - * zak_audit_get_changes_widget: + * zak_audit_get_changes_datamodel: * @zak_audit: an #ZakAudit object. * @datasource_name: * @table_name: @@ -1769,15 +1763,13 @@ zak_audit_action_from_gdastatement (ZakAudit *zak_audit, * * Returns: the #GtkWidget. */ -GtkWidget -*zak_audit_get_changes_widget (ZakAudit *zak_audit, - const gchar *datasource_name, - const gchar *table_name, - const gchar **key_values) +GdaDataModel +*zak_audit_get_changes_datamodel (ZakAudit *zak_audit, + const gchar *datasource_name, + const gchar *table_name, + const gchar **key_values) { - GError *error; - - GtkWidget *ret; + GdaDataModel *ret; ZakAuditDatasource *datasource; ZakAuditTable *table; @@ -1791,22 +1783,13 @@ GtkWidget guint row; guint rows; - ChangesColumn *column; - GHashTable *ht_columns; gchar *sql; GString *sql_where; GString *sql_where_record; GdaDataModel *dm; GdaDataModel *dm_tmp; - - GtkWidget *wgrid; - GdaExGrid *gdaexgrid; - GdaExGridColumn *gdaexgridcolumn; - GtkTreeStore *tstore; - - GtkTreeIter iter; - GtkTreeIter *iter_prev; + GdaDataModelArray *dm_values; guint row_action; guint rows_action; @@ -1814,6 +1797,8 @@ GtkWidget guint col; guint cols; + GType *gtypes; + ZakAuditPrivate *priv = ZAK_AUDIT_GET_PRIVATE (zak_audit); datasource = get_datasource_from_name (zak_audit, datasource_name); @@ -1838,16 +1823,6 @@ GtkWidget return NULL; } - ht_columns = g_hash_table_new (g_str_hash, g_str_equal); - - error = NULL; - gtk_builder_add_objects_from_file (priv->gtkbuilder, priv->guifile, - g_strsplit ("w_changes", - "|", -1), - &error); - - ret = GTK_WIDGET (gtk_builder_get_object (priv->gtkbuilder, "w_changes")); - sql_where = g_string_new (""); sql_where_record = g_string_new (""); @@ -1877,8 +1852,6 @@ GtkWidget strtol (field_value, NULL, 10)); } - gdaexgrid = gdaex_grid_new (); - sql = g_strdup_printf ("SELECT *" " FROM fields" " WHERE id_tables = %d" @@ -1889,37 +1862,32 @@ GtkWidget { rows = gda_data_model_get_n_rows (dm); - gdaexgridcolumn = gdaex_grid_column_new (_("ID"), "id", G_TYPE_INT, TRUE, TRUE, TRUE, TRUE, -1); - gdaex_grid_add_column (gdaexgrid, gdaexgridcolumn); - - gdaexgridcolumn = gdaex_grid_column_new_defaults (_("Date"), "date", G_TYPE_STRING); - gdaex_grid_add_column (gdaexgrid, gdaexgridcolumn); - - gdaexgridcolumn = gdaex_grid_column_new_defaults (_("Operation"), NULL, G_TYPE_STRING); - gdaex_grid_add_column (gdaexgrid, gdaexgridcolumn); - - gdaexgridcolumn = gdaex_grid_column_new_defaults (_("User"), NULL, G_TYPE_STRING); - gdaex_grid_add_column (gdaexgrid, gdaexgridcolumn); + gtypes = g_new0 (GType, CHANGES_STATIC_COLUMNS + rows); + gtypes[COL_CHANGES_ID] = G_TYPE_STRING; + gtypes[COL_CHANGES_DATE] = G_TYPE_STRING; + gtypes[COL_CHANGES_ID_OPERATION] = G_TYPE_STRING; + gtypes[COL_CHANGES_OPERATION] = G_TYPE_STRING; + gtypes[COL_CHANGES_USER] = G_TYPE_STRING; for (row = 0; row < rows; row++) { - column = g_new0 (ChangesColumn, 1); - column->col = CHANGES_STATIC_COLUMNS + row; - column->field_name = gdaex_data_model_get_field_value_stringify_at (dm, row, "name"); - - /* TODO to ask - * column->field_long_name = - */ + gtypes[CHANGES_STATIC_COLUMNS + row] = G_TYPE_STRING; + } - /* TODO find the last value in database - * column->field_value = - */ + ret = gda_data_model_array_new_with_g_types_v (CHANGES_STATIC_COLUMNS + rows, gtypes); - gdaexgridcolumn = gdaex_grid_column_new_defaults (column->field_name, NULL, G_TYPE_STRING); - gdaex_grid_add_column (gdaexgrid, gdaexgridcolumn); + gda_data_model_set_column_name (ret, COL_CHANGES_ID, "zak_audit_action_id"); + gda_data_model_set_column_name (ret, COL_CHANGES_DATE, "zak_audit_action_date"); + gda_data_model_set_column_name (ret, COL_CHANGES_ID_OPERATION, "zak_audit_action_id_operation"); + gda_data_model_set_column_name (ret, COL_CHANGES_OPERATION, "zak_audit_action_operation"); + gda_data_model_set_column_name (ret, COL_CHANGES_USER, "zak_audit_action_user"); - g_hash_table_insert (ht_columns, (gpointer)column->field_name, (gpointer)column); + for (row = 0; row < rows; row++) + { + gda_data_model_set_column_name (ret, CHANGES_STATIC_COLUMNS + row, gdaex_data_model_get_field_value_stringify_at (dm, row, "name")); } + + dm_values = gda_data_model_array_copy_model (ret, NULL); } else { @@ -1935,16 +1903,9 @@ GtkWidget g_object_unref (dm); } - wgrid = gdaex_grid_get_widget (gdaexgrid); - gtk_container_add (GTK_CONTAINER (gtk_builder_get_object (priv->gtkbuilder, "scrolledwindow1")), wgrid); - gtk_widget_show (wgrid); - tstore = GTK_TREE_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (wgrid))); - /* find the last action * go backward */ - iter_prev = NULL; - sql = g_strdup_printf ("SELECT a.id, a.type, a.username, a.date," " v.value" " FROM actions AS a" @@ -1963,25 +1924,12 @@ GtkWidget { rows_action = gda_data_model_get_n_rows (dm); - for (row_action = 0; row_action < rows_action; row_action++) + if (rows_action > 0) { - /* TODO check if key field value is changed */ - - /* TODO i could find field that there's not in columns (the dm passed) */ + gda_data_model_append_row (GDA_DATA_MODEL (dm_values), NULL); - if (gdaex_data_model_get_field_value_integer_at (dm, row_action, "type") == ZAK_AUDIT_ACTION_DELETE) + if (gdaex_data_model_get_field_value_integer_at (dm, 0, "type") == ZAK_AUDIT_ACTION_DELETE) { - gtk_tree_store_append (tstore, &iter, NULL); - gtk_tree_store_set (tstore, &iter, - COL_CHANGES_ID, gdaex_data_model_get_field_value_integer_at (dm, row_action, "id"), - COL_CHANGES_DATE, g_strdup_printf ("%s.%d", g_date_time_format (gdaex_data_model_get_field_value_gdatetime_at (dm, row_action, "date"), "%d/%m/%Y %H.%M.%S"), - gdaex_data_model_get_field_value_gdatimestamp_at (dm, row_action, "date")->fraction), - COL_CHANGES_OPERATION, _("Deleted"), - COL_CHANGES_USER, gdaex_data_model_get_field_value_stringify_at (dm, row_action, "username"), - -1); - - gtk_tree_store_append (tstore, &iter, NULL); - /* last values are stored in zakaudit tables */ sql = g_strdup_printf ("SELECT v.*, f.name" " FROM values AS v" @@ -1995,89 +1943,92 @@ GtkWidget rows = gda_data_model_get_n_rows (dm_tmp); for (row = 0; row < rows; row++) { - column = (ChangesColumn *)g_hash_table_lookup (ht_columns, gdaex_data_model_get_field_value_stringify_at (dm_tmp, row, "name")); - if (column != NULL) - { - column->field_value = gdaex_data_model_get_field_value_stringify_at (dm_tmp, row, "value"); - gtk_tree_store_set (tstore, &iter, - column->col, column->field_value, - -1); - } + gda_data_model_set_value_at (GDA_DATA_MODEL (dm_values), + gda_data_model_get_column_index (GDA_DATA_MODEL (dm_values), gdaex_data_model_get_field_value_stringify_at (dm_tmp, row, "name")), + 0, + gda_data_model_get_value_at (dm_tmp, gda_data_model_get_column_index (dm_tmp, "value"), row, NULL), + NULL); } g_object_unref (dm_tmp); } - - iter_prev = &iter; } - else if (gdaex_data_model_get_field_value_integer_at (dm, row_action, "type") == ZAK_AUDIT_ACTION_AFTER_UPDATE - || gdaex_data_model_get_field_value_integer_at (dm, row_action, "type") == ZAK_AUDIT_ACTION_INSERT) + else { - if (iter_prev != NULL) - { - iter = *iter_prev; - } - else + /* last values are stored in datasource audited */ + sql = g_strdup_printf ("SELECT *" + " FROM %s" + " WHERE %s", + table->name, + sql_where_record->str + 5); + dm_tmp = gdaex_query (datasource->gdaex, sql); + g_free (sql); + if (dm_tmp != NULL) { - gtk_tree_store_append (tstore, &iter, NULL); - - /* last values are stored in datasource audited */ - sql = g_strdup_printf ("SELECT *" - " FROM %s" - " WHERE %s", - table->name, - sql_where_record->str + 5); - dm_tmp = gdaex_query (datasource->gdaex, sql); - g_free (sql); - if (dm_tmp != NULL) + cols = gda_data_model_get_n_columns (dm_tmp); + for (col = 0; col < cols; col++) { - cols = gda_data_model_get_n_columns (dm_tmp); - for (col = 0; col < cols; col++) - { - column = (ChangesColumn *)g_hash_table_lookup (ht_columns, gda_data_model_get_column_name (dm_tmp, col)); - if (column != NULL) - { - column->field_value = gdaex_data_model_get_value_stringify_at (dm_tmp, 0, col); - gtk_tree_store_set (tstore, &iter, - column->col, column->field_value, - -1); - } - } - g_object_unref (dm_tmp); + gda_data_model_set_value_at (GDA_DATA_MODEL (dm_values), + gda_data_model_get_column_index (GDA_DATA_MODEL (dm_values), gda_data_model_get_column_name (dm_tmp, col)), + 0, + gda_data_model_get_value_at (dm_tmp, gda_data_model_get_column_index (dm_tmp, "value"), 0, NULL), NULL); } + g_object_unref (dm_tmp); } + } + } - gtk_tree_store_set (tstore, &iter, - COL_CHANGES_ID, gdaex_data_model_get_field_value_integer_at (dm, row_action, "id"), - COL_CHANGES_DATE, g_strdup_printf ("%s.%d", g_date_time_format (gdaex_data_model_get_field_value_gdatetime_at (dm, row_action, "date"), "%d/%m/%Y %H.%M.%S"), - gdaex_data_model_get_field_value_gdatimestamp_at (dm, row_action, "date")->fraction), - COL_CHANGES_OPERATION, gdaex_data_model_get_field_value_integer_at (dm, row_action, "type") == ZAK_AUDIT_ACTION_AFTER_UPDATE ? _("Edited") : - gdaex_data_model_get_field_value_integer_at (dm, row_action, "type") == ZAK_AUDIT_ACTION_INSERT ? _("Inserted") : _("not valid"), - COL_CHANGES_USER, gdaex_data_model_get_field_value_stringify_at (dm, row_action, "username"), - -1); - - iter_prev = g_memdup (&iter, sizeof (GtkTreeIter)); - - if (row_action == rows_action - 1) - { - continue; - } - - gtk_tree_store_append (tstore, &iter, NULL); + for (row_action = 0; row_action < rows_action; row_action++) + { + /* TODO check if key field value is changed */ - /* copy iter_prev to iter */ - gchar *field_value; + /* TODO i could find field that there's not in columns (the dm passed) */ - for (col = 0; col < g_list_length (table->fields); col++) - { - gtk_tree_model_get (GTK_TREE_MODEL (tstore), iter_prev, - col + CHANGES_STATIC_COLUMNS, &field_value, - -1); - gtk_tree_store_set (tstore, &iter, - col + CHANGES_STATIC_COLUMNS, field_value, - -1); - } + gda_data_model_append_row (ret, NULL); + + gda_data_model_set_value_at (ret, + gda_data_model_get_column_index (ret, "zak_audit_action_id"), + row_action, + zak_utils_gvalue_new_string (g_strdup_printf ("%d", gdaex_data_model_get_field_value_integer_at (dm, row_action, "id"))), + NULL); + gda_data_model_set_value_at (ret, + gda_data_model_get_column_index (ret, "zak_audit_action_date"), + row_action, + zak_utils_gvalue_new_string (g_strdup_printf ("%s.%d", g_date_time_format (gdaex_data_model_get_field_value_gdatetime_at (dm, row_action, "date"), "%d/%m/%Y %H.%M.%S"), + gdaex_data_model_get_field_value_gdatimestamp_at (dm, row_action, "date")->fraction)), + NULL); + gda_data_model_set_value_at (ret, + gda_data_model_get_column_index (ret, "zak_audit_action_id_operation"), + row_action, + zak_utils_gvalue_new_string (g_strdup_printf ("%d", gdaex_data_model_get_field_value_integer_at (dm, row_action, "type"))), + NULL); + gda_data_model_set_value_at (ret, + gda_data_model_get_column_index (ret, "zak_audit_action_operation"), + row_action, + zak_utils_gvalue_new_string (gdaex_data_model_get_field_value_integer_at (dm, row_action, "type") == ZAK_AUDIT_ACTION_AFTER_UPDATE ? _("Edited") : + gdaex_data_model_get_field_value_integer_at (dm, row_action, "type") == ZAK_AUDIT_ACTION_INSERT ? _("Inserted") : + gdaex_data_model_get_field_value_integer_at (dm, row_action, "type") == ZAK_AUDIT_ACTION_DELETE ? _("Deleted") : _("not valid")), + NULL); + gda_data_model_set_value_at (ret, + gda_data_model_get_column_index (ret, "zak_audit_action_user"), + row_action, + zak_utils_gvalue_new_string (g_strdup (gdaex_data_model_get_field_value_stringify_at (dm, row_action, "username"))), + NULL); + + /* copy starting values */ + cols = gda_data_model_get_n_columns (GDA_DATA_MODEL (dm_values)); + for (col = CHANGES_STATIC_COLUMNS; col < cols; col++) + { + gda_data_model_set_value_at (ret, + col, + row_action, + gda_data_model_get_value_at (GDA_DATA_MODEL (dm_values), col, 0, NULL), + NULL); + } - /* changing edited values/columns */ + if (gdaex_data_model_get_field_value_integer_at (dm, row_action, "type") == ZAK_AUDIT_ACTION_AFTER_UPDATE + || gdaex_data_model_get_field_value_integer_at (dm, row_action, "type") == ZAK_AUDIT_ACTION_INSERT) + { + /* changing edited values/columns in starting values data model */ sql = g_strdup_printf ("SELECT v.*, f.name, f.is_key" " FROM values AS v" " INNER JOIN fields AS f ON v.id_fields = f.id" @@ -2090,39 +2041,41 @@ GtkWidget rows = gda_data_model_get_n_rows (dm_tmp); for (row = 0; row < rows; row++) { - column = (ChangesColumn *)g_hash_table_lookup (ht_columns, gdaex_data_model_get_field_value_stringify_at (dm_tmp, row, "name")); - if (column != NULL) + GValue *value; + + if (gdaex_data_model_get_field_value_boolean_at (dm_tmp, row, "is_key")) { - if (gdaex_data_model_get_field_value_boolean_at (dm_tmp, row, "is_key")) + gchar **split; + + split = g_strsplit (gdaex_data_model_get_field_value_stringify_at (dm_tmp, row, "value"), + "|", -1); + if (g_strv_length (split) > 1) { - gchar **split; - - split = g_strsplit (gdaex_data_model_get_field_value_stringify_at (dm_tmp, row, "value"), - "|", -1); - if (g_strv_length (split) > 1) - { - column->field_value = g_strdup (split[1]); - } - else - { - column->field_value = g_strdup (split[0]); - } - - g_strfreev (split); + value = zak_utils_gvalue_new_string (g_strdup (split[1])); } else { - column->field_value = gdaex_data_model_get_field_value_stringify_at (dm_tmp, row, "value"); + value = zak_utils_gvalue_new_string (g_strdup (split[0])); } - gtk_tree_store_set (tstore, &iter, - column->col, column->field_value, - -1); + + g_strfreev (split); } + else + { + value = gda_data_model_get_value_at (dm_tmp, + gda_data_model_get_column_index (dm_tmp, "value"), + row, + NULL); + } + + gda_data_model_set_value_at (GDA_DATA_MODEL (dm_values), + gda_data_model_get_column_index (GDA_DATA_MODEL (dm_values), gdaex_data_model_get_field_value_stringify_at (dm_tmp, row, "name")), + 0, + value, + NULL); } g_object_unref (dm_tmp); } - - iter_prev = g_memdup (&iter, sizeof (GtkTreeIter)); } } } @@ -2134,6 +2087,130 @@ GtkWidget return ret; } +/** + * zak_audit_get_changes_widget: + * @zak_audit: an #ZakAudit object. + * @datasource_name: + * @table_name: + * @key_values: + * + * Returns: the #GtkWidget. + */ +GtkWidget +*zak_audit_get_changes_widget (ZakAudit *zak_audit, + const gchar *datasource_name, + const gchar *table_name, + const gchar **key_values) +{ + GError *error; + + GtkWidget *ret; + + GtkWidget *wgrid; + GdaExGrid *gdaexgrid; + GdaExGridColumn *gdaexgridcolumn; + + gchar *sql; + GdaDataModel *dm; + + guint row; + guint rows; + + ZakAuditDatasource *datasource; + ZakAuditTable *table; + + ZakAuditPrivate *priv = ZAK_AUDIT_GET_PRIVATE (zak_audit); + + datasource = get_datasource_from_name (zak_audit, datasource_name); + if (datasource == NULL) + { + g_warning (_("Unable to find the datasource «%s» on loaded datasources."), + datasource_name); + return NULL; + } + + table = get_table_from_name (zak_audit, datasource, table_name); + if (table == NULL) + { + g_warning (_("Unable to find the table «%s» on loaded datasources."), + table_name); + return NULL; + } + + error = NULL; + gtk_builder_add_objects_from_file (priv->gtkbuilder, priv->guifile, + g_strsplit ("w_changes", + "|", -1), + &error); + + ret = GTK_WIDGET (gtk_builder_get_object (priv->gtkbuilder, "w_changes")); + + gdaexgrid = gdaex_grid_new (); + + gdaexgridcolumn = gdaex_grid_column_new_defaults (_("ID"), "zak_audit_action_id", G_TYPE_STRING); + gdaex_grid_add_column (gdaexgrid, gdaexgridcolumn); + + gdaexgridcolumn = gdaex_grid_column_new_defaults (_("Date"), "zak_audit_action_date", G_TYPE_STRING); + gdaex_grid_add_column (gdaexgrid, gdaexgridcolumn); + + gdaexgridcolumn = gdaex_grid_column_new_defaults (_("ID operation"), "zak_audit_action_id_operation", G_TYPE_STRING); + gdaex_grid_add_column (gdaexgrid, gdaexgridcolumn); + + gdaexgridcolumn = gdaex_grid_column_new_defaults (_("Operation"), "zak_audit_action_operation", G_TYPE_STRING); + gdaex_grid_add_column (gdaexgrid, gdaexgridcolumn); + + gdaexgridcolumn = gdaex_grid_column_new_defaults (_("User"), "zak_audit_action_user", G_TYPE_STRING); + gdaex_grid_add_column (gdaexgrid, gdaexgridcolumn); + + sql = g_strdup_printf ("SELECT *" + " FROM fields" + " WHERE id_tables = %d" + " ORDER BY id", + table->id); + dm = gdaex_query (priv->gdaex, sql); + if (dm != NULL && gda_data_model_get_n_rows (dm) > 0) + { + rows = gda_data_model_get_n_rows (dm); + + for (row = 0; row < rows; row++) + { + /* TODO to ask + * column->field_long_name = + */ + + /* TODO find the last value in database + * column->field_value = + */ + + gdaexgridcolumn = gdaex_grid_column_new_defaults (gdaex_data_model_get_field_value_stringify_at (dm, row, "name"), gdaex_data_model_get_field_value_stringify_at (dm, row, "name"), G_TYPE_STRING); + gdaex_grid_add_column (gdaexgrid, gdaexgridcolumn); + } + } + else + { + if (dm != NULL) + { + g_object_unref (dm); + } + g_warning (_("Fields not found for table <%s>."), table->name); + return NULL; + } + if (dm != NULL) + { + g_object_unref (dm); + } + + wgrid = gdaex_grid_get_widget (gdaexgrid); + gtk_container_add (GTK_CONTAINER (gtk_builder_get_object (priv->gtkbuilder, "scrolledwindow1")), wgrid); + gtk_widget_show (wgrid); + + dm = zak_audit_get_changes_datamodel (zak_audit, datasource_name, table_name, key_values); + + gdaex_grid_fill_from_datamodel (gdaexgrid, dm, NULL); + + return ret; +} + /** * zak_audit_get_user_insertion: * @zak_audit: an #ZakAudit object. diff --git a/src/libzakaudit.h b/src/libzakaudit.h index eabef8c..8a11741 100644 --- a/src/libzakaudit.h +++ b/src/libzakaudit.h @@ -1,7 +1,7 @@ /* * libzakaudit.h * - * Copyright (C) 2005-2019 Andrea Zagli + * Copyright (C) 2005-2020 Andrea Zagli * * This file is part of libzak_audit. * @@ -106,6 +106,11 @@ GtkWidget *zak_audit_get_changes_widget (ZakAudit *zak_audit, const gchar *table_name, const gchar **key_values); +GdaDataModel *zak_audit_get_changes_datamodel (ZakAudit *zak_audit, + const gchar *datasource_name, + const gchar *table_name, + const gchar **key_values); + const gchar *zak_audit_get_user_insertion (ZakAudit *zak_audit, const gchar *datasource_name, const gchar *table_name, -- 2.49.0