From afc934ca10f5fda860aad361ddd441596c5d79da Mon Sep 17 00:00:00 2001 From: Andrea Zagli Date: Sun, 6 Jun 2010 11:12:42 +0200 Subject: [PATCH] Some adjustments and bugfixes. --- .gitignore | 1 + libaudit.pc.in | 2 +- src/audit.c | 243 ++++++++++++++++++++++++++++++------------------- 3 files changed, 149 insertions(+), 97 deletions(-) diff --git a/.gitignore b/.gitignore index 8bbe3ec..3ff7f11 100644 --- a/.gitignore +++ b/.gitignore @@ -31,3 +31,4 @@ docs/reference/xml *.la *.bak test1 +libaudit*tar* diff --git a/libaudit.pc.in b/libaudit.pc.in index 460a016..dfeecb0 100644 --- a/libaudit.pc.in +++ b/libaudit.pc.in @@ -6,6 +6,6 @@ includedir=@includedir@ Name: @PACKAGE_NAME@ Description: Database auditing Version: @PACKAGE_VERSION@ -Requires: libgdaobj +Requires: libgdaex Libs: -L${libdir} -laudit Cflags: -I${includedir} diff --git a/src/audit.c b/src/audit.c index 23d95e0..446c0a5 100644 --- a/src/audit.c +++ b/src/audit.c @@ -24,11 +24,57 @@ #include #endif +#include + #include "libaudit.h" +typedef struct +{ + gint id; + gchar *name; +} Field; + +typedef struct +{ + gint id; + gchar *name; + GList *fields; +} Table; + +typedef struct +{ + gint id; + gchar *name; + gchar *cnc_string; + GdaEx *gdaex; + GList *tables; +} Datasource; + static void audit_class_init (AuditClass *klass); static void audit_init (Audit *audit); +static Audit *audit_new_ (void); +static gboolean load_fields (Audit *audit, + Table *table); +static gboolean load_tables (Audit *audit, + Datasource *datasource); +static gboolean load_datasources (Audit *audit); +static Field *get_field_from_name (Audit *audit, + Table *table, + const char *field); +static Table *get_table_from_name (Audit *audit, + Datasource *datasource, + const char *table); +static Datasource *get_datasource_from_name (Audit *audit, + const char *datasource); +static gboolean insert_value (Audit *audit, + gint id_actions, + Table *table, + gchar *field_name, + gchar *value); +static gchar *value_string_unquote (const gchar *value); +static void parse_cond (GdaSqlExpr *cond, gchar **str); + static void audit_set_property (GObject *object, guint property_id, const GValue *value, @@ -49,28 +95,6 @@ struct _AuditPrivate GHashTable *fields_updated; }; -typedef struct -{ - gint id; - gchar *name; -} Field; - -typedef struct -{ - gint id; - gchar *name; - GList *fields; -} Table; - -typedef struct -{ - gint id; - gchar *name; - gchar *cnc_string; - GdaEx *gdaex; - GList *tables; -} Datasource; - /* PRIVATE */ G_DEFINE_TYPE (Audit, audit, G_TYPE_OBJECT) @@ -188,9 +212,12 @@ load_tables (Audit *audit, datasource->tables = g_list_append (datasource->tables, (gpointer)tab); - /* per ogni table devo caricare i fields */ + /* for each table must be loaded fields */ tab->fields = NULL; - load_fields (audit, tab); + if (!load_fields (audit, tab)) + { + return FALSE; + } } return TRUE; @@ -206,7 +233,7 @@ load_datasources (Audit *audit) AuditPrivate *priv = AUDIT_GET_PRIVATE (audit); - /* per ogni datasource nella table datasources devo aprire una connessione */ + /* for each datasource on datasources table must be opened a connection */ dm = gdaex_query (priv->gdaex, "SELECT id, name, cnc_string" " FROM datasources" " WHERE status <> 'D'"); @@ -231,23 +258,26 @@ load_datasources (Audit *audit) datas->name = gdaex_data_model_get_field_value_stringify_at (dm, row, "name"); datas->cnc_string = gdaex_data_model_get_field_value_stringify_at (dm, row, "cnc_string"); - g_debug ("DATASOURCE\nid: %d\nname: %s\ncnc_string: %s", - datas->id, datas->name, datas->cnc_string); + /*g_debug ("DATASOURCE\nid: %d\nname: %s\ncnc_string: %s", + datas->id, datas->name, datas->cnc_string);*/ datas->gdaex = gdaex_new_from_string (datas->cnc_string); priv->datasources = g_list_append (priv->datasources, (gpointer)datas); - /* per ogni datasource devo caricare tables e fields */ + /* for each datasource must be loaded tables and fields */ datas->tables = NULL; - load_tables (audit, datas); + if (!load_tables (audit, datas)) + { + return FALSE; + } } return TRUE; } static Field -*get_campo_from_name (Audit *audit, +*get_field_from_name (Audit *audit, Table *table, const char *field) { @@ -267,7 +297,7 @@ static Field } static Table -*get_tabella_from_name (Audit *audit, +*get_table_from_name (Audit *audit, Datasource *datasource, const char *table) { @@ -318,7 +348,7 @@ insert_value (Audit *audit, AuditPrivate *priv = AUDIT_GET_PRIVATE (audit); - Field *field = get_campo_from_name (audit, table, field_name); + Field *field = get_field_from_name (audit, table, field_name); if (field == NULL) { g_warning ("Unable to find the field \"%s\" on loaded fields.", @@ -342,13 +372,61 @@ insert_value (Audit *audit, sql = g_strdup_printf ("INSERT INTO values" " (id, id_actions, id_fields, value)" " VALUES (%d, %d, %d, '%s')", - id_new, id_actions, field->id, value); + id_new, id_actions, field->id, + gdaex_strescape ((const gchar *)value_string_unquote (value), NULL)); gdaex_execute (priv->gdaex, sql); } return TRUE; } +static void +parse_cond (GdaSqlExpr *cond, gchar **str) +{ + if (cond->cond->operator_type == GDA_SQL_OPERATOR_TYPE_EQ) + { + GdaSqlExpr *op1 = (GdaSqlExpr *)cond->cond->operands->data; + GdaSqlExpr *op2 = (GdaSqlExpr *)cond->cond->operands->next->data; + + *str = g_strconcat (*str, (g_strcmp0 (*str, "") != 0 ? "|" : ""), + gda_value_stringify (op1->value), + "|", + gda_value_stringify (op2->value), + NULL); + } + else + { + GSList *ops; + + ops = cond->cond->operands; + while (ops != NULL) + { + parse_cond ((GdaSqlExpr *)ops->data, str); + ops = g_slist_next (ops); + } + } +} + +static gchar +*value_string_unquote (const gchar *value) +{ + gchar *ret; + guint l; + + ret = g_strdup (value); + l = strlen (ret); + + if (l > 0) + { + if (ret[0] == '\'' && ret[l - 1] == '\'') + { + ret = g_strndup (ret + 1, l - 2); + } + } + + return ret; +} + static void audit_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { @@ -383,9 +461,9 @@ audit_get_property (GObject *object, guint property_id, GValue *value, GParamSpe /** * audit_new: - * @gda_connection: un #GdaConnection. + * @gda_connection: a #GdaConnection object. * - * Returns: l'oggetto #Audit appena creato. + * Returns: the newly #Audit object. */ Audit *audit_new (GdaConnection *gda_connection) @@ -416,9 +494,9 @@ Audit /** * audit_new_from_string: - * @cnc_string: la stringa di connessione al datasource che contiene le tabelle per la libreria. + * @cnc_string: the connection string to the datasource that contains library's tables. * - * Returns: l'oggetto #Audit appena creato. + * Returns: the newly #Audit object. */ Audit *audit_new_from_string (const gchar *cnc_string) @@ -449,14 +527,14 @@ Audit /** * audit_action: - * @audit: l'oggetto #Audit su cui effettuare l'azione. - * @action: il tipo di azione. - * @dn: lo username che effettua l'azione. + * @audit: an #Audit object. + * @action: the action's type. + * @dn: 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. * - * Returns: #TRUE se l'azione viene effettuata con successo. + * Returns: #TRUE on success. */ gboolean audit_action (Audit *audit, @@ -502,15 +580,15 @@ audit_action (Audit *audit, /** * audit_action_v: - * @audit: l'oggetto #Audit su cui effettuare l'azione. + * @audit: an #Audit object. * @action: the action's type. - * @dn: lo username che effettua l'azione. + * @dn: the username that make the action. * @datasource_name: the datasource's name. * @table_name: the table's name. * @fields_values: a #NULL-terminated array of strings in the form * "...#NULL" * - * Returns: #TRUE se l'azione viene effettuata con successo. + * Returns: #TRUE on success. */ gboolean audit_action_v (Audit *audit, @@ -544,7 +622,7 @@ audit_action_v (Audit *audit, return; } - /* trovo il nuovo id azione */ + /* find the new action's id */ dm = gdaex_query (priv->gdaex, "SELECT COALESCE (MAX (id), 0) FROM actions"); if (dm != NULL && gda_data_model_get_n_rows (dm) == 1) @@ -553,7 +631,7 @@ audit_action_v (Audit *audit, } id++; - /* trovo il timestamp dell'operazione */ + /* find action's timestamp */ t = time (NULL); tm_ora = localtime (&t); @@ -566,8 +644,8 @@ audit_action_v (Audit *audit, return FALSE; } - /* trovo la table */ - table = get_tabella_from_name (audit, datasource, table_name); + /* find the table */ + table = get_table_from_name (audit, datasource, table_name); if (table == NULL) { g_warning ("Unable to find the table \"%s\" on loaded tables.", @@ -575,7 +653,7 @@ audit_action_v (Audit *audit, return FALSE; } - /* salvo l'azione */ + /* saving the action */ if (action != AUDIT_ACTION_BEFORE_UPDATE) { /* TODO find the way to save more than 2 digits for the seconds */ @@ -595,7 +673,7 @@ audit_action_v (Audit *audit, switch (action) { case AUDIT_ACTION_INSERT: - /* salvo tutti i fields */ + /* saving all fields */ sql = g_strdup_printf ("SELECT * FROM %s", table_name); @@ -624,7 +702,7 @@ audit_action_v (Audit *audit, cols = gda_data_model_get_n_columns (dm); for (col = 0; col < cols; col++) { - /* trovo il field */ + /* 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)); @@ -632,7 +710,7 @@ audit_action_v (Audit *audit, break; case AUDIT_ACTION_BEFORE_UPDATE: - /* memorizzo tutta la table che sta per essere modificata */ + /* storing the whole table to be changed */ sql = g_strdup_printf ("SELECT * FROM %s", table_name); @@ -669,7 +747,7 @@ audit_action_v (Audit *audit, break; case AUDIT_ACTION_AFTER_UPDATE: - /* salvo i fields modificati */ + /* saving changed fields */ sql = g_strdup_printf ("SELECT * FROM %s", table_name); @@ -702,16 +780,16 @@ audit_action_v (Audit *audit, 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 (strcmp (value, value_new) != 0) + if (g_strcmp0 (value, value_new) != 0) { - /* field modificato */ - insert_value (audit, id, table, field_name, value_new); + /* field changed: must be saved the old value */ + insert_value (audit, id, table, field_name, value); } } break; case AUDIT_ACTION_DELETE: - /* salvo solo i fields della chiave */ + /* saving just key's fields */ for (strpart = 0; strpart < l; strpart++) { field_name = (gchar *)fields_values[strpart]; @@ -733,42 +811,15 @@ audit_action_v (Audit *audit, return TRUE; } -static void -parse_cond (GdaSqlExpr *cond, gchar **str) -{ - if (cond->cond->operator_type == GDA_SQL_OPERATOR_TYPE_EQ) - { - GdaSqlExpr *op1 = (GdaSqlExpr *)cond->cond->operands->data; - GdaSqlExpr *op2 = (GdaSqlExpr *)cond->cond->operands->next->data; - - *str = g_strconcat (*str, (g_strcmp0 (*str, "") != 0 ? "|" : ""), - gda_value_stringify (op1->value), - "|", - gda_value_stringify (op2->value), - NULL); - } - else - { - GSList *ops; - - ops = cond->cond->operands; - while (ops != NULL) - { - parse_cond ((GdaSqlExpr *)ops->data, str); - ops = g_slist_next (ops); - } - } -} - /** * audit_action_from_gdastatement: - * @audit: l'oggetto #Audit su cui effettuare l'azione. - * @action: il tipo di azione. - * @dn: lo username che effettua l'azione. + * @audit: an #Audit object. + * @action: the action's type. + * @dn: the username that make the action. * @datasource_name: the datasource's name. - * @gda_statement: + * @gda_statement: a #GdaStatement object. * - * Returns: #TRUE se l'azione viene effettuata con successo. + * Returns: #TRUE on success. */ gboolean audit_action_from_gdastatement (Audit *audit, @@ -888,25 +939,25 @@ audit_destroy (Audit *audit) /** * audit_get_record_at: - * @audit: - * @datasoruce: - * @tabella: - * @tm_ora: + * @audit: an #Audit object. + * @datasource: + * @table: + * @tm_time: * - * Returns: il record con la chiave specificata al timestamp specificato. + * Returns: the record with the specified key at the specified timestamp. */ gboolean audit_get_record_at (Audit *audit, const gchar *datasource_name, const gchar *table_name, - struct tm *tm_ora, + struct tm *tm_time, ...) { GdaDataModel *dm; gchar *sql; Datasource *datasource; - /* trovo il datasource */ + /* find the datasource */ datasource = get_datasource_from_name (audit, datasource_name); if (datasource == NULL) { -- 2.49.0