From 5fa0c1f6a614da653a49255f40abe1f87451e577 Mon Sep 17 00:00:00 2001 From: Andrea Zagli Date: Sun, 22 Apr 2018 12:18:27 +0200 Subject: [PATCH] Completed function ::get_changes_widget. --- src/audit.c | 238 +++++++++++++++++++++++++++++++++++++------------- tests/test1.c | 9 +- 2 files changed, 184 insertions(+), 63 deletions(-) diff --git a/src/audit.c b/src/audit.c index 71f9041..5d3cc04 100644 --- a/src/audit.c +++ b/src/audit.c @@ -1,10 +1,10 @@ /* * audit.c * - * Copyright (C) 2005-2015 Andrea Zagli + * Copyright (C) 2005-2018 Andrea Zagli * * This file is part of libzakaudit. - * + * * 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 @@ -306,7 +306,7 @@ load_fields (ZakAudit *zak_audit, field->name, NULL); if (field->is_key) { - table->keys = g_list_append (table->fields, (gpointer)field); + table->keys = g_list_append (table->keys, (gpointer)field); table->keys_sql = g_strconcat (table->keys_sql == NULL ? "" : g_strconcat (table->keys_sql, ", ", NULL), field->name, NULL); @@ -455,7 +455,11 @@ load_datasources (ZakAudit *zak_audit, va_list ap) datas->id, datas->name, datas->cnc_string);*/ datas->gdaex = gdaex_new_from_string (datas->cnc_string); - + if (datas->gdaex == NULL) + { + g_warning (_("Unable to open connection to «%s»."), datas->cnc_string); + } + priv->datasources = g_list_append (priv->datasources, (gpointer)datas); /* for each datasource must be loaded tables and fields */ @@ -1585,25 +1589,38 @@ GtkWidget gchar *sql; GString *sql_where; + GString *sql_where_record; GdaDataModel *dm; + GdaDataModel *dm_tmp; GtkTreeView *tview; GtkCellRenderer *renderer; GtkTreeViewColumn *vcolumn; GtkListStore *lstore; GtkTreeIter iter; + GtkTreeIter *iter_prev; + + guint row_action; + guint rows_action; + + guint col; + guint cols; 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; } @@ -1624,6 +1641,7 @@ GtkWidget ret = GTK_WIDGET (gtk_builder_get_object (priv->gtkbuilder, "w_changes")); sql_where = g_string_new (""); + sql_where_record = g_string_new (""); for (strpart = 0; strpart < l; strpart++) { @@ -1638,11 +1656,17 @@ GtkWidget if (field_value == NULL) break; /* TODO the db field can be other type than string */ - g_string_append_printf (sql_where, " AND (v.id_fields = %d" + g_string_append_printf (sql_where, + " AND (v.id_fields = %d" " AND (v.value = '%s' OR v.value LIKE '%s|%%'))", field->id, field_value, field_value); + + g_string_append_printf (sql_where_record, + " AND %s = %d", + field_name, + strtol (field_value, NULL, 10)); } tview = GTK_TREE_VIEW (gtk_builder_get_object (priv->gtkbuilder, "treeview1")); @@ -1738,6 +1762,8 @@ GtkWidget /* 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" @@ -1746,8 +1772,7 @@ GtkWidget " WHERE a.id_tables = %d" "%s" " AND f.is_key = TRUE" - " ORDER BY a.id DESC" - " LIMIT 1", + " ORDER BY a.id DESC", table->id, sql_where->str); @@ -1755,71 +1780,166 @@ GtkWidget g_free (sql); if (dm != NULL && gda_data_model_get_n_rows (dm) > 0) { - gtk_list_store_append (lstore, &iter); - gtk_list_store_set (lstore, &iter, - COL_CHANGES_ID, gdaex_data_model_get_field_value_integer_at (dm, 0, "id"), - COL_CHANGES_DATE, g_date_time_format (gdaex_data_model_get_field_value_gdatetime_at (dm, 0, "date"), "%d/%m/%Y %H.%M.%S"), - COL_CHANGES_OPERATION, gdaex_data_model_get_field_value_integer_at (dm, 0, "type") == ZAK_AUDIT_ACTION_DELETE ? "Delete" : - gdaex_data_model_get_field_value_integer_at (dm, 0, "type") == ZAK_AUDIT_ACTION_AFTER_UPDATE ? "Edit" : - gdaex_data_model_get_field_value_integer_at (dm, 0, "type") == ZAK_AUDIT_ACTION_INSERT ? "Insert" : "non valid", - COL_CHANGES_USER, gdaex_data_model_get_field_value_stringify_at (dm, 0, "username"), - -1); + rows_action = gda_data_model_get_n_rows (dm); - /* TODO check if key field value is changed */ + for (row_action = 0; row_action < rows_action; row_action++) + { + /* TODO check if key field value is changed */ - /* TODO i could find field that there's not in columns (the dm passed) */ + /* TODO i could find field that there's not in columns (the dm passed) */ - if (gdaex_data_model_get_field_value_integer_at (dm, 0, "type") == ZAK_AUDIT_ACTION_DELETE) - { - /* last values are stored in zakaudit tables */ - sql = g_strdup_printf ("SELECT v.*, f.name" - " FROM values AS v" - " INNER JOIN fields AS f ON v.id_fields = f.id" - " WHERE v.id_actions = %d", - gdaex_data_model_get_field_value_integer_at (dm, 0, "id")); - dm = gdaex_query (priv->gdaex, sql); - g_free (sql); - if (dm != NULL) + if (gdaex_data_model_get_field_value_integer_at (dm, row_action, "type") == ZAK_AUDIT_ACTION_DELETE) { - rows = gda_data_model_get_n_rows (dm); - for (row = 0; row < rows; row++) + gtk_list_store_append (lstore, &iter); + gtk_list_store_set (lstore, &iter, + COL_CHANGES_ID, gdaex_data_model_get_field_value_integer_at (dm, row_action, "id"), + COL_CHANGES_DATE, g_date_time_format (gdaex_data_model_get_field_value_gdatetime_at (dm, row_action, "date"), "%d/%m/%Y %H.%M.%S"), + COL_CHANGES_OPERATION, _("Deleted"), + COL_CHANGES_USER, gdaex_data_model_get_field_value_stringify_at (dm, row_action, "username"), + -1); + + gtk_list_store_append (lstore, &iter); + + /* last values are stored in zakaudit tables */ + sql = g_strdup_printf ("SELECT v.*, f.name" + " FROM values AS v" + " INNER JOIN fields AS f ON v.id_fields = f.id" + " WHERE v.id_actions = %d", + gdaex_data_model_get_field_value_integer_at (dm, row_action, "id")); + dm_tmp = gdaex_query (priv->gdaex, sql); + g_free (sql); + if (dm_tmp != NULL) { - column = (ChangesColumn *)g_hash_table_lookup (ht_columns, gdaex_data_model_get_field_value_stringify_at (dm, row, "name")); - if (column != NULL) + rows = gda_data_model_get_n_rows (dm_tmp); + for (row = 0; row < rows; row++) { - column->field_value = gdaex_data_model_get_field_value_stringify_at (dm, row, "value"); - gtk_list_store_set (lstore, &iter, - column->col, column->field_value, - -1); + 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_list_store_set (lstore, &iter, + column->col, column->field_value, + -1); + } } + g_object_unref (dm_tmp); } + + iter_prev = &iter; } - } - else if (gdaex_data_model_get_field_value_integer_at (dm, 0, "type") == ZAK_AUDIT_ACTION_AFTER_UPDATE - || gdaex_data_model_get_field_value_integer_at (dm, 0, "type") == ZAK_AUDIT_ACTION_INSERT) - { - /* last values are stored in datasource audited */ - sql = g_strdup_printf ("SELECT *" - " FROM %s" - " WHERE %s", - table->name, - sql_where->str + 5); - dm = gdaex_query (datasource->gdaex, sql); - g_free (sql); - if (dm != NULL) + 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) { - rows = gda_data_model_get_n_columns (dm); - for (row = 0; row < rows; row++) + if (iter_prev != NULL) { - column = (ChangesColumn *)g_hash_table_lookup (ht_columns, gda_data_model_get_column_name (dm, row)); - if (column != NULL) + iter = *iter_prev; + } + else + { + gtk_list_store_append (lstore, &iter); + + /* 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) { - column->field_value = gdaex_data_model_get_value_stringify_at (dm, 0, row); - gtk_list_store_set (lstore, &iter, - column->col, column->field_value, - -1); + 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_list_store_set (lstore, &iter, + column->col, column->field_value, + -1); + } + } + g_object_unref (dm_tmp); } } + + gtk_list_store_set (lstore, &iter, + COL_CHANGES_ID, gdaex_data_model_get_field_value_integer_at (dm, row_action, "id"), + COL_CHANGES_DATE, g_date_time_format (gdaex_data_model_get_field_value_gdatetime_at (dm, row_action, "date"), "%d/%m/%Y %H.%M.%S"), + 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_list_store_append (lstore, &iter); + + /* copy iter_prev to iter */ + gchar *field_value; + + for (col = 0; col < g_list_length (table->fields); col++) + { + gtk_tree_model_get (GTK_TREE_MODEL (lstore), iter_prev, + col + CHANGES_STATIC_COLUMNS, &field_value, + -1); + gtk_list_store_set (lstore, &iter, + col + CHANGES_STATIC_COLUMNS, field_value, + -1); + } + + /* changing edited values/columns */ + 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" + " WHERE v.id_actions = %d", + gdaex_data_model_get_field_value_integer_at (dm, row_action, "id")); + dm_tmp = gdaex_query (priv->gdaex, sql); + g_free (sql); + if (dm_tmp != NULL) + { + 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) + { + 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) + { + column->field_value = g_strdup (split[1]); + } + else + { + column->field_value = g_strdup (split[0]); + } + + g_strfreev (split); + } + else + { + column->field_value = gdaex_data_model_get_field_value_stringify_at (dm_tmp, row, "value"); + } + gtk_list_store_set (lstore, &iter, + column->col, column->field_value, + -1); + } + } + g_object_unref (dm_tmp); + } + + iter_prev = g_memdup (&iter, sizeof (GtkTreeIter)); } } } @@ -1828,8 +1948,6 @@ GtkWidget g_object_unref (dm); } - g_warning (_("The function is still to be implemented")); - return ret; } diff --git a/tests/test1.c b/tests/test1.c index d43a923..c6ddcbe 100644 --- a/tests/test1.c +++ b/tests/test1.c @@ -4,7 +4,7 @@ * Copyright (C) 2005-2015 Andrea Zagli * * This file is part of libzakaudit. - * + * * 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 @@ -27,7 +27,7 @@ static gchar *cnc_zakaudit; static gchar *cnc_db; -static GOptionEntry entries[] = +static GOptionEntry entries[] = { { "cnc_string_zakaudit", 0, 0, G_OPTION_ARG_STRING, &cnc_zakaudit, "Connection string to zakaudit database", NULL }, { "cnc_string_db", 0, 0, G_OPTION_ARG_STRING, &cnc_db, "Connection string to test database", NULL }, @@ -152,10 +152,13 @@ main (int argc, char *argv[]) zak_audit_action_from_where (audit, ZAK_AUDIT_ACTION_DELETE, "I", "audit_test1", "test1", "id IN (3, 4)"); gdaex_execute (gdaex, "DELETE FROM test1 WHERE id IN (3, 4)"); + gdaex_execute (gdaex, "INSERT INTO test1 VALUES (5, 'Only inserted', 13, 1234.33)"); + zak_audit_action_from_where (audit, ZAK_AUDIT_ACTION_INSERT, "I", "audit_test1", "test1", "id = 5"); + g_warning ("User insertion: %s", zak_audit_get_user_insertion (audit, "audit_test1", "test1", (const gchar **)g_strsplit ("id|2", "|", -1))); - w = zak_audit_get_changes_widget (audit, "audit_test1", "test1", (const gchar **)g_strsplit ("id|2", "|", -1)); + w = zak_audit_get_changes_widget (audit, "audit_test1", "test1", (const gchar **)g_strsplit ("id|5", "|", -1)); g_signal_connect (w, "delete-event", G_CALLBACK (on_w_delete_event), NULL); g_signal_connect (w, "destroy", gtk_main_quit, NULL); -- 2.49.0