<interface>
<requires lib="gtk+" version="2.24"/>
<!-- interface-naming-policy project-wide -->
- <object class="GtkTreeStore" id="tstore_changes">
- <columns>
- <!-- column-name id_actions -->
- <column type="guint"/>
- <!-- column-name date -->
- <column type="gchararray"/>
- <!-- column-name type -->
- <column type="gchararray"/>
- <!-- column-name user -->
- <column type="gchararray"/>
- <!-- column-name field -->
- <column type="gchararray"/>
- <!-- column-name value -->
- <column type="gchararray"/>
- </columns>
- </object>
<object class="GtkWindow" id="w_changes">
<property name="can_focus">False</property>
<property name="modal">True</property>
<object class="GtkTreeView" id="treeview1">
<property name="visible">True</property>
<property name="can_focus">True</property>
- <property name="model">tstore_changes</property>
<property name="rules_hint">True</property>
- <child>
- <object class="GtkTreeViewColumn" id="treeviewcolumn5">
- <property name="title" translatable="yes">Date</property>
- <child>
- <object class="GtkCellRendererText" id="cellrenderertext5"/>
- <attributes>
- <attribute name="text">1</attribute>
- </attributes>
- </child>
- </object>
- </child>
- <child>
- <object class="GtkTreeViewColumn" id="treeviewcolumn1">
- <property name="title" translatable="yes">Type</property>
- <child>
- <object class="GtkCellRendererText" id="cellrenderertext1"/>
- <attributes>
- <attribute name="text">2</attribute>
- </attributes>
- </child>
- </object>
- </child>
- <child>
- <object class="GtkTreeViewColumn" id="treeviewcolumn2">
- <property name="title" translatable="yes">User</property>
- <child>
- <object class="GtkCellRendererText" id="cellrenderertext2"/>
- <attributes>
- <attribute name="text">3</attribute>
- </attributes>
- </child>
- </object>
- </child>
- <child>
- <object class="GtkTreeViewColumn" id="treeviewcolumn3">
- <property name="title" translatable="yes">Field</property>
- <child>
- <object class="GtkCellRendererText" id="cellrenderertext3"/>
- <attributes>
- <attribute name="text">4</attribute>
- </attributes>
- </child>
- </object>
- </child>
- <child>
- <object class="GtkTreeViewColumn" id="treeviewcolumn4">
- <property name="title" translatable="yes">Value</property>
- <child>
- <object class="GtkCellRendererText" id="cellrenderertext4"/>
- <attributes>
- <attribute name="text">5</attribute>
- </attributes>
- </child>
- </object>
- </child>
</object>
</child>
</object>
#include "libzakaudit.h"
+enum
+{
+ COL_CHANGES_ID,
+ COL_CHANGES_DATE,
+ 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
{
gint id;
if (action < 1)
{
g_warning ("Action %d not valid.", action);
- return;
+ return FALSE;
}
/* find the new action's id */
return ret;
}
-
/**
* zak_audit_get_changes_widget:
* @zak_audit: an #ZakAudit object.
gchar *field_name;
gchar *field_value;
+ guint row;
+ guint rows;
+ ChangesColumn *column;
+ GHashTable *ht_columns;
+ GType *gtype;
+
gchar *sql;
GString *sql_where;
GdaDataModel *dm;
- GtkTreeStore *tstore;
+ GtkTreeView *tview;
+ GtkCellRenderer *renderer;
+ GtkTreeViewColumn *vcolumn;
+ GtkListStore *lstore;
GtkTreeIter iter;
- GtkTreeIter iter_parent;
ZakAuditPrivate *priv = ZAK_AUDIT_GET_PRIVATE (zak_audit);
return NULL;
}
+ l = g_strv_length ((gchar **)key_values);
+ if (l == 0)
+ {
+ 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);
+
sql_where = g_string_new ("");
- l = g_strv_length ((gchar **)key_values);
for (strpart = 0; strpart < l; strpart++)
{
field_name = (gchar *)key_values[strpart];
field_value);
}
- sql = g_strdup_printf ("(SELECT a.id, a.type, a.username, a.date,"
- " v.value"
- " FROM actions AS a"
- " INNER JOIN values AS v ON a.id = v.id_actions"
- " INNER JOIN fields AS f ON v.id_fields = f.id"
- " WHERE a.type = %d"
- " AND a.id_tables = %d"
- "%s"
- " AND f.is_key = TRUE)"
- " UNION"
- " (SELECT a.id, a.type, a.username, a.date,"
- " v.value"
- " FROM actions AS a"
- " INNER JOIN values AS v ON a.id = v.id_actions"
- " INNER JOIN fields AS f ON v.id_fields = f.id"
- " WHERE a.type = %d"
- " AND a.id_tables = %d"
- "%s"
- " AND f.is_key = TRUE)"
- " UNION",
- " (SELECT a.id, a.type, a.username, a.date,"
+ tview = GTK_TREE_VIEW (gtk_builder_get_object (priv->gtkbuilder, "treeview1"));
+
+ sql = g_strdup_printf ("SELECT *"
+ " FROM fields"
+ " WHERE id_tables = %d",
+ 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);
+
+ gtype = g_new0 (GType, CHANGES_STATIC_COLUMNS + rows);
+
+ gtype[COL_CHANGES_ID] = G_TYPE_INT; /* id */
+ renderer = gtk_cell_renderer_spin_new ();
+ gtk_cell_renderer_set_alignment (renderer, 1.0, 0.5);
+ vcolumn = gtk_tree_view_column_new ();
+ gtk_tree_view_column_pack_start (vcolumn, renderer, TRUE);
+ gtk_tree_view_column_set_title (vcolumn, "ID");
+ gtk_tree_view_column_add_attribute (vcolumn, renderer, "text", COL_CHANGES_ID);
+
+ gtype[COL_CHANGES_DATE] = G_TYPE_STRING; /* date */
+ renderer = gtk_cell_renderer_text_new ();
+ vcolumn = gtk_tree_view_column_new ();
+ gtk_tree_view_column_pack_start (vcolumn, renderer, TRUE);
+ gtk_tree_view_column_set_title (vcolumn, "Date");
+ gtk_tree_view_column_add_attribute (vcolumn, renderer, "text", COL_CHANGES_DATE);
+
+ gtype[COL_CHANGES_OPERATION] = G_TYPE_STRING; /* type */
+ renderer = gtk_cell_renderer_text_new ();
+ vcolumn = gtk_tree_view_column_new ();
+ gtk_tree_view_column_pack_start (vcolumn, renderer, TRUE);
+ gtk_tree_view_column_set_title (vcolumn, "Operation");
+ gtk_tree_view_column_add_attribute (vcolumn, renderer, "text", COL_CHANGES_OPERATION);
+
+ gtype[COL_CHANGES_USER] = G_TYPE_STRING; /* username */
+ renderer = gtk_cell_renderer_text_new ();
+ vcolumn = gtk_tree_view_column_new ();
+ gtk_tree_view_column_pack_start (vcolumn, renderer, TRUE);
+ gtk_tree_view_column_set_title (vcolumn, "User");
+ gtk_tree_view_column_add_attribute (vcolumn, renderer, "text", COL_CHANGES_USER);
+
+ 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 =
+ */
+
+ /* TODO find the last value in database
+ * column->field_value =
+ */
+
+ g_hash_table_insert (ht_columns, (gpointer)column->field_name, (gpointer)column);
+
+ gtype[CHANGES_STATIC_COLUMNS + row] = G_TYPE_STRING;
+ }
+ }
+ 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);
+ }
+
+ lstore = GTK_TREE_STORE (gtk_list_store_newv (4 + rows, gtype));
+ gtk_tree_view_set_model (tview, GTK_TREE_MODEL (lstore));
+
+ /* find the last action
+ * go backward
+ */
+ sql = g_strdup_printf ("SELECT a.id, a.type, a.username, a.date,"
" v.value"
" FROM actions AS a"
" INNER JOIN values AS v ON a.id = v.id_actions"
" INNER JOIN fields AS f ON v.id_fields = f.id"
- " WHERE a.type = %d"
- " AND a.id_tables = %d"
+ " WHERE a.id_tables = %d"
"%s"
- " AND f.is_key = TRUE)",
- ZAK_AUDIT_ACTION_INSERT,
- table->id,
- sql_where->str,
- ZAK_AUDIT_ACTION_AFTER_UPDATE,
- table->id,
- sql_where->str,
- ZAK_AUDIT_ACTION_DELETE,
+ " AND f.is_key = TRUE"
+ " ORDER BY a.id DESC"
+ " LIMIT 1",
table->id,
sql_where->str);
g_free (sql);
if (dm != NULL && gda_data_model_get_n_rows (dm) > 0)
{
- error = NULL;
- gtk_builder_add_objects_from_file (priv->gtkbuilder, priv->guifile,
- g_strsplit ("tstore_changes"
- "|w_changes",
- "|", -1),
- &error);
-
- tstore = (GtkTreeStore *)gtk_builder_get_object (priv->gtkbuilder, "tstore_changes");
+ gtk_list_store_append (lstore, &iter);
+ gtk_list_store_set (lstore, &iter,
+ COL_CHANGES_ID, gdaex_data_model_get_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);
/* TODO check if key field value is changed */
+ /* 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"
+ " INNSER 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)
+ {
+ rows = gda_data_model_get_n_rows (dm);
+ for (row = 0; row < rows; row++)
+ {
+ column = (ChangesColumn *)g_hash_table_lookup (ht_columns, gdaex_data_model_get_field_value_stringify_at (dm, row, "name"));
+ if (column != NULL)
+ {
+ 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);
+ }
+ }
+ }
+ }
+ 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)
+ {
+ rows = gda_data_model_get_n_columns (dm);
+ for (row = 0; row < rows; row++)
+ {
+ column = (ChangesColumn *)g_hash_table_lookup (ht_columns, gda_data_model_get_column_name (dm, row));
+ if (column != 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);
+ }
+ }
+ }
+ }
}
if (dm != NULL)
{