diff options
Diffstat (limited to 'src/analysis/db/collection.c')
-rw-r--r-- | src/analysis/db/collection.c | 272 |
1 files changed, 240 insertions, 32 deletions
diff --git a/src/analysis/db/collection.c b/src/analysis/db/collection.c index 5c25720..84acc58 100644 --- a/src/analysis/db/collection.c +++ b/src/analysis/db/collection.c @@ -24,41 +24,19 @@ #include "collection.h" +#include <assert.h> +#include <malloc.h> #include <stdio.h> #include <string.h> +#include "collection-int.h" #include "../../common/extstr.h" #include "../../common/io.h" #include "../../glibext/chrysamarshal.h" -/* Collection générique d'éléments (instance) */ -struct _GDbCollection -{ - GObject parent; /* A laisser en premier */ - - uint32_t featuring; /* Fonctionnalité représentée */ - GType type; /* Identifiant GLib équivalent */ - const char *name; /* Nom en base de données */ - - GList *items; /* Eléments rassemblés */ - GList *sorted; /* Eléments triés */ - GRWLock params_access; /* Verrou de protection */ - -}; - -/* Collection générique d'éléments (classe) */ -struct _GDbCollectionClass -{ - GObjectClass parent; /* A laisser en premier */ - - /* Signaux */ - - void (* content_changed) (GDbCollection *, DBAction, GDbItem *); - -}; @@ -80,6 +58,9 @@ static void g_db_collection_finalize(GDbCollection *); /* --------------------- MANIPULATIONS AVEC UNE BASE DE DONNEES --------------------- */ +/* Décrit les colonnes utiles à un chargement de données. */ +static bool g_db_collection_setup_load(GDbCollection *, bound_value **, size_t *); + /* Enregistre un élément de collection dans une base de données. */ static bool g_db_collection_store_item(const GDbCollection *, const GDbItem *, sqlite3 *); @@ -345,8 +326,37 @@ bool g_db_collection_send(GDbCollection *collec, int fd, DBAction action, GDbIte } +/****************************************************************************** +* * +* Paramètres : collec = ensemble d'éléments à considérer. * +* fd = flux ouvert en écriture pour l'émission de données. * +* * +* Description : Envoie pour mise à jour tous les éléments courants. * +* * +* Retour : Bilan de l'exécution de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ +bool g_db_collection_send_all_updates(GDbCollection *collec, int fd) +{ + bool result; /* Bilan à renvoyer */ + GList *iter; /* Boucle de parcours */ + + result = true; + + for (iter = g_list_first(collec->items); + iter != NULL && result; + iter = g_list_next(iter)) + { + result = g_db_collection_send(collec, fd, DBA_ADD_ITEM, G_DB_ITEM(iter->data)); + + } + + return result; +} @@ -408,17 +418,76 @@ GList *g_db_collection_list_items(const GDbCollection *collec) } +/****************************************************************************** +* * +* Paramètres : collec = ensemble d'éléments à consulter. * +* ... = clef identifiant de manière unique un élément. * +* * +* Description : Détermine si un élément est déjà présent ou non. * +* * +* Retour : Elément trouvé ou NULL si aucun. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GDbItem *g_db_collection_has_key(GDbCollection *collec, ...) +{ + GDbItem *result; /* Bilan à retourner */ + va_list ap; /* Liste d'arguments en plus */ + + va_start(ap, collec); + + result = G_DB_COLLECTION_GET_CLASS(collec)->has_key(collec, &ap); + + va_end(ap); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : collec = ensemble d'éléments à consulter. * +* item = élément complet dont un double est à rechercher. * +* * +* Description : Détermine si un élément est déjà présent ou non. * +* * +* Retour : true si un élément similaire est présent dans la collection. * +* * +* Remarques : - * +* * +******************************************************************************/ +bool g_db_collection_has_item(GDbCollection *collec, GDbItem *item) +{ + bool result; /* Bilan à retourner */ + GList *found; /* Test de présence existante */ + + /** + * Un verrou doit être posé ! + * Il n'y a pas d'assert() possible pour le vérifier... + */ + + printf(" --- has\n"); + + found = g_list_find_custom(collec->items, item, (GCompareFunc)g_db_item_compare); + printf(" --- has: %p\n", found); + result = (found != NULL); + 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 à l'ajout d'un nouvel élément dans la collection. * * * @@ -428,12 +497,13 @@ GList *g_db_collection_list_items(const GDbCollection *collec) * * ******************************************************************************/ -bool g_db_collection_add_item(GDbCollection *collec, GDbItem *item) +bool _g_db_collection_add_item(GDbCollection *collec, GDbItem *item, bool lock) { bool result; /* Bilan à faire remonter */ GList *found; /* Test de présence existante */ - g_db_collection_wlock(collec); + if (lock) + g_db_collection_wlock(collec); found = g_list_find_custom(collec->items, item, (GCompareFunc)g_db_item_compare); @@ -451,14 +521,15 @@ bool g_db_collection_add_item(GDbCollection *collec, GDbItem *item) g_signal_emit_by_name(collec, "content-changed", DBA_ADD_ITEM, item); - printf(" ==== CONTENT CHANGED !!!\n"); + printf(" ==== CONTENT CHANGED (-> %u) !!!\n", g_list_length(collec->items)); result = true; } - g_db_collection_wunlock(collec); + if (lock) + g_db_collection_wunlock(collec); return result; @@ -469,6 +540,7 @@ bool g_db_collection_add_item(GDbCollection *collec, GDbItem *item) * * * Paramètres : collec = ensemble d'éléments à considérer. * * item = élément de collection à copier. * +* lock = indique si le verrou d'écriture doit être posé. * * * * Description : Procède à la modification d'un élément dans la collection. * * * @@ -478,7 +550,7 @@ bool g_db_collection_add_item(GDbCollection *collec, GDbItem *item) * * ******************************************************************************/ -bool g_db_collection_modify_item(GDbCollection *collec, GDbItem *item) +bool _g_db_collection_modify_item(GDbCollection *collec, GDbItem *item, bool lock) { bool result; /* Bilan à faire remonter */ GList *found; /* Test de présence existante */ @@ -499,15 +571,151 @@ bool g_db_collection_modify_item(GDbCollection *collec, GDbItem *item) - /* ---------------------------------------------------------------------------------- */ -/* CREATION DE L'ABSTRACTION POUR COLLECTIONS */ /* MANIPULATIONS AVEC UNE BASE DE DONNEES */ /* ---------------------------------------------------------------------------------- */ /****************************************************************************** * * +* Paramètres : collec = ensemble d'éléments à consulter. * +* values = tableau d'éléments à compléter. [OUT] * +* count = nombre de descriptions renseignées. [OUT] * +* * +* Description : Décrit les colonnes utiles à un chargement de données. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_db_collection_setup_load(GDbCollection *collec, bound_value **values, size_t *count) +{ + *values = NULL; + *count = 0; + + return G_DB_COLLECTION_GET_CLASS(collec)->setup_load(collec, values, count); + +} + + +/****************************************************************************** +* * +* Paramètres : collec = ensemble d'éléments à peupler. * +* db = base de données repondant aux requêtes. * +* * +* Description : Charge un ensemble d'éléments à partir d'une base de données.* +* * +* Retour : Bilan de l'exécution de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_db_collection_load_all_items(GDbCollection *collec, sqlite3 *db) +{ + bool result; /* Conclusion à faire remonter */ + bound_value *values; /* Champs de table à inclure */ + size_t count; /* Nombre de ces champs */ + char *sql; /* Requête SQL à construire */ + size_t i; /* Boucle de parcours */ + sqlite3_stmt *stmt; /* Déclaration mise en place */ + int ret; /* Bilan d'un appel à SQLite */ + + if (!g_db_collection_setup_load(collec, &values, &count)) + return false; + + result = false; + + /* Préparation de la requête */ + + sql = strdup("SELECT "); + + for (i = 0; i < count; i++) + { + if (i > 0) sql = stradd(sql, ", "); + + sql = stradd(sql, values[i].name); + + } + + sql = stradd(sql, " FROM "); + sql = stradd(sql, collec->name); + sql = stradd(sql, ";"); + + ret = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL); + if (ret != SQLITE_OK) + { + fprintf(stderr, "Can't prepare SELECT statment '%s' (ret=%d): %s\n", sql, ret, sqlite3_errmsg(db)); + goto gdclai_exit; + } + + /* Chargement des valeurs existantes */ + + result = true; + + for (ret = sqlite3_step(stmt); ret == SQLITE_ROW && result; ret = sqlite3_step(stmt)) + { + /* Conversion des valeurs */ + + for (i = 0; i < count; i++) + { + values[i].type = sqlite3_column_type(stmt, i); + + switch (values[i].type) + { + case SQLITE_INTEGER: + values[i].type = SQLITE_INT64; + values[i].integer64 = sqlite3_column_int64(stmt, i); + break; + + case SQLITE_FLOAT: + assert(0); /* TODO */ + break; + + case SQLITE_TEXT: + values[i].cstring = (const char *)sqlite3_column_text(stmt, i); + break; + + case SQLITE_BLOB: + assert(0); /* TODO */ + break; + + case SQLITE_NULL: + break; + + default: + assert(0); + break; + + } + + } + + /* Chargement d'un nouvel élément */ + + result = G_DB_COLLECTION_GET_CLASS(collec)->load_item(collec, values, count); + + } + + /* Sortie propre */ + + sqlite3_finalize(stmt); + + gdclai_exit: + + free(sql); + + printf("LOAD ? %d\n", result); + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : collec = ensemble d'éléments à considérer. * * item = élément de collection à enregistrer. * * db = base de données à mettre à jour. * |