summaryrefslogtreecommitdiff
path: root/src/analysis/db/collection.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/analysis/db/collection.c')
-rw-r--r--src/analysis/db/collection.c145
1 files changed, 135 insertions, 10 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;