CREATE TABLE datasources (
id integer NOT NULL,
- name character varying(30) DEFAULT '',
+ name character varying(50) DEFAULT '',
cnc_string character varying(255) DEFAULT '',
status character varying(1) DEFAULT '',
CONSTRAINT datasources_pkey PRIMARY KEY (id)
CREATE TABLE tables (
id integer NOT NULL,
- name character varying(30) DEFAULT '',
+ name character varying(50) DEFAULT '',
status character varying(1) DEFAULT '',
id_datasources integer NOT NULL,
CONSTRAINT tables_pkey PRIMARY KEY (id)
CREATE TABLE fields (
id integer NOT NULL,
id_tables integer NOT NULL,
- name character varying(30) DEFAULT '',
+ name character varying(50) DEFAULT '',
+ is_key boolean DEFAULT false,
status character varying(1) DEFAULT '',
CONSTRAINT fields_pkey PRIMARY KEY (id)
);
);
CREATE TABLE values (
- id bigint NOT NULL,
id_actions bigint NOT NULL,
id_fields integer NOT NULL,
value character varying DEFAULT '',
- CONSTRAINT valori_pkey PRIMARY KEY (id)
+ CONSTRAINT values_pkey PRIMARY KEY (id_actions, id_fields)
);
{
gint id;
gchar *name;
+ gboolean is_key;
} Field;
typedef struct
gint id;
gchar *name;
GList *fields;
+ gchar *fields_sql;
+ GList *keys;
+ gchar *keys_sql;
} Table;
typedef struct
return FALSE;
}
- sql = g_strdup_printf ("SELECT id, name FROM fields"
+ sql = g_strdup_printf ("SELECT id, name, is_key FROM fields"
" WHERE status <> 'D' AND id_tables = %d",
table->id);
dm = gdaex_query (priv->gdaex, sql);
cam->id = gdaex_data_model_get_field_value_integer_at (dm, row, "id");
cam->name = gdaex_data_model_get_field_value_stringify_at (dm, row, "name");
+ cam->is_key = gdaex_data_model_get_field_value_boolean_at (dm, row, "is_key");
if (gda_data_model_get_column_index (dm_table, cam->name) < 0)
{
}
table->fields = g_list_append (table->fields, (gpointer)cam);
+ table->fields_sql = g_strconcat (table->fields_sql == NULL ? "" :
+ g_strconcat (table->fields_sql, ", ", NULL),
+ cam->name, NULL);
+ if (cam->is_key)
+ {
+ table->keys = g_list_append (table->fields, (gpointer)cam);
+ table->keys_sql = g_strconcat (table->keys_sql == NULL ? "" :
+ g_strconcat (table->keys_sql, ", ", NULL),
+ cam->name, NULL);
+ }
+ }
+
+ if (table->keys == NULL)
+ {
+ g_warning ("No key's fields defined for table «%s».",
+ table->name);
+ return FALSE;
}
return TRUE;
/* for each table must be loaded fields */
tab->fields = NULL;
+ tab->fields_sql = NULL;
+ tab->keys = NULL;
+ tab->keys_sql = NULL;
if (!load_fields (audit, datasource, tab))
{
return FALSE;
* @username: the username that make the action.
* @datasource_name: the datasource's name.
* @table_name: the table's name.
- * @...: a #NULL terminated list of couples field-value.
+ * @...: a #NULL terminated list of couples field-value, that represent the WHERE part.
*
* Returns: #TRUE on success.
*/
return ret;
}
+static gchar
+*normalize_fields_list (const gchar *fields_list)
+{
+ gchar *ret;
+
+ gchar **fields;
+ guint i;
+ guint r;
+ guint n_fields;
+
+ ret = g_strdup ("");
+ fields = g_strsplit (fields_list, ", ", 0);
+
+ n_fields = g_strv_length (fields);
+ for (i = 0; i < n_fields; i++)
+ {
+ if (i == 0)
+ {
+ ret = g_strconcat (ret, fields[i], NULL);
+ }
+ else
+ {
+ if (g_strrstr_len (ret, strlen (fields[i]), fields[i]) == NULL)
+ {
+ ret = g_strconcat (ret, ", ", fields[i], NULL);
+ }
+ }
+ }
+
+ return ret;
+}
+
/**
* audit_action_v:
* @audit: an #Audit object.
switch (action)
{
case AUDIT_ACTION_INSERT:
- /* TODO for now it saves all the fields passed */
- /* saving just key's fields */
+ sql = g_strdup_printf ("SELECT %s FROM %s",
+ table->keys_sql,
+ table->name);
+
+ sql_where = g_strdup (" WHERE TRUE");
for (strpart = 0; strpart < l; strpart++)
{
field_name = (gchar *)fields_values[strpart];
value = (gchar *)fields_values[++strpart];
if (value == NULL) break;
- insert_value (audit, id, table, field_name, value);
+ /* TODO the db field can be other type than string */
+ sql_where = g_strconcat (sql_where, " AND ", field_name, " = ", value, "", NULL);
+ }
+
+ sql = g_strconcat (sql, sql_where, NULL);
+ dm = gdaex_query (datasource->gdaex, sql);
+
+ if (dm == NULL) return FALSE;
+
+ if (gda_data_model_get_n_rows (dm) == 0 ||
+ gda_data_model_get_n_rows (dm) > 1) return FALSE;
+
+ cols = gda_data_model_get_n_columns (dm);
+ for (col = 0; col < cols; col++)
+ {
+ /* find the field */
+ field_name = (gchar *)gda_data_model_get_column_title (dm, col);
+ insert_value (audit, id, table, field_name,
+ gdaex_data_model_get_value_stringify_at (dm, 0, col));
}
break;
case AUDIT_ACTION_BEFORE_UPDATE:
- /* storing the whole table to be changed */
- sql = g_strdup_printf ("SELECT * FROM %s",
- table_name);
+ if (priv->fields_updated != NULL)
+ {
+ g_hash_table_destroy (priv->fields_updated);
+ priv->fields_updated = NULL;
+ }
+
+ sql = g_strdup_printf ("SELECT %s FROM %s",
+ normalize_fields_list ((const gchar *)g_strconcat (table->keys_sql, ", ", table->fields_sql, NULL)),
+ table->name);
sql_where = g_strdup (" WHERE TRUE");
for (strpart = 0; strpart < l; strpart++)
if (gda_data_model_get_n_rows (dm) == 0 ||
gda_data_model_get_n_rows (dm) > 1) return FALSE;
- priv->fields_updated = g_hash_table_new (g_str_hash, g_str_equal);
+ priv->fields_updated = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
cols = gda_data_model_get_n_columns (dm);
for (col = 0; col < cols; col++)
{
break;
case AUDIT_ACTION_AFTER_UPDATE:
- /* saving changed fields */
- sql = g_strdup_printf ("SELECT * FROM %s",
- table_name);
+ if (priv->fields_updated == NULL)
+ {
+ g_warning ("You must call before an action of type AUDIT_ACTION_AFTER_UPDATE.");
+ return FALSE;
+ }
+
+ /* saving changed fields and the key */
+ sql = g_strdup_printf ("SELECT %s FROM %s",
+ normalize_fields_list ((const gchar *)g_strconcat (table->keys_sql, ", ", table->fields_sql, NULL)),
+ table->name);
sql_where = g_strdup (" WHERE TRUE");
for (strpart = 0; strpart < l; strpart++)
value = (gchar *)g_hash_table_lookup (priv->fields_updated, (gconstpointer)field_name);
value_new = gdaex_data_model_get_value_stringify_at (dm, 0, col);
- if (g_strcmp0 (value, value_new) != 0)
+ if ((get_field_from_name (audit, table, (const gchar *)field_name))->is_key)
+ {
+ /* the key is always saved with old and new values */
+ insert_value (audit, id, table, field_name, g_strconcat (value, "|", value_new, NULL));
+ }
+ else if (g_strcmp0 (value, value_new) != 0)
{
/* field changed: must be saved the old value */
insert_value (audit, id, table, field_name, value);
}
}
+
+ g_hash_table_destroy (priv->fields_updated);
+ priv->fields_updated = NULL;
break;
case AUDIT_ACTION_DELETE:
/* saving all fields */
- sql = g_strdup_printf ("SELECT * FROM %s",
- table_name);
+ sql = g_strdup_printf ("SELECT %s FROM %s",
+ table->fields_sql,
+ table->name);
sql_where = g_strdup (" WHERE TRUE");
for (strpart = 0; strpart < l; strpart++)