summaryrefslogtreecommitdiff
path: root/src/analysis/db
diff options
context:
space:
mode:
Diffstat (limited to 'src/analysis/db')
-rw-r--r--src/analysis/db/collection.c145
-rw-r--r--src/analysis/db/collection.h12
-rw-r--r--src/analysis/db/item-int.h2
-rw-r--r--src/analysis/db/item.c26
4 files changed, 153 insertions, 32 deletions
diff --git a/src/analysis/db/collection.c b/src/analysis/db/collection.c
index 5e5adb7..0292c5c 100644
--- a/src/analysis/db/collection.c
+++ b/src/analysis/db/collection.c
@@ -278,6 +278,8 @@ bool g_db_collection_recv(GDbCollection *collec, int fd, sqlite3 *db)
bool status; /* Bilan de lecture initiale */
DBAction action; /* Commande de la requête */
GDbItem *item; /* Définition d'élément visé */
+ GList *found; /* Test de présence existante */
+ timestamp_t inactive; /* Horodatage de désactivation */
status = safe_recv(fd, &val32, sizeof(uint32_t), 0);
if (!status) return false;
@@ -287,9 +289,6 @@ bool g_db_collection_recv(GDbCollection *collec, int fd, sqlite3 *db)
item = g_object_new(collec->type, NULL);
- if (db != NULL)
- g_db_item_set_server_side(item);
-
status = g_db_item_recv(item, fd, 0);
if (!status) return false;
@@ -299,6 +298,10 @@ bool g_db_collection_recv(GDbCollection *collec, int fd, sqlite3 *db)
{
case DBA_ADD_ITEM:
+ /* Ecrasement des horodatages par les valeurs communes du serveur */
+ if (db != NULL)
+ g_db_item_set_server_side(item);
+
result = g_db_collection_add_item(collec, item);
if (result)
@@ -310,17 +313,44 @@ bool g_db_collection_recv(GDbCollection *collec, int fd, sqlite3 *db)
}
if (!result)
- /* TODO : retirer l'élémnt */;
+ /* TODO : retirer l'élément */;
break;
case DBA_REM_ITEM:
+
+ g_db_collection_wlock(collec);
+
+ found = g_list_find_custom(collec->items, item, (GCompareFunc)g_db_item_compare_with_timestamp);
+
+ result = (found != NULL);
+
+ if (result)
+ {
+ /* Côté client */
+ if (db == NULL)
+ result = _g_db_collection_remove_item(collec, item, false);
+
+ /* Côté serveur */
+ else
+ {
+ if (g_db_item_is_active(G_DB_ITEM(found->data)))
+ {
+ inactive = _g_db_collection_compute_inactivity_timestamp(collec, false);
+ result = _g_db_collection_update_item_activity(collec, item, inactive, false);
+ }
+ }
+
+ }
+
+ g_db_collection_wunlock(collec);
+
break;
case DBA_CHANGE_STATE:
if (db == NULL)
- result = g_db_collection_update_item_activity(collec, item);
+ result = g_db_collection_update_item_activity(collec, item, g_db_item_get_timestamp(item) + 1);
else
result = false;
@@ -565,9 +595,104 @@ bool _g_db_collection_add_item(GDbCollection *collec, GDbItem *item, bool lock)
g_signal_emit_by_name(collec, "content-changed", DBA_ADD_ITEM, item);
+ if (lock)
+ g_db_collection_wunlock(collec);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : collec = ensemble d'éléments à considérer. *
+* item = élément de collection à manipuler. *
+* lock = indique si le verrou d'écriture doit être posé. *
+* *
+* Description : Procède au retrait d'un nouvel élément dans la collection. *
+* *
+* Retour : Bilan de l'exécution de l'opération. *
+* *
+* Remarques : L'appelant reste le propriétaire de l'object transféré. *
+* *
+******************************************************************************/
+
+bool _g_db_collection_remove_item(GDbCollection *collec, GDbItem *item, bool lock)
+{
+ bool result; /* Bilan à faire remonter */
+ GList *found; /* Test de présence existante */
+ GDbItem *internal; /* Elément interne à modifier */
+
+ result = true;
+
+ if (lock)
+ g_db_collection_wlock(collec);
+
+ found = g_list_find_custom(collec->items, item, (GCompareFunc)g_db_item_compare_with_timestamp);
+
+ result = (found != NULL);
+
+ if (result)
+ {
+ internal = G_DB_ITEM(found->data);
+
+ collec->items = g_list_delete_link(collec->items, found);
+
+ g_signal_emit_by_name(collec, "content-changed", DBA_REM_ITEM, internal);
+
+ g_object_unref(G_OBJECT(internal));
+
+ }
+
+ if (lock)
+ g_db_collection_wunlock(collec);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : collec = ensemble d'éléments à considérer. *
+* lock = indique si le verrou d'écriture doit être posé. *
+* *
+* Description : Détermine l'horodatage le plus jeune pour une désactivation. *
+* *
+* Retour : Horodatage à utiliser pour une phase de désactivation. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+timestamp_t _g_db_collection_compute_inactivity_timestamp(GDbCollection *collec, bool lock)
+{
+ timestamp_t result; /* Horodatage à retourner */
+ GList *iter; /* Boucle de parcours */
+ GDbItem *item; /* Elément interne à consulter */
+ timestamp_t stamp; /* Horodatage de l'élément */
+
+ result = TIMESTAMP_ALL_ACTIVE;
+
+ if (lock)
+ g_db_collection_wlock(collec);
+
+ for (iter = g_list_first(collec->items);
+ iter != NULL && result;
+ iter = g_list_next(iter))
+ {
+ item = G_DB_ITEM(iter->data);
+
+ if (!g_db_item_is_active(item))
+ {
+ stamp = g_db_item_get_timestamp(item);
- printf(" ==== CONTENT CHANGED (-> %u) !!!\n", g_list_length(collec->items));
+ if (timestamp_is_younger(stamp, result))
+ result = stamp;
+ }
+
+ }
if (lock)
g_db_collection_wunlock(collec);
@@ -591,7 +716,7 @@ bool _g_db_collection_add_item(GDbCollection *collec, GDbItem *item, bool lock)
* *
******************************************************************************/
-bool _g_db_collection_update_item_activity(GDbCollection *collec, GDbItem *item, bool lock)
+bool _g_db_collection_update_item_activity(GDbCollection *collec, GDbItem *item, timestamp_t timestamp, bool lock)
{
bool result; /* Bilan à faire remonter */
GList *found; /* Test de présence existante */
@@ -608,7 +733,7 @@ bool _g_db_collection_update_item_activity(GDbCollection *collec, GDbItem *item,
{
internal = G_DB_ITEM(found->data);
- g_db_item_set_activity(internal, (timestamp_t []) { g_db_item_get_timestamp(item) + 1 });
+ g_db_item_set_activity(internal, (timestamp_t []) { timestamp });
g_signal_emit_by_name(collec, "content-changed", DBA_CHANGE_STATE, internal);
@@ -893,8 +1018,6 @@ bool g_db_collection_load_all_items(GDbCollection *collec, sqlite3 *db)
new = g_object_new(G_DB_COLLECTION(collec)->type, NULL);
- g_db_item_set_server_side(new);
-
result = g_db_item_load(new, values, count);
result &= g_db_collection_add_item(G_DB_COLLECTION(collec), new);
@@ -1321,6 +1444,8 @@ bool update_activity_in_collections(GList *list, int fd, sqlite3 *db)
GList *i; /* Boucle de parcours #2 */
GDbItem *item; /* Elément collecté à manipuler*/
+ /* TODO : lock ? */
+
status = recv_timestamp(&timestamp, fd, 0);
if (!status) return false;
diff --git a/src/analysis/db/collection.h b/src/analysis/db/collection.h
index ac3e60f..e9f93d2 100644
--- a/src/analysis/db/collection.h
+++ b/src/analysis/db/collection.h
@@ -102,11 +102,19 @@ bool g_db_collection_has_item(GDbCollection *, GDbItem *);
/* Procède à l'ajout d'un nouvel élément dans la collection. */
bool _g_db_collection_add_item(GDbCollection *, GDbItem *, bool);
+/* Procède au retrait d'un nouvel élément dans la collection. */
+bool _g_db_collection_remove_item(GDbCollection *, GDbItem *, bool);
+
+/* Détermine l'horodatage le plus jeune pour une désactivation. */
+timestamp_t _g_db_collection_compute_inactivity_timestamp(GDbCollection *, bool);
+
/* Met à jour le statut d'activité d'un élément de collection. */
-bool _g_db_collection_update_item_activity(GDbCollection *, GDbItem *, bool);
+bool _g_db_collection_update_item_activity(GDbCollection *, GDbItem *, timestamp_t, bool);
#define g_db_collection_add_item(c, i) _g_db_collection_add_item(c, i, true)
-#define g_db_collection_update_item_activity(c, i) _g_db_collection_update_item_activity(c, i, true)
+#define g_db_collection_remove_item(c, i) _g_db_collection_remove_item(c, i, true)
+#define g_db_collection_compute_inactivity_timestamp(c) _g_db_collection_compute_inactivity_timestamp(c, true)
+#define g_db_collection_update_item_activity(c, i, t) _g_db_collection_update_item_activity(c, i, t, true)
/* Active les éléments en amont d'un horodatage donné. */
GList *g_db_collection_set_last_active(GDbCollection *, timestamp_t, timestamp_t *, sqlite3 *);
diff --git a/src/analysis/db/item-int.h b/src/analysis/db/item-int.h
index 1af1048..fb33c72 100644
--- a/src/analysis/db/item-int.h
+++ b/src/analysis/db/item-int.h
@@ -63,8 +63,6 @@ struct _GDbItem
{
GObject parent; /* A laisser en premier */
- bool server_side; /* Instance côté serveur */
-
timestamp_t created; /* Date de création */
timestamp_t timestamp; /* Date dernière activité */
diff --git a/src/analysis/db/item.c b/src/analysis/db/item.c
index 5463e85..3fc6f6f 100644
--- a/src/analysis/db/item.c
+++ b/src/analysis/db/item.c
@@ -191,8 +191,6 @@ void g_db_item_set_server_side(GDbItem *item)
init_timestamp(&item->created);
item->timestamp = item->created;
- item->server_side = true;
-
}
@@ -288,15 +286,11 @@ static bool g_db_item_recv_from_fd(GDbItem *item, int fd, int flags)
{
bool status; /* Bilan d'une réception */
- if (!item->server_side)
- {
- status = recv_timestamp(&item->created, fd, flags);
- if (!status) return false;
-
- status = recv_timestamp(&item->timestamp, fd, flags);
- if (!status) return false;
+ status = recv_timestamp(&item->created, fd, flags);
+ if (!status) return false;
- }
+ status = recv_timestamp(&item->timestamp, fd, flags);
+ if (!status) return false;
status = recv_rle_string(&item->author, fd, flags);
if (!status) return false;
@@ -354,15 +348,11 @@ static bool g_db_item_send_to_fd(const GDbItem *item, int fd, int flags)
{
bool status; /* Bilan d'une émission */
- if (item->server_side)
- {
- status = send_timestamp(&item->created, fd, MSG_MORE | flags);
- if (!status) return false;
-
- status = send_timestamp(&item->timestamp, fd, MSG_MORE | flags);
- if (!status) return false;
+ status = send_timestamp(&item->created, fd, 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;