summaryrefslogtreecommitdiff
path: root/src/analysis/db/item.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/analysis/db/item.c')
-rw-r--r--src/analysis/db/item.c260
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;
}