diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2014-10-16 22:04:29 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2014-10-16 22:04:29 (GMT) |
commit | 6d34dbbb00da0c276261d0e1ce4bf862f22fd8e0 (patch) | |
tree | a5d3c8644691934ba84a91919f7db177f70743f1 /src/analysis/db | |
parent | e75f44a99c8f984af4c47fa9a2c8e7e9841700d8 (diff) |
Stored a bookmark into the data base and saved the archive.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@414 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/analysis/db')
-rw-r--r-- | src/analysis/db/cdb.c | 47 | ||||
-rw-r--r-- | src/analysis/db/cdb.h | 2 | ||||
-rw-r--r-- | src/analysis/db/client.c | 43 | ||||
-rw-r--r-- | src/analysis/db/client.h | 3 | ||||
-rw-r--r-- | src/analysis/db/collection.c | 162 | ||||
-rw-r--r-- | src/analysis/db/collection.h | 6 | ||||
-rw-r--r-- | src/analysis/db/item-int.h | 10 | ||||
-rw-r--r-- | src/analysis/db/item.c | 93 | ||||
-rw-r--r-- | src/analysis/db/item.h | 18 | ||||
-rw-r--r-- | src/analysis/db/items/bookmark.c | 61 | ||||
-rw-r--r-- | src/analysis/db/items/bookmark.h | 2 | ||||
-rw-r--r-- | src/analysis/db/protocol.h | 27 |
12 files changed, 442 insertions, 32 deletions
diff --git a/src/analysis/db/cdb.c b/src/analysis/db/cdb.c index 563aa40..55d1b2d 100644 --- a/src/analysis/db/cdb.c +++ b/src/analysis/db/cdb.c @@ -34,7 +34,6 @@ #include <pthread.h> #include <signal.h> #include <stdio.h> -#include <sqlite3.h> #include <string.h> #include <unistd.h> #include <sys/stat.h> @@ -283,6 +282,8 @@ GCdbArchive *g_cdb_archive_new(const char *owner, const rle_string *hash, const result->filename = get_xdg_config_dir(suffix); + printf("dealing with '%s'...\n", result->filename); + free(suffix); if (!mkpath(result->filename)) @@ -318,7 +319,7 @@ GCdbArchive *g_cdb_archive_new(const char *owner, const rle_string *hash, const g_cdb_archive_create_xml_desc(result, user); g_cdb_archive_create_db(result, NULL); - if (!g_cdb_archive_write(result)) + if (g_cdb_archive_write(result) != DBE_NONE) goto gcan_error; } @@ -473,13 +474,13 @@ static bool g_cdb_archive_read(GCdbArchive *archive) * * ******************************************************************************/ -bool g_cdb_archive_write(const GCdbArchive *archive) +DBError g_cdb_archive_write(const GCdbArchive *archive) { - bool result; /* Conclusion à retourner */ + DBError result; /* Conclusion à retourner */ struct archive *out; /* Archive à constituer */ int ret; /* Bilan d'un appel */ - result = false; + result = DBE_ARCHIVE_ERROR; out = archive_write_new(); archive_write_add_filter_xz(out); @@ -488,16 +489,19 @@ bool g_cdb_archive_write(const GCdbArchive *archive) ret = archive_write_open_filename(out, archive->filename); if (ret != ARCHIVE_OK) goto gcaw_exit; - bool add_file_to_archive(struct archive *out, const char *src, const char *path) + DBError add_file_to_archive(struct archive *out, const char *src, const char *path) { + DBError status; /* Bilan à renvoyer */ struct stat info; /* Informations d'origine */ struct archive_entry *entry; /* Elément de l'archive */ int fd; /* Flux ouvert en lecture */ char buffer[ARCHIVE_RBUF_SIZE]; /* Tampon pour les transferts */ ssize_t len; /* Quantité de données lues */ + status = DBE_ARCHIVE_ERROR; + ret = stat(src, &info); - if (ret != 0) return false; + if (ret != 0) return DBE_SYS_ERROR; entry = archive_entry_new(); @@ -508,7 +512,11 @@ bool g_cdb_archive_write(const GCdbArchive *archive) if (ret != 0) goto afta_error; fd = open(src, O_RDONLY); - if (fd == -1) goto afta_error; + if (fd == -1) + { + status = DBE_SYS_ERROR; + goto afta_error; + } for (len = safe_read(fd, buffer, ARCHIVE_RBUF_SIZE); len > 0; @@ -522,18 +530,20 @@ bool g_cdb_archive_write(const GCdbArchive *archive) archive_entry_free(entry); - return true; + return DBE_NONE; afta_error: archive_entry_free(entry); - return false; + return status; } result = add_file_to_archive(out, archive->xml_desc, "desc.xml"); - result &= add_file_to_archive(out, archive->sql_db, "sql.db"); + + if (result == DBE_NONE) + result = add_file_to_archive(out, archive->sql_db, "sql.db"); gcaw_exit: @@ -781,6 +791,7 @@ static void *g_cdb_archive_process(GCdbArchive *archive) uint32_t val32; /* Valeur sur 32 bits */ bool status; /* Bilan de lecture initiale */ uint32_t command; /* Commande de la requête */ + DBError error; /* Bilan d'une opération */ GDbCollection *collec; /* Collection visée au final */ void interrupt_poll_with_sigusr1(int sig) { }; @@ -843,6 +854,18 @@ static void *g_cdb_archive_process(GCdbArchive *archive) switch (command) { + case DBC_SAVE: + + error = g_cdb_archive_write(archive); + + if (!safe_send(fds[i].fd, (uint32_t []) { htobe32(DBC_SAVE) }, sizeof(uint32_t), 0)) + goto gcap_bad_exchange; + + if (!safe_send(fds[i].fd, (uint32_t []) { htobe32(error) }, sizeof(uint32_t), 0)) + goto gcap_bad_exchange; + + break; + case DBC_COLLECTION: status = safe_recv(fds[i].fd, &val32, sizeof(uint32_t), 0); @@ -851,7 +874,7 @@ static void *g_cdb_archive_process(GCdbArchive *archive) collec = find_collection_in_list(archive->collections, be32toh(val32)); if (collec == NULL) goto gcap_bad_exchange; - status = g_db_collection_recv(collec, fds[i].fd); + status = g_db_collection_recv(collec, fds[i].fd, archive->db); if (!status) goto gcap_bad_exchange; printf("## CDB ## Got something for collection %p...\n", collec); diff --git a/src/analysis/db/cdb.h b/src/analysis/db/cdb.h index 17327f5..e9abb02 100644 --- a/src/analysis/db/cdb.h +++ b/src/analysis/db/cdb.h @@ -60,7 +60,7 @@ GType g_cdb_archive_get_type(void); GCdbArchive *g_cdb_archive_new(const char *, const rle_string *, const rle_string *, DBError *); /* Enregistre une archive avec tous les éléments à conserver. */ -bool g_cdb_archive_write(const GCdbArchive *); +DBError g_cdb_archive_write(const GCdbArchive *); /* Détermine si une empreinte correspond à celle d'une archive. */ int g_cdb_archive_compare_hash(const GCdbArchive *, const rle_string *); diff --git a/src/analysis/db/client.c b/src/analysis/db/client.c index 4b807ae..71df99c 100644 --- a/src/analysis/db/client.c +++ b/src/analysis/db/client.c @@ -328,6 +328,7 @@ static void *g_db_client_update(GDbClient *client) uint32_t val32; /* Valeur sur 32 bits */ bool status; /* Bilan d'une opération */ uint32_t command; /* Commande de la requête */ + DBError error; /* Bilan d'une commande passée */ GDbCollection *collec; /* Collection visée au final */ fds.fd = client->fd; @@ -353,6 +354,19 @@ static void *g_db_client_update(GDbClient *client) switch (command) { + case DBC_SAVE: + + status = safe_recv(fds.fd, &val32, sizeof(uint32_t), 0); + if (!status) goto gdcu_bad_exchange; + + error = be32toh(val32); + + printf("## CLIENT ## Saved ? %d\n", error); + + + + break; + case DBC_COLLECTION: status = safe_recv(fds.fd, &val32, sizeof(uint32_t), 0); @@ -361,7 +375,7 @@ static void *g_db_client_update(GDbClient *client) collec = find_collection_in_list(client->collections, be32toh(val32)); if (collec == NULL) goto gdcu_bad_exchange; - status = g_db_collection_recv(collec, fds.fd); + status = g_db_collection_recv(collec, fds.fd, NULL); if (!status) goto gdcu_bad_exchange; @@ -459,3 +473,30 @@ void g_db_client_put_fd(GDbClient *client) g_mutex_unlock(&client->sending_lock); } + + +/****************************************************************************** +* * +* Paramètres : client = client pour les accès distants à manipuler. * +* * +* Description : Effectue une demande de sauvegarde de l'état courant. * +* * +* Retour : true si la commande a bien été envoyée, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_db_client_save(GDbClient *client) +{ + bool result; /* Bilan partiel à remonter */ + + g_db_client_get_fd(client); + + result = safe_send(client->fd, (uint32_t []) { htobe32(DBC_SAVE) }, sizeof(uint32_t), 0); + + g_db_client_put_fd(client); + + return result; + +} diff --git a/src/analysis/db/client.h b/src/analysis/db/client.h index a1a9f8e..963744b 100644 --- a/src/analysis/db/client.h +++ b/src/analysis/db/client.h @@ -65,6 +65,9 @@ int g_db_client_get_fd(GDbClient *); /* Marque le canal de communication comme disponible. */ void g_db_client_put_fd(GDbClient *); +/* Effectue une demande de sauvegarde de l'état courant. */ +bool g_db_client_save(GDbClient *); + #endif /* _ANALYSIS_DB_CLIENT_H */ diff --git a/src/analysis/db/collection.c b/src/analysis/db/collection.c index 20b1ff3..5c25720 100644 --- a/src/analysis/db/collection.c +++ b/src/analysis/db/collection.c @@ -24,6 +24,11 @@ #include "collection.h" +#include <stdio.h> +#include <string.h> + + +#include "../../common/extstr.h" #include "../../common/io.h" #include "../../glibext/chrysamarshal.h" @@ -36,6 +41,7 @@ struct _GDbCollection 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 */ @@ -71,6 +77,15 @@ static void g_db_collection_finalize(GDbCollection *); +/* --------------------- MANIPULATIONS AVEC UNE BASE DE DONNEES --------------------- */ + + +/* Enregistre un élément de collection dans une base de données. */ +static bool g_db_collection_store_item(const GDbCollection *, const GDbItem *, sqlite3 *); + + + + /* Indique le type défini pour une collection générique d'éléments. */ G_DEFINE_TYPE(GDbCollection, g_db_collection, G_TYPE_OBJECT); @@ -170,7 +185,8 @@ static void g_db_collection_finalize(GDbCollection *collec) /****************************************************************************** * * * Paramètres : id = identifiant réseau des éléments à traiter. * -* type = type GLib des éléments à intégrer dans la collection. * +* type = type GLib des éléments à placer dans la collection. * +* name = indique le nom désignant la table associée. * * * * Description : Prépare la mise en place d'une nouvelle collection. * * * @@ -180,7 +196,7 @@ static void g_db_collection_finalize(GDbCollection *collec) * * ******************************************************************************/ -GDbCollection *g_db_collection_new(uint32_t id, GType type) +GDbCollection *g_db_collection_new(uint32_t id, GType type, const char *name) { GDbCollection *result; /* Adresse à retourner */ @@ -188,6 +204,7 @@ GDbCollection *g_db_collection_new(uint32_t id, GType type) result->featuring = id; result->type = type; + result->name = name; return result; @@ -233,6 +250,7 @@ uint32_t g_db_collection_get_feature(const GDbCollection *collec) * * * Paramètres : collec = ensemble d'éléments à considérer. * * fd = flux ouvert en lecture pour la réception de données.* +* db = base de données à mettre à jour. * * * * Description : Réceptionne et traite une requête réseau pour collection. * * * @@ -244,7 +262,7 @@ uint32_t g_db_collection_get_feature(const GDbCollection *collec) * * ******************************************************************************/ -bool g_db_collection_recv(GDbCollection *collec, int fd) +bool g_db_collection_recv(GDbCollection *collec, int fd, sqlite3 *db) { bool result; /* Bilan à faire remonter */ uint32_t val32; /* Valeur sur 32 bits */ @@ -269,6 +287,8 @@ bool g_db_collection_recv(GDbCollection *collec, int fd) { case DBA_ADD_ITEM: result = g_db_collection_add_item(collec, item); + if (result && db != NULL) + result = g_db_collection_store_item(collec, item, db); break; case DBA_REM_ITEM: @@ -430,6 +450,10 @@ 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"); + + result = true; } @@ -478,6 +502,138 @@ 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 à considérer. * +* item = élément de collection à enregistrer. * +* db = base de données à mettre à jour. * +* * +* Description : Enregistre un élément de collection dans une base de données.* +* * +* Retour : Bilan de l'exécution de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_db_collection_store_item(const GDbCollection *collec, const GDbItem *item, 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 */ + int index; /* Indice de valeur attachée */ + + if (!g_db_item_prepare_db_statement(item, true, &values, &count)) + return false; + + result = false; + + /* Préparation de la requête */ + + sql = strdup("INSERT INTO "); + sql = stradd(sql, collec->name); + sql = stradd(sql, " ("); + + for (i = 0; i < count; i++) + { + if (i > 0) sql = stradd(sql, ", "); + + sql = stradd(sql, values[i].name); + + } + + sql = stradd(sql, ") VALUES ("); + + for (i = 0; i < count; i++) + { + if (i > 0) sql = stradd(sql, ", "); + + if (values[i].type == SQLITE_RAW) + sql = stradd(sql, values[i].cstring); + else + sql = stradd(sql, "?"); + + } + + sql = stradd(sql, ");"); + + ret = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL); + if (ret != SQLITE_OK) + { + fprintf(stderr, "Can't prepare INSERT statment '%s' (ret=%d): %s\n", sql, ret, sqlite3_errmsg(db)); + goto gdcsi_exit; + } + + /* Attribution des valeurs */ + + index = 1; + + for (i = 0; i < count; i++) + { + switch (values[i].type) + { + case SQLITE_INT64: + ret = sqlite3_bind_int64(stmt, index, values[i].integer64); + index++; + break; + + case SQLITE_TEXT: + ret = sqlite3_bind_text(stmt, index, values[i].string, -1, values[i].delete); + index++; + break; + + default: + ret = SQLITE_OK; + break; + + } + + if (ret != SQLITE_OK) + { + fprintf(stderr, "Can't bind value for parameter nb %d in '%s' (ret=%d): %s\n", + index - 1, sql, ret, sqlite3_errmsg(db)); + goto gdcsi_exit; + } + + } + + /* Exécution finale */ + + ret = sqlite3_step(stmt); + + if (ret != SQLITE_DONE) + { + fprintf(stderr, "INSERT statement '%s' didn't return DONE (ret=%d): %s\n", sql, ret, sqlite3_errmsg(db)); + goto gdcsi_exit; + } + + sqlite3_finalize(stmt); + + result = true; + + gdcsi_exit: + + free(sql); + + printf("INSERT ? %d\n", result); + + return result; + +} + + + + +/* ---------------------------------------------------------------------------------- */ +/* CREATION DE L'ABSTRACTION POUR COLLECTIONS */ /* ---------------------------------------------------------------------------------- */ diff --git a/src/analysis/db/collection.h b/src/analysis/db/collection.h index 75ee7df..b400820 100644 --- a/src/analysis/db/collection.h +++ b/src/analysis/db/collection.h @@ -26,6 +26,8 @@ #include <glib-object.h> +#include <sqlite3.h> +#include <stdbool.h> #include <stdint.h> @@ -52,7 +54,7 @@ typedef struct _GDbCollectionClass GDbCollectionClass; GType g_db_collection_get_type(void); /* Prépare la mise en place d'une nouvelle collection. */ -GDbCollection *g_db_collection_new(uint32_t, GType); +GDbCollection *g_db_collection_new(uint32_t, GType, const char *); @@ -63,7 +65,7 @@ uint32_t g_db_collection_get_feature(const GDbCollection *); /* Réceptionne et traite une requête réseau pour collection. */ -bool g_db_collection_recv(GDbCollection *, int); +bool g_db_collection_recv(GDbCollection *, int, sqlite3 *); /* Envoie pour traitement une requête réseau pour collection. */ bool g_db_collection_send(GDbCollection *, int, DBAction, GDbItem *); diff --git a/src/analysis/db/item-int.h b/src/analysis/db/item-int.h index b6d8f9c..0f75ed4 100644 --- a/src/analysis/db/item-int.h +++ b/src/analysis/db/item-int.h @@ -32,12 +32,20 @@ + + + + + /* Importe la définition d'une base d'éléments pour collection. */ typedef bool (* recv_db_item_fc) (GDbItem *, int, int); /* Exporte la définition d'une base d'éléments pour collection. */ typedef bool (* send_db_item_fc) (const GDbItem *, int, int); +/* Constitue les champs destinés à une insertion / modification. */ +typedef bool (* prepare_db_statement) (const GDbItem *, bool, bound_value **, size_t *); + /* Base d'un élément pour collection générique (instance) */ struct _GDbItem @@ -61,6 +69,8 @@ struct _GDbItemClass recv_db_item_fc recv; /* Réception depuis le réseau */ send_db_item_fc send; /* Emission depuis le réseau */ + prepare_db_statement prepare_stmt; /* Préparation d'une requête */ + }; diff --git a/src/analysis/db/item.c b/src/analysis/db/item.c index e2fd7f3..7fa1a52 100644 --- a/src/analysis/db/item.c +++ b/src/analysis/db/item.c @@ -24,8 +24,13 @@ #include "item.h" +#include <malloc.h> +#include <sqlite3.h> + + #include "item-int.h" #include "../../common/io.h" +#include "../../core/params.h" @@ -52,6 +57,13 @@ static bool g_db_item_send_to_fd(const GDbItem *, int, int); +/* --------------------- MANIPULATIONS AVEC UNE BASE DE DONNEES --------------------- */ + + +/* Constitue les champs destinés à une insertion / modification. */ +static bool _g_db_item_prepare_db_statement(const GDbItem *, bool, bound_value **, size_t *); + + /* Indique le type défini pour une base d'élément de collection générique. */ G_DEFINE_TYPE(GDbItem, g_db_item, G_TYPE_OBJECT); @@ -83,6 +95,8 @@ static void g_db_item_class_init(GDbItemClass *klass) klass->recv = (recv_db_item_fc)g_db_item_recv_from_fd; klass->send = (send_db_item_fc)g_db_item_send_to_fd; + klass->prepare_stmt = (prepare_db_statement)_g_db_item_prepare_db_statement; + } @@ -354,3 +368,82 @@ bool g_db_item_is_volatile(const GDbItem *item) return item->is_volatile; } + + + +/* ---------------------------------------------------------------------------------- */ +/* MANIPULATIONS AVEC UNE BASE DE DONNEES */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : item = base d'éléments sur laquelle s'appuyer. * +* create = indique si la préparation vise une création ou non. * +* 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 : Bilan de l'opération : succès ou non. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool _g_db_item_prepare_db_statement(const GDbItem *item, bool create, bound_value **values, size_t *count) +{ + char *author; /* Identification à diffuser */ + bound_value *value; /* Valeur à éditer / définir */ + + if (!g_generic_config_get_value(get_main_configuration(), MPK_AUTHOR_NAME, &author)) + return false; + + *values = (bound_value *)realloc(*values, ++(*count) * sizeof(bound_value)); + value = &(*values)[*count - 1]; + + value->name = "user"; + value->type = SQLITE_TEXT; + value->string = author; + value->delete = free; + + if (!create) + { + *values = (bound_value *)realloc(*values, ++(*count) * sizeof(bound_value)); + value = &(*values)[*count - 1]; + + value->name = "modified"; + value->type = SQLITE_RAW; + value->string = "CURRENT_TIMESTAMP"; + value->delete = SQLITE_STATIC; + + } + + return true; + +} + + +/****************************************************************************** +* * +* Paramètres : item = base d'éléments sur laquelle s'appuyer. * +* create = indique si la préparation vise une création ou non. * +* 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 : Bilan de l'opération : succès ou non. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_db_item_prepare_db_statement(const GDbItem *item, bool create, bound_value **values, size_t *count) +{ + *values = NULL; + *count = 0; + + return G_DB_ITEM_GET_CLASS(item)->prepare_stmt(item, create, values, count); + +} diff --git a/src/analysis/db/item.h b/src/analysis/db/item.h index 3938610..2f8ee60 100644 --- a/src/analysis/db/item.h +++ b/src/analysis/db/item.h @@ -29,6 +29,9 @@ #include <stdbool.h> +#include "../../common/sqlite.h" + + #define G_TYPE_DB_ITEM g_db_item_get_type() #define G_DB_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_db_item_get_type(), GDbItem)) @@ -65,4 +68,19 @@ bool g_db_item_is_volatile(const GDbItem *); +/* --------------------- MANIPULATIONS AVEC UNE BASE DE DONNEES --------------------- */ + + +/* Définition du tronc commun pour les créations SQLite */ +#define SQLITE_DB_ITEM_CREATE \ + "user TEXT, " \ + "created TIMESTAMP DEFAULT CURRENT_TIMESTAMP, " \ + "modified TIMESTAMP DEFAULT CURRENT_TIMESTAMP, " + + +/* Constitue les champs destinés à une insertion / modification. */ +bool g_db_item_prepare_db_statement(const GDbItem *, bool, bound_value **, size_t *); + + + #endif /* _ANALYSIS_DB_ITEM_H */ diff --git a/src/analysis/db/items/bookmark.c b/src/analysis/db/items/bookmark.c index c28a837..6ff386c 100644 --- a/src/analysis/db/items/bookmark.c +++ b/src/analysis/db/items/bookmark.c @@ -75,6 +75,9 @@ static bool g_db_bookmark_recv_from_fd(GDbBookmark *, int, int); /* Exporte la définition d'un signet dans un flux réseau. */ static bool g_db_bookmark_send_to_fd(const GDbBookmark *, int, int); +/* Constitue les champs destinés à une insertion / modification. */ +static bool g_db_bookmark_prepare_db_statement(const GDbBookmark *, bool, bound_value **, size_t *); + @@ -97,10 +100,8 @@ bool create_bookmark_db_table(sqlite3 *db) char *msg; /* Message d'erreur */ sql = "CREATE TABLE Bookmarks (" \ - "id INT PRIMARY KEY NOT NULL, " \ - "user TEXT NOT NULL, " \ - "created INT NOT NULL, " \ - "address INT NOT NULL, " \ + SQLITE_DB_ITEM_CREATE \ + SQLITE_VMPA_CREATE \ "comment TEXT" \ ");"; @@ -157,6 +158,8 @@ static void g_db_bookmark_class_init(GDbBookmarkClass *klass) item->recv = (recv_db_item_fc)g_db_bookmark_recv_from_fd; item->send = (send_db_item_fc)g_db_bookmark_send_to_fd; + item->prepare_stmt = (prepare_db_statement)g_db_bookmark_prepare_db_statement; + } @@ -235,13 +238,7 @@ GDbBookmark *g_db_bookmark_new(const vmpa2t *addr, const char *comment) result = g_object_new(G_TYPE_DB_BOOKMARK, NULL); - - - - /* TODO */ - - //dup addr; - + copy_vmpa(&result->addr, addr); g_db_bookmark_set_comment(result, comment); @@ -351,6 +348,46 @@ static bool g_db_bookmark_send_to_fd(const GDbBookmark *bookmark, int fd, int fl } +/****************************************************************************** +* * +* Paramètres : item = base d'éléments sur laquelle s'appuyer. * +* create = indique si la préparation vise une création ou non. * +* 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_bookmark_prepare_db_statement(const GDbBookmark *bookmark, bool create, bound_value **values, size_t *count) +{ + bool status; /* Bilan d'opération initiale */ + bound_value *value; /* Valeur à éditer / définir */ + + status = G_DB_ITEM_CLASS(g_db_bookmark_parent_class)->prepare_stmt(G_DB_ITEM(bookmark), create, values, count); + if (!status) return false; + + status = prepare_vmpa_db_statement(&bookmark->addr, create, values, count); + if (!status) return false; + + *values = (bound_value *)realloc(*values, ++(*count) * sizeof(bound_value)); + value = &(*values)[*count - 1]; + + value->name = "comment"; + value->type = SQLITE_TEXT; + value->cstring = g_db_bookmark_get_comment(bookmark); + value->delete = SQLITE_STATIC; + + return true; + +} + + + @@ -370,7 +407,7 @@ static bool g_db_bookmark_send_to_fd(const GDbBookmark *bookmark, int fd, int fl * * ******************************************************************************/ -vmpa2t *g_db_bookmark_get_address(GDbBookmark *bookmark) +const vmpa2t *g_db_bookmark_get_address(GDbBookmark *bookmark) { return &bookmark->addr; diff --git a/src/analysis/db/items/bookmark.h b/src/analysis/db/items/bookmark.h index d1b073c..cd5e202 100644 --- a/src/analysis/db/items/bookmark.h +++ b/src/analysis/db/items/bookmark.h @@ -66,7 +66,7 @@ GType g_db_bookmark_get_type(void); GDbBookmark *g_db_bookmark_new(const vmpa2t *, const char *); /* Fournit l'adresse associée à un signet. */ -vmpa2t *g_db_bookmark_get_address(GDbBookmark *); +const vmpa2t *g_db_bookmark_get_address(GDbBookmark *); /* Fournit le commentaire associé à un signet. */ const char *g_db_bookmark_get_comment(const GDbBookmark *); diff --git a/src/analysis/db/protocol.h b/src/analysis/db/protocol.h index 05b559e..85d44cb 100644 --- a/src/analysis/db/protocol.h +++ b/src/analysis/db/protocol.h @@ -113,6 +113,7 @@ typedef enum _DBCommand { DBC_HELO, /* Connexion initiale C -> S */ DBC_WELCOME, /* Réponse initiale S -> C */ + DBC_SAVE, /* Enregistrement de l'archive */ DBC_COLLECTION, /* Implication d'une collection*/ DBC_COUNT @@ -132,6 +133,8 @@ typedef enum _DBError { DBE_NONE, /* Succès d'une opération */ DBE_WRONG_VERSION, /* Proto Client != Serveur */ + DBE_SYS_ERROR, /* Erreur suite à un appel sys.*/ + DBE_ARCHIVE_ERROR, /* Soucis du côté libarchive */ DBE_COUNT @@ -141,6 +144,30 @@ typedef enum _DBError +/** + * Gestion de la commande 'DBC_SAVE'. + * + * Le client connecté envoie un paquet de la forme suivante : + * + * [ Ordre de sauvegarde : DBC_SAVE ] + * + * Le serveur s'exécute et renvoie un bilan : + * + * [ Ordre de sauvegarde : DBC_SAVE ] + * [ Statut d'exécution ; cf. DBError ] + * + * Les traitements se réalisent dans : + * - g_db_client_save() pour la partie client en émission. + * - g_cdb_archive_process() pour la partie serveur. + * - g_db_client_update() pour la partie client en réception. + * + */ + + + + + + |