diff options
Diffstat (limited to 'src/analysis/db/item.c')
-rw-r--r-- | src/analysis/db/item.c | 260 |
1 files changed, 179 insertions, 81 deletions
diff --git a/src/analysis/db/item.c b/src/analysis/db/item.c index d2f87c3..5463e85 100644 --- a/src/analysis/db/item.c +++ b/src/analysis/db/item.c @@ -26,6 +26,7 @@ #include <assert.h> #include <malloc.h> +#include <string.h> #include <sqlite3.h> @@ -47,9 +48,6 @@ static void g_db_item_dispose(GDbItem *); /* Procède à la libération totale de la mémoire. */ static void g_db_item_finalize(GDbItem *); -/* Effectue la comparaison entre deux éléments de collection. */ -static gint g_db_item_cmp(GDbItem *, GDbItem *); - /* Importe la définition d'une base d'éléments pour collection. */ static bool g_db_item_recv_from_fd(GDbItem *, int, int); @@ -94,7 +92,7 @@ static void g_db_item_class_init(GDbItemClass *klass) object->dispose = (GObjectFinalizeFunc/* ! */)g_db_item_dispose; object->finalize = (GObjectFinalizeFunc)g_db_item_finalize; - klass->cmp = (GCompareFunc)g_db_item_cmp; + klass->cmp = (cmp_db_item_fc)g_db_item_cmp; klass->recv = (recv_db_item_fc)g_db_item_recv_from_fd; klass->send = (send_db_item_fc)g_db_item_send_to_fd; @@ -165,6 +163,12 @@ static void g_db_item_dispose(GDbItem *item) static void g_db_item_finalize(GDbItem *item) { + exit_rle_string(&item->author); + exit_rle_string(&item->tool); + + if (item->label != NULL) + free(item->label); + G_OBJECT_CLASS(g_db_item_parent_class)->finalize(G_OBJECT(item)); } @@ -172,8 +176,31 @@ static void g_db_item_finalize(GDbItem *item) /****************************************************************************** * * -* Paramètres : a = premier élément à analyser. * -* b = second élément à analyser. * +* Paramètres : item = élément de collection à traiter. * +* * +* Description : Indique à l'élément qu'il se trouve du côté serveur. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_db_item_set_server_side(GDbItem *item) +{ + init_timestamp(&item->created); + item->timestamp = item->created; + + item->server_side = true; + +} + + +/****************************************************************************** +* * +* Paramètres : a = premier élément à analyser. * +* b = second élément à analyser. * +* with = précise les horodatages à prendre en compte. * * * * Description : Effectue la comparaison entre deux éléments de collection. * * * @@ -183,35 +210,42 @@ static void g_db_item_finalize(GDbItem *item) * * ******************************************************************************/ -static gint g_db_item_cmp(GDbItem *a, GDbItem *b) +gint g_db_item_cmp(GDbItem *a, GDbItem *b, bool with) { gint result; /* Bilan à retourner */ - /** - * A n'utiliser qu'en dernier recours, pour départager deux - * éléments par un serveur NTP... - */ + if (with) + result = cmp_timestamp(&a->timestamp, &b->timestamp); + else + result = 0; - if (a->modified > b->modified) - result = 1; + if (result == 0) + result = cmp_timestamp(&a->created, &b->created); - else if (a->modified < b->modified) - result = -1; + if (result == 0) + result = strcmp(a->label, b->label); - else - { - if (a->created > b->created) - result = 1; + return result; - else if (a->created < b->created) - result = -1; +} - else - result = cmp_rle_string(&a->label, &b->label); - } +/****************************************************************************** +* * +* Paramètres : a = premier élément à analyser. * +* b = second élément à analyser. * +* * +* Description : Effectue la comparaison entre deux éléments de collection. * +* * +* Retour : Bilan de la comparaison : -1, 0 ou 1. * +* * +* Remarques : - * +* * +******************************************************************************/ - return result; +gint g_db_item_compare_with_timestamp(GDbItem *a, GDbItem *b) +{ + return G_DB_ITEM_GET_CLASS(a)->cmp(a, b, true); } @@ -229,18 +263,18 @@ static gint g_db_item_cmp(GDbItem *a, GDbItem *b) * * ******************************************************************************/ -gint g_db_item_compare(GDbItem *a, GDbItem *b) +gint g_db_item_compare_without_timestamp(GDbItem *a, GDbItem *b) { - return G_DB_ITEM_GET_CLASS(a)->cmp(a, b); + return G_DB_ITEM_GET_CLASS(a)->cmp(a, b, false); } /****************************************************************************** * * -* Paramètres : item = base d'éléments à charger. [OUT] * -* fd = flux ouvert en lecture pour l'importation. * -* flags = éventuelles options d'envoi supplémentaires. * +* Paramètres : item = base d'éléments à charger. [OUT] * +* fd = flux ouvert en lecture pour l'importation. * +* flags = éventuelles options d'envoi supplémentaires. * * * * Description : Importe la définition d'une base d'éléments pour collection. * * * @@ -252,18 +286,17 @@ gint g_db_item_compare(GDbItem *a, GDbItem *b) static bool g_db_item_recv_from_fd(GDbItem *item, int fd, int flags) { - uint64_t val64; /* Valeur sur 64 bits */ bool status; /* Bilan d'une réception */ - status = safe_recv(fd, &val64, sizeof(uint64_t), MSG_WAITALL | flags); - if (!status) return false; - - item->created = be64toh(val64); + if (!item->server_side) + { + status = recv_timestamp(&item->created, fd, flags); + if (!status) return false; - status = safe_recv(fd, &val64, sizeof(uint64_t), MSG_WAITALL | flags); - if (!status) return false; + status = recv_timestamp(&item->timestamp, fd, flags); + if (!status) return false; - item->modified = be64toh(val64); + } status = recv_rle_string(&item->author, fd, flags); if (!status) return false; @@ -271,9 +304,6 @@ static bool g_db_item_recv_from_fd(GDbItem *item, int fd, int flags) status = recv_rle_string(&item->tool, fd, flags); if (!status) return false; - status = recv_rle_string(&item->label, fd, flags); - if (!status) return false; - return true; } @@ -295,7 +325,13 @@ static bool g_db_item_recv_from_fd(GDbItem *item, int fd, int flags) bool g_db_item_recv(GDbItem *item, int fd, int flags) { - return G_DB_ITEM_GET_CLASS(item)->recv(item, fd, flags); + bool result; /* Bilan à retourner */ + + result = G_DB_ITEM_GET_CLASS(item)->recv(item, fd, flags); + + G_DB_ITEM_GET_CLASS(item)->build_label(item); + + return result; } @@ -318,19 +354,20 @@ static bool g_db_item_send_to_fd(const GDbItem *item, int fd, int flags) { bool status; /* Bilan d'une émission */ - status = safe_send(fd, (uint64_t []) { htobe64(item->created) }, sizeof(uint64_t), MSG_MORE | flags); - if (!status) return false; + if (item->server_side) + { + status = send_timestamp(&item->created, fd, MSG_MORE | flags); + if (!status) return false; - status = safe_send(fd, (uint64_t []) { htobe64(item->modified) }, sizeof(uint64_t), MSG_MORE | flags); - if (!status) return false; + status = send_timestamp(&item->timestamp, fd, MSG_MORE | flags); + if (!status) return false; - status = send_rle_string(&item->author, fd, MSG_MORE | flags); - if (!status) return false; + } - status = send_rle_string(&item->tool, fd, MSG_MORE | flags); + status = send_rle_string(&item->author, fd, MSG_MORE | flags); if (!status) return false; - status = send_rle_string(&item->label, fd, flags); + status = send_rle_string(&item->tool, fd, flags); if (!status) return false; return true; @@ -417,6 +454,86 @@ bool g_db_item_cancel(GDbItem *item, GLoadedBinary *binary) /****************************************************************************** * * +* Paramètres : item = élément de collection à consulter. * +* * +* Description : Décrit l'élément de collection en place. * +* * +* Retour : Chaîne de caractère correspondante. * +* * +* Remarques : - * +* * +******************************************************************************/ + +const char *g_db_item_get_label(const GDbItem *item) +{ + return item->label; + +} + + +/****************************************************************************** +* * +* Paramètres : item = élément de collection à consulter. * +* * +* Description : Fournit l'horodatage associé à l'élément de collection. * +* * +* Retour : Date d'activité de l'élément. * +* * +* Remarques : - * +* * +******************************************************************************/ + +timestamp_t g_db_item_get_timestamp(const GDbItem *item) +{ + return item->timestamp; + +} + + +/****************************************************************************** +* * +* Paramètres : item = élément de collection à mettre à jour. * +* first = horodatage du premier élément désactivé ou NULL. * +* * +* Description : Active ou désactive un élément de collection en place. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_db_item_set_activity(GDbItem *item, timestamp_t *first) +{ + if (first == NULL) + item->timestamp = item->created; + else + item->timestamp = --(*first); + +} + + +/****************************************************************************** +* * +* Paramètres : item = élément de collection à consulter. * +* * +* Description : Indique si l'élément est activé ou désactivé. * +* * +* Retour : Etat de l'activité de l'élément. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_db_item_is_active(const GDbItem *item) +{ + return (cmp_timestamp(&item->created, &item->timestamp) == 0); + +} + + +/****************************************************************************** +* * * Paramètres : item = base d'éléments à modifier. * * is_volatile = état du besoin en sauvegarde. * * * @@ -477,31 +594,17 @@ bool g_db_item_is_volatile(const GDbItem *item) static bool _g_db_item_prepare_db_statement(const GDbItem *item, bound_value **values, size_t *count) { bool result; /* Bilan à retourner */ - bound_value *value; /* Valeur à éditer / définir */ result = true; - *count += 2; - *values = (bound_value *)realloc(*values, *count * sizeof(bound_value)); - - value = &(*values)[*count - 2]; - - value->name = "created"; - value->type = SQLITE_INT64; - value->integer64 = item->created; + result &= prepare_db_statement_for_timestamp(&item->created, "created", values, count); - value = &(*values)[*count - 1]; - - value->name = "modified"; - value->type = SQLITE_INT64; - value->integer64 = item->modified; + result &= prepare_db_statement_for_timestamp(&item->timestamp, "timestamp", values, count); result &= prepare_db_statement_for_rle_string(&item->author, "author", values, count); result &= prepare_db_statement_for_rle_string(&item->tool, "tool", values, count); - result &= prepare_db_statement_for_rle_string(&item->label, "label", values, count); - return result; } @@ -548,28 +651,17 @@ bool g_db_item_prepare_db_statement(const GDbItem *item, bound_value **values, s static bool _g_db_item_load(GDbItem *item, const bound_value *values, size_t count) { bool result; /* Bilan global à retourner */ - const bound_value *value; /* Valeur à éditer / définir */ - - value = find_bound_value(values, count, "created"); - if (value == NULL) return false; - if (value->type != SQLITE_INT64) return false; - - item->created = value->integer64; - value = find_bound_value(values, count, "modified"); - if (value == NULL) return false; - if (value->type != SQLITE_INT64) return false; + result = true; - item->modified = value->integer64; + result &= load_timestamp(&item->created, "created", values, count); - result = true; + result &= load_timestamp(&item->timestamp, "timestamp", values, count); result &= load_rle_string(&item->author, "author", values, count); result &= load_rle_string(&item->tool, "tool", values, count); - result &= load_rle_string(&item->label, "label", values, count); - return result; } @@ -591,6 +683,12 @@ static bool _g_db_item_load(GDbItem *item, const bound_value *values, size_t cou bool g_db_item_load(GDbItem *item, const bound_value *values, size_t count) { - return G_DB_ITEM_GET_CLASS(item)->load(item, values, count); + bool result; /* Bilan à retourner */ + + result = G_DB_ITEM_GET_CLASS(item)->load(item, values, count); + + G_DB_ITEM_GET_CLASS(item)->build_label(item); + + return result; } |