diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2015-07-22 21:23:49 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2015-07-22 21:23:49 (GMT) |
commit | 21537636cd8318cf5a720211619ad3c3023b52e9 (patch) | |
tree | 93380a9152f18e39cf0ba427ede96533c5c6f16a /src/analysis/db/items/comment.c | |
parent | 361a0953c73635c6c383516280a8d634768f8226 (diff) |
Fortified the client/server protocol and first exchanges.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@554 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/analysis/db/items/comment.c')
-rw-r--r-- | src/analysis/db/items/comment.c | 400 |
1 files changed, 358 insertions, 42 deletions
diff --git a/src/analysis/db/items/comment.c b/src/analysis/db/items/comment.c index 73a18b0..1bed0ab 100644 --- a/src/analysis/db/items/comment.c +++ b/src/analysis/db/items/comment.c @@ -28,17 +28,20 @@ #include <sys/socket.h> +#include "../collection-int.h" #include "../item-int.h" -#include "../misc/rlestr.h" +/* --------------------- ELABORATION D'UN ELEMENT DE COLLECTION --------------------- */ + + /* Commentaire à placer dans du texte quelconque (instance) */ struct _GDbComment { GDbItem parent; /* A laisser en premier */ - vmpa2t *addr; /* Adresse du commentaire */ + vmpa2t addr; /* Adresse du commentaire */ rle_string text; /* Contenu du commentaire */ }; @@ -51,7 +54,6 @@ struct _GDbCommentClass }; - /* Initialise la classe des commentaires dans une zone de texte. */ static void g_db_comment_class_init(GDbCommentClass *); @@ -73,53 +75,58 @@ static bool g_db_comment_recv_from_fd(GDbComment *, int, int); /* Exporte la définition d'un commentaire dans un flux réseau. */ static bool g_db_comment_send_to_fd(const GDbComment *, int, int); +/* Constitue les champs destinés à une insertion / modification. */ +static bool g_db_comment_prepare_db_statement(const GDbComment *, bound_value **, size_t *); +/* Charge les valeurs utiles pour un commentaire. */ +static bool g_db_comment_load(GDbComment *, const bound_value *, size_t); -/****************************************************************************** -* * -* Paramètres : db = accès à la base de données. * -* * -* Description : Crée la table des commentaires dans une base de données. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ -bool create_comment_db_table(sqlite3 *db) +/* ---------------------- DEFINITION DE LA COLLECTION ASSOCIEE ---------------------- */ + + +/* Collection dédiée aux commentaires textuels (instance) */ +struct _GCommentCollection { - char *sql; /* Requête à exécuter */ - int ret; /* Bilan de la création */ - char *msg; /* Message d'erreur */ + GDbCollection parent; /* A laisser en premier */ - sql = "CREATE TABLE Comments (" \ - "id INT PRIMARY KEY NOT NULL, " \ - "user TEXT NOT NULL, " \ - "created INT NOT NULL, " \ - "address INT NOT NULL, " \ - "comment TEXT" \ - ");"; +}; - ret = sqlite3_exec(db, sql, NULL, NULL, &msg); - if (ret != SQLITE_OK) - { - fprintf(stderr, "sqlite3_exec(): %s\n", msg); - sqlite3_free(msg); - } +/* Collection dédiée aux commentaires textuels (classe) */ +struct _GCommentCollectionClass +{ + GDbCollectionClass parent; /* A laisser en premier */ - return (ret == SQLITE_OK); +}; -} +/* Initialise la classe des commentaires sous forme de texte. */ +static void g_comment_collection_class_init(GCommentCollectionClass *); + +/* Initialise un commentaire sous forme de zone de texte. */ +static void g_comment_collection_init(GCommentCollection *); + +/* Supprime toutes les références externes. */ +static void g_comment_collection_dispose(GCommentCollection *); +/* Procède à la libération totale de la mémoire. */ +static void g_comment_collection_finalize(GCommentCollection *); +/* Crée la table des commentaires dans une base de données. */ +static bool g_comment_collection_create_db_table(const GCommentCollection *, sqlite3 *); +/* Décrit les colonnes utiles à un chargement de données. */ +static bool g_comment_collection_setup_load(GCommentCollection *, bound_value **, size_t *); +/* Détermine si un élément est déjà présent ou non. */ +static GDbItem *g_comment_collection_has_key(GCommentCollection *, va_list *); +/* ---------------------------------------------------------------------------------- */ +/* ELABORATION D'UN ELEMENT DE COLLECTION */ +/* ---------------------------------------------------------------------------------- */ /* Indique le type défini pour un commentaire à l'intérieur d'une zone de texte. */ @@ -155,6 +162,9 @@ static void g_db_comment_class_init(GDbCommentClass *klass) item->recv = (recv_db_item_fc)g_db_comment_recv_from_fd; item->send = (send_db_item_fc)g_db_comment_send_to_fd; + item->prepare_stmt = (prepare_db_statement)g_db_comment_prepare_db_statement; + item->load = (load_db_item_fc)g_db_comment_load; + } @@ -209,9 +219,7 @@ static void g_db_comment_dispose(GDbComment *comment) static void g_db_comment_finalize(GDbComment *comment) { - delete_vmpa(comment->addr); - - exit_rle_string(comment->text); + exit_rle_string(&comment->text); G_OBJECT_CLASS(g_db_comment_parent_class)->finalize(G_OBJECT(comment)); @@ -238,7 +246,7 @@ GDbComment *g_db_comment_new(const vmpa2t *addr, const char *text, bool is_volat result = g_object_new(G_TYPE_DB_COMMENT, NULL); - result->addr = dup_vmpa(addr); + copy_vmpa(&result->addr, addr); g_db_comment_set_text(result, text); @@ -266,11 +274,14 @@ static gint g_db_comment_cmp(GDbComment *a, GDbComment *b) { gint result; /* Bilan de la comparaison */ - result = cmp_vmpa_by_phy(a->addr, b->addr); + result = cmp_vmpa_by_phy(&a->addr, &b->addr); if (result == 0) result = cmp_rle_string(&a->text, &b->text); + if (result == 0) + result = G_DB_ITEM_CLASS(g_db_comment_parent_class)->cmp(G_DB_ITEM(a), G_DB_ITEM(b)); + return 0; } @@ -297,10 +308,10 @@ static bool g_db_comment_recv_from_fd(GDbComment *comment, int fd, int flags) status = G_DB_ITEM_CLASS(g_db_comment_parent_class)->recv(G_DB_ITEM(comment), fd, flags); if (!status) return false; - if (!recv_vmpa(comment->addr, fd, 0)) + if (!recv_vmpa(&comment->addr, fd, flags)) return false; - if (!recv_rle_string(&comment->text, fd, 0)) + if (!recv_rle_string(&comment->text, fd, flags)) return false; return true; @@ -329,7 +340,7 @@ static bool g_db_comment_send_to_fd(const GDbComment *comment, int fd, int flags status = G_DB_ITEM_CLASS(g_db_comment_parent_class)->send(G_DB_ITEM(comment), fd, MSG_MORE | flags); if (!status) return false; - if (!send_vmpa(comment->addr, fd, MSG_MORE | flags)) + if (!send_vmpa(&comment->addr, fd, MSG_MORE | flags)) return false; if (!send_rle_string(&comment->text, fd, flags)) @@ -342,6 +353,67 @@ static bool g_db_comment_send_to_fd(const GDbComment *comment, int fd, int flags /****************************************************************************** * * +* Paramètres : comment = base d'éléments sur laquelle s'appuyer. * +* values = couples de champs et de valeurs à lier. [OUT] * +* count = nombre de ces couples. [OUT] * +* * +* Description : Constitue les champs destinés à une insertion / modification.* +* * +* Retour : Etat du besoin en sauvegarde. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_db_comment_prepare_db_statement(const GDbComment *comment, bound_value **values, size_t *count) +{ + bool status; /* Bilan d'opération initiale */ + + status = G_DB_ITEM_CLASS(g_db_comment_parent_class)->prepare_stmt(G_DB_ITEM(comment), values, count); + if (!status) return false; + + status = prepare_vmpa_db_statement(&comment->addr, values, count); + if (!status) return false; + + status &= prepare_db_statement_for_rle_string(&comment->text, "text", values, count); + if (!status) return false; + + return true; + +} + + +/****************************************************************************** +* * +* Paramètres : comment = commentaire textuel à charger depuis les réponses. * +* values = tableau d'éléments à consulter. * +* count = nombre de descriptions renseignées. * +* * +* Description : Charge les valeurs utiles pour un commentaire. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_db_comment_load(GDbComment *comment, const bound_value *values, size_t count) +{ + bool result; /* Bilan à faire remonter */ + + result = G_DB_ITEM_CLASS(g_db_comment_parent_class)->load(G_DB_ITEM(comment), values, count); + + result &= load_vmpa(&comment->addr, values, count); + + result &= load_rle_string(&comment->text, "text", values, count); + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : comment = informations à consulter. * * * * Description : Fournit l'adresse associée à un commentaire. * @@ -354,7 +426,7 @@ static bool g_db_comment_send_to_fd(const GDbComment *comment, int fd, int flags const vmpa2t *g_db_comment_get_address(GDbComment *comment) { - return comment->addr; + return &comment->addr; } @@ -396,3 +468,247 @@ void g_db_comment_set_text(GDbComment *comment, const char *text) set_rle_string(&comment->text, text); } + + + +/* ---------------------------------------------------------------------------------- */ +/* DEFINITION DE LA COLLECTION ASSOCIEE */ +/* ---------------------------------------------------------------------------------- */ + + +/* Indique le type défini pour une collection de commentaires. */ +G_DEFINE_TYPE(GCommentCollection, g_comment_collection, G_TYPE_DB_COLLECTION); + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des commentaires sous forme de texte. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_comment_collection_class_init(GCommentCollectionClass *klass) +{ + GObjectClass *object; /* Autre version de la classe */ + GDbCollectionClass *collec; /* Encore une autre vision... */ + + object = G_OBJECT_CLASS(klass); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_comment_collection_dispose; + object->finalize = (GObjectFinalizeFunc)g_comment_collection_finalize; + + collec = G_DB_COLLECTION_CLASS(klass); + + collec->create_table = (collec_create_db_table_fc)g_comment_collection_create_db_table; + collec->setup_load = (collec_setup_load_fc)g_comment_collection_setup_load; + collec->has_key = (collec_has_key_fc)g_comment_collection_has_key; + +} + + +/****************************************************************************** +* * +* Paramètres : collec = instance à initialiser. * +* * +* Description : Initialise un commentaire sous forme de zone de texte. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_comment_collection_init(GCommentCollection *collec) +{ + + + G_DB_COLLECTION(collec)->featuring = 0; + G_DB_COLLECTION(collec)->type = G_TYPE_DB_COMMENT; + G_DB_COLLECTION(collec)->name = "Comments"; + + + +} + + +/****************************************************************************** +* * +* Paramètres : collec = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_comment_collection_dispose(GCommentCollection *collec) +{ + G_OBJECT_CLASS(g_comment_collection_parent_class)->dispose(G_OBJECT(collec)); + +} + + +/****************************************************************************** +* * +* Paramètres : collec = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_comment_collection_finalize(GCommentCollection *collec) +{ + G_OBJECT_CLASS(g_comment_collection_parent_class)->finalize(G_OBJECT(collec)); + +} + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Crée une collection dédiée aux commentaires. * +* * +* Retour : Collection mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GCommentCollection *g_comment_collection_new(void) +{ + GCommentCollection *result; /* Instance à retourner */ + + result = g_object_new(G_TYPE_COMMENT_COLLECTION, NULL); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : collec = ensemble d'éléments spectateur des opérations. * +* db = accès à la base de données. * +* * +* Description : Crée la table des commentaires dans une base de données. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_comment_collection_create_db_table(const GCommentCollection *collec, sqlite3 *db) +{ + char *sql; /* Requête à exécuter */ + int ret; /* Bilan de la création */ + char *msg; /* Message d'erreur */ + + sql = "CREATE TABLE Comments (" \ + SQLITE_DB_ITEM_CREATE ", " \ + SQLITE_VMPA_CREATE ", " \ + SQLITE_RLESTR_CREATE("text") \ + ");"; + + ret = sqlite3_exec(db, sql, NULL, NULL, &msg); + if (ret != SQLITE_OK) + { + fprintf(stderr, "sqlite3_exec(): %s\n", msg); + sqlite3_free(msg); + } + + return (ret == SQLITE_OK); + +} + + +/****************************************************************************** +* * +* 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_comment_collection_setup_load(GCommentCollection *collec, bound_value **values, size_t *count) +{ + bool status; /* Bilan d'une préparation */ + + status = G_DB_COLLECTION_CLASS(g_comment_collection_parent_class)->setup_load(G_DB_COLLECTION(collec), \ + values, count); + if (!status) return false; + + if (!setup_load_for_vmpa(NULL, values, count)) + return false; + + if (!setup_load_of_rle_string(NULL, "text", values, count)) + return false; + + return true; + +} + + +/****************************************************************************** +* * +* Paramètres : collec = ensemble d'éléments à consulter. * +* ap = 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 : - * +* * +******************************************************************************/ + +static GDbItem *g_comment_collection_has_key(GCommentCollection *collec, va_list *ap) +{ + GDbItem *result; /* Bilan à retourner */ + vmpa2t *ref; /* Adresse de référence */ + GList *items; /* Eléments déjà en place */ + GList *iter; /* Boucle de parcours */ + GDbComment *bm; /* Signet à consulter */ + + result = NULL; + + ref = va_arg(ap, vmpa2t *); + + items = g_db_collection_list_items(G_DB_COLLECTION(collec)); + + for (iter = g_list_first(items); iter != NULL && result == NULL; iter = g_list_next(iter)) + { + bm = G_DB_COMMENT(iter->data); + + if (cmp_vmpa(&bm->addr, ref) != 0) + + /** + * Un verrou est sensé être posé, donc il n'y a pas besoin + * de toucher au décompte des références car l'élément trouvé + * ne peut pas être supprimé. + */ + result = G_DB_ITEM(bm); + + } + + return result; + +} |