From 86ba53836168bcc591f532f2419fa290de601572 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Wed, 8 May 2019 11:28:58 +0200 Subject: Updated the core functions dealing with SQLite databases. --- src/analysis/db/collection.c | 291 +++++------------------------ src/analysis/db/item-int.h | 8 +- src/analysis/db/item.c | 113 +++++++----- src/analysis/db/item.h | 6 +- src/analysis/db/items/bookmark.c | 74 ++++---- src/analysis/db/items/comment.c | 183 +++++++++++-------- src/analysis/db/items/move.c | 80 ++++---- src/analysis/db/items/switcher.c | 129 +++++++------ src/analysis/db/misc/rlestr.c | 101 ++++------- src/analysis/db/misc/rlestr.h | 9 +- src/analysis/db/misc/timestamp.c | 69 +++---- src/analysis/db/misc/timestamp.h | 9 +- src/arch/vmpa.c | 81 +++------ src/arch/vmpa.h | 5 +- src/common/sqlite.c | 382 +++++++++++++++++++++++++++++++++++++++ src/common/sqlite.h | 12 ++ src/glibext/gbinarycursor.c | 38 +--- src/glibext/gbinarycursor.h | 4 +- src/glibext/glinecursor-int.h | 8 +- src/glibext/glinecursor.c | 6 +- src/glibext/glinecursor.h | 2 +- 21 files changed, 885 insertions(+), 725 deletions(-) diff --git a/src/analysis/db/collection.c b/src/analysis/db/collection.c index 0a617f3..cdc91aa 100644 --- a/src/analysis/db/collection.c +++ b/src/analysis/db/collection.c @@ -67,6 +67,9 @@ static bool _g_db_collection_setup_load(GDbCollection *, bound_value **, size_t /* Décrit les colonnes utiles à un chargement de données. */ static bool g_db_collection_setup_load(GDbCollection *, bound_value **, size_t *); +/* Charge et intère un élément dans une collection. */ +static bool g_db_collection_load_new_item(const bound_value *, size_t, GDbCollection *); + /* Enregistre un élément de collection dans une base de données. */ static bool g_db_collection_store_item(const GDbCollection *, const GDbItem *, sqlite3 *); @@ -961,16 +964,16 @@ bool g_db_collection_create_db_table(const GDbCollection *collec, sqlite3 *db) static bool _g_db_collection_setup_load(GDbCollection *collec, bound_value **values, size_t *count) { - if (!setup_load_of_timestamp(NULL, "created", values, count)) + if (!store_timestamp(NULL, "created", values, count)) return false; - if (!setup_load_of_timestamp(NULL, "timestamp", values, count)) + if (!store_timestamp(NULL, "timestamp", values, count)) return false; - if (!setup_load_of_rle_string(NULL, "author", values, count)) + if (!store_rle_string(NULL, "author", values, count)) return false; - if (!setup_load_of_rle_string(NULL, "tool", values, count)) + if (!store_rle_string(NULL, "tool", values, count)) return false; return true; @@ -1004,157 +1007,63 @@ static bool g_db_collection_setup_load(GDbCollection *collec, bound_value **valu /****************************************************************************** * * -* Paramètres : collec = ensemble d'éléments à peupler. * -* db = base de données repondant aux requêtes. * +* Paramètres : values = couples de champs et de valeurs à lier. * +* count = nombre de ces couples. * +* collec = collection à manipuler. * * * -* Description : Charge un ensemble d'éléments à partir d'une base de données.* +* Description : Charge et intère un élément dans une collection. * * * -* Retour : Bilan de l'exécution de l'opération. * +* Retour : Bilan de l'opération : succès ou non. * * * * Remarques : - * * * ******************************************************************************/ -bool g_db_collection_load_all_items(GDbCollection *collec, sqlite3 *db) +static bool g_db_collection_load_new_item(const bound_value *values, size_t count, GDbCollection *collec) { - 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 native_type; /* Type de valeur dans la base */ + bool result; /* Bilan à retourner */ GDbItem *new; /* Nouvel élément à insérer */ - result = false; - - if (!g_db_collection_setup_load(collec, &values, &count)) - goto gdclai_building_values; - - /* Préparation de la requête */ + new = g_object_new(G_DB_COLLECTION(collec)->type, NULL); - sql = strdup("SELECT "); + result = g_db_item_load(new, values, count); - for (i = 0; i < count; i++) + if (result) { - if (i > 0) sql = stradd(sql, ", "); + result = g_db_collection_add_item(G_DB_COLLECTION(collec), new); - sql = stradd(sql, values[i].name); + g_object_unref(G_OBJECT(new)); } - 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++) - { - native_type = sqlite3_column_type(stmt, i); - - /** - * On réalise une petite conversion selon le champ. - * - * Le filtre SQLITE_NATIVE est destiné à conserver le type choisi par - * SQLite. Typiquement, une chaîne peut être à SQLITE_NULL ou SQLITE_TEXT - * selon la valeur conservée dans la base. - * - * D'autres éléments, comme les localisations en mémoire, peuvent aussi - * avoir un champ éventuellement nul, donc la définition à partir des - * indications de la base de données reste importante. - * - * En ce qui concerne les valeurs numériques, SQLite ne fait pas de - * distinction : tout passe par la fonction sqlite3VdbeIntValue(), - * qui effectue des transtypages au besoin pour tout ce qui n'est - * pas numérique. - * - * Pour les types internes SQLITE_INTEGER et SQLITE_BOOLEAN, - * il est donc nécessaire d'ajuster en interne. - */ - - if (native_type == SQLITE_INTEGER) - native_type = SQLITE_INT64; - - if (values[i].type == SQLITE_NATIVE) - values[i].type = native_type; - - else - assert(values[i].type == native_type - || values[i].type == SQLITE_INTEGER - || values[i].type == SQLITE_BOOLEAN); - - switch (values[i].type) - { - case SQLITE_BOOLEAN: - values[i].boolean = (bool)sqlite3_column_int(stmt, i); - break; - - case SQLITE_INTEGER: - values[i].integer = sqlite3_column_int(stmt, i); - break; - - case SQLITE_INT64: - values[i].integer64 = sqlite3_column_int64(stmt, i); - break; - - case SQLITE_FLOAT: - assert(0); - break; - - case SQLITE_TEXT: - values[i].cstring = (const char *)sqlite3_column_text(stmt, i); - break; - - case SQLITE_BLOB: - assert(0); - break; - - case SQLITE_NULL: - break; - - default: - assert(0); - break; - - } - - } - - /* Chargement d'un nouvel élément */ - - new = g_object_new(G_DB_COLLECTION(collec)->type, NULL); - - result = g_db_item_load(new, values, count); - result &= g_db_collection_add_item(G_DB_COLLECTION(collec), new); - - g_object_unref(G_OBJECT(new)); + return result; - } +} - /* Sortie propre */ - sqlite3_finalize(stmt); +/****************************************************************************** +* * +* 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 : - * +* * +******************************************************************************/ - gdclai_exit: +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 */ - free(sql); + result = g_db_collection_setup_load(collec, &values, &count); - gdclai_building_values: + if (result) + result = load_db_values(db, collec->name, values, count, (db_load_cb)g_db_collection_load_new_item, collec); free_all_bound_values(values, count); @@ -1182,121 +1091,11 @@ static bool g_db_collection_store_item(const GDbCollection *collec, const GDbIte 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 */ - result = false; - - if (!g_db_item_prepare_db_statement(item, &values, &count)) - goto gdcsi_building_values; - - /* Préparation de la requête */ - - sql = strdup("INSERT INTO "); - sql = stradd(sql, collec->name); - sql = stradd(sql, " ("); + result = g_db_item_store(item, &values, &count); - 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_BOOLEAN: - ret = sqlite3_bind_int(stmt, index, values[i].boolean); - index++; - break; - - case SQLITE_INTEGER: - ret = sqlite3_bind_int(stmt, index, values[i].integer); - index++; - break; - - 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; - - case SQLITE_NULL: - ret = sqlite3_bind_null(stmt, index); - index++; - break; - - default: - assert(false); - ret = SQLITE_ERROR; - 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); - - gdcsi_building_values: + if (result) + result = store_db_values(db, collec->name, values, count); free_all_bound_values(values, count); @@ -1334,7 +1133,7 @@ static bool g_db_collection_store_updated_item(const GDbCollection *collec, cons result = false; - if (!g_db_item_prepare_db_statement(item, &values, &count)) + if (!g_db_item_store(item, &values, &count)) goto gdcsui_building_values; /* Préparation de la requête */ diff --git a/src/analysis/db/item-int.h b/src/analysis/db/item-int.h index 618bab9..3a5f47d 100644 --- a/src/analysis/db/item-int.h +++ b/src/analysis/db/item-int.h @@ -51,12 +51,12 @@ typedef void (* build_item_label_fc) (GDbItem *); /* Exécute un élément de collection sur un binaire. */ typedef bool (* run_item_fc) (GDbItem *, GLoadedBinary *); -/* Constitue les champs destinés à une insertion / modification. */ -typedef bool (* prepare_db_statement) (const GDbItem *, bound_value **, size_t *); - /* Charge les valeurs utiles pour une localisation. */ typedef bool (* load_db_item_fc) (GDbItem *, const bound_value *, size_t); +/* Constitue les champs destinés à une insertion / modification. */ +typedef bool (* store_db_item_fc) (const GDbItem *, bound_value **, size_t *); + /* Base d'un élément pour collection générique (instance) */ struct _GDbItem @@ -91,8 +91,8 @@ struct _GDbItemClass run_item_fc apply; /* Application de l'élément */ run_item_fc cancel; /* Retrait de l'élément */ - prepare_db_statement prepare_stmt; /* Préparation d'une requête */ load_db_item_fc load; /* Chargement à partir d'une BD*/ + store_db_item_fc store; /* Préparation d'une requête */ }; diff --git a/src/analysis/db/item.c b/src/analysis/db/item.c index f01a953..6fa168f 100644 --- a/src/analysis/db/item.c +++ b/src/analysis/db/item.c @@ -58,12 +58,12 @@ static bool _g_db_item_pack(const GDbItem *, packed_buffer *); /* --------------------- MANIPULATIONS AVEC UNE BASE DE DONNEES --------------------- */ -/* Constitue les champs destinés à une insertion / modification. */ -static bool _g_db_item_prepare_db_statement(const GDbItem *, bound_value **, size_t *); - /* Charge les valeurs utiles pour un élément de collection. */ static bool _g_db_item_load(GDbItem *, const bound_value *, size_t); +/* Constitue les champs destinés à une insertion / modification. */ +static bool _g_db_item_store(const GDbItem *, bound_value **, size_t *); + /* Indique le type défini pour une base d'élément de collection générique. */ @@ -96,8 +96,8 @@ static void g_db_item_class_init(GDbItemClass *klass) klass->unpack = (unpack_db_item_fc)_g_db_item_unpack; klass->pack = (pack_db_item_fc)_g_db_item_pack; - klass->prepare_stmt = (prepare_db_statement)_g_db_item_prepare_db_statement; klass->load = (load_db_item_fc)_g_db_item_load; + klass->store = (store_db_item_fc)_g_db_item_store; } @@ -616,31 +616,31 @@ bool g_db_item_is_volatile(const GDbItem *item) /****************************************************************************** * * -* Paramètres : item = base d'éléments sur laquelle s'appuyer. * -* values = couples de champs et de valeurs à lier. [OUT] * -* count = nombre de ces couples. [OUT] * +* Paramètres : item = base d'éléments à charger depuis les réponses. * +* values = tableau d'éléments à consulter. * +* count = nombre de descriptions renseignées. * * * -* Description : Constitue les champs destinés à une insertion / modification.* +* Description : Charge les valeurs utiles pour un élément de collection. * * * -* Retour : Bilan de l'opération : succès ou non. * +* Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ -static bool _g_db_item_prepare_db_statement(const GDbItem *item, bound_value **values, size_t *count) +static bool _g_db_item_load(GDbItem *item, const bound_value *values, size_t count) { - bool result; /* Bilan à retourner */ + bool result; /* Bilan global à retourner */ result = true; - result &= prepare_db_statement_for_timestamp(&item->created, "created", values, count); + result &= load_timestamp(&item->created, "created", values, count); - result &= prepare_db_statement_for_timestamp(&item->timestamp, "timestamp", values, count); + result &= load_timestamp(&item->timestamp, "timestamp", values, count); - result &= prepare_db_statement_for_rle_string(&item->author, "author", values, count); + result &= load_rle_string(&item->author, "author", values, count); - result &= prepare_db_statement_for_rle_string(&item->tool, "tool", values, count); + result &= load_rle_string(&item->tool, "tool", values, count); return result; @@ -649,55 +649,75 @@ static bool _g_db_item_prepare_db_statement(const GDbItem *item, bound_value **v /****************************************************************************** * * -* Paramètres : item = base d'éléments sur laquelle s'appuyer. * -* values = couples de champs et de valeurs à lier. [OUT] * -* count = nombre de ces couples. [OUT] * +* Paramètres : item = base d'éléments à charger depuis les réponses. * +* values = tableau d'éléments à consulter. * +* count = nombre de descriptions renseignées. * * * -* Description : Constitue les champs destinés à une insertion / modification.* +* Description : Charge les valeurs utiles pour un élément de collection. * * * -* Retour : Bilan de l'opération : succès ou non. * +* Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ -bool g_db_item_prepare_db_statement(const GDbItem *item, bound_value **values, size_t *count) +bool g_db_item_load(GDbItem *item, const bound_value *values, size_t count) { - *values = NULL; - *count = 0; + bool result; /* Bilan à retourner */ + + result = G_DB_ITEM_GET_CLASS(item)->load(item, values, count); - return G_DB_ITEM_GET_CLASS(item)->prepare_stmt(item, values, count); + return result; } /****************************************************************************** * * -* Paramètres : item = base d'éléments à charger depuis les réponses. * -* values = tableau d'éléments à consulter. * -* count = nombre de descriptions renseignées. * +* Paramètres : item = base d'éléments sur laquelle s'appuyer. * +* values = couples de champs et de valeurs à lier. [OUT] * +* count = nombre de ces couples. [OUT] * * * -* Description : Charge les valeurs utiles pour un élément de collection. * +* Description : Constitue les champs destinés à une insertion / modification.* * * -* Retour : Bilan de l'opération. * +* Retour : Bilan de l'opération : succès ou non. * * * * Remarques : - * * * ******************************************************************************/ -static bool _g_db_item_load(GDbItem *item, const bound_value *values, size_t count) +static bool _g_db_item_store(const GDbItem *item, bound_value **values, size_t *count) { - bool result; /* Bilan global à retourner */ - - result = true; + bool result; /* Bilan à retourner */ - result &= load_timestamp(&item->created, "created", values, count); + if (item == NULL) + result = store_timestamp(NULL, "created", values, count); + else + result = store_timestamp(&item->created, "created", values, count); - result &= load_timestamp(&item->timestamp, "timestamp", values, count); + if (result) + { + if (item == NULL) + result = store_timestamp(NULL, "timestamp", values, count); + else + result = store_timestamp(&item->timestamp, "timestamp", values, count); + } - result &= load_rle_string(&item->author, "author", values, count); + if (result) + { + if (item == NULL) + result = store_rle_string(NULL, "author", values, count); + else + result = store_rle_string(&item->author, "author", values, count); + } - result &= load_rle_string(&item->tool, "tool", values, count); + if (result) + { + if (item == NULL) + result = store_rle_string(NULL, "tool", values, count); + else + result = store_rle_string(&item->tool, "tool", values, count); + } return result; @@ -706,24 +726,23 @@ static bool _g_db_item_load(GDbItem *item, const bound_value *values, size_t cou /****************************************************************************** * * -* Paramètres : item = base d'éléments à charger depuis les réponses. * -* values = tableau d'éléments à consulter. * -* count = nombre de descriptions renseignées. * +* Paramètres : item = base d'éléments sur laquelle s'appuyer. * +* values = couples de champs et de valeurs à lier. [OUT] * +* count = nombre de ces couples. [OUT] * * * -* Description : Charge les valeurs utiles pour un élément de collection. * +* Description : Constitue les champs destinés à une insertion / modification.* * * -* Retour : Bilan de l'opération. * +* Retour : Bilan de l'opération : succès ou non. * * * * Remarques : - * * * ******************************************************************************/ -bool g_db_item_load(GDbItem *item, const bound_value *values, size_t count) +bool g_db_item_store(const GDbItem *item, bound_value **values, size_t *count) { - bool result; /* Bilan à retourner */ - - result = G_DB_ITEM_GET_CLASS(item)->load(item, values, count); + *values = NULL; + *count = 0; - return result; + return G_DB_ITEM_GET_CLASS(item)->store(item, values, count); } diff --git a/src/analysis/db/item.h b/src/analysis/db/item.h index 1cb0a0b..6644507 100644 --- a/src/analysis/db/item.h +++ b/src/analysis/db/item.h @@ -108,12 +108,12 @@ bool g_db_item_is_volatile(const GDbItem *); /* --------------------- MANIPULATIONS AVEC UNE BASE DE DONNEES --------------------- */ -/* Constitue les champs destinés à une insertion / modification. */ -bool g_db_item_prepare_db_statement(const GDbItem *, bound_value **, size_t *); - /* Charge les valeurs utiles pour un élément de collection. */ bool g_db_item_load(GDbItem *, const bound_value *, size_t); +/* Constitue les champs destinés à une insertion / modification. */ +bool g_db_item_store(const GDbItem *, 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 d3010dd..5d6ccfa 100644 --- a/src/analysis/db/items/bookmark.c +++ b/src/analysis/db/items/bookmark.c @@ -93,12 +93,12 @@ static bool g_db_bookmark_apply(GDbBookmark *, GLoadedBinary *); /* Annule un signet sur un tampon de binaire chargé. */ static bool g_db_bookmark_cancel(GDbBookmark *, GLoadedBinary *); -/* Constitue les champs destinés à une insertion / modification. */ -static bool g_db_bookmark_prepare_db_statement(const GDbBookmark *, bound_value **, size_t *); - /* Charge les valeurs utiles pour un signet. */ static bool g_db_bookmark_load(GDbBookmark *, const bound_value *, size_t); +/* Constitue les champs destinés à une insertion / modification. */ +static bool g_db_bookmark_store(const GDbBookmark *, bound_value **, size_t *); + /* ---------------------- DEFINITION DE LA COLLECTION ASSOCIEE ---------------------- */ @@ -186,8 +186,8 @@ static void g_db_bookmark_class_init(GDbBookmarkClass *klass) item->apply = (run_item_fc)g_db_bookmark_apply; item->cancel = (run_item_fc)g_db_bookmark_cancel; - item->prepare_stmt = (prepare_db_statement)g_db_bookmark_prepare_db_statement; item->load = (load_db_item_fc)g_db_bookmark_load; + item->store = (store_db_item_fc)g_db_bookmark_store; } @@ -492,61 +492,73 @@ static bool g_db_bookmark_cancel(GDbBookmark *bookmark, GLoadedBinary *binary) /****************************************************************************** * * -* Paramètres : bookmark = base d'éléments sur laquelle s'appuyer. * -* values = couples de champs et de valeurs à lier. [OUT] * -* count = nombre de ces couples. [OUT] * +* Paramètres : bookmark = bascule d'affichage à charger depuis les réponses.* +* values = tableau d'éléments à consulter. * +* count = nombre de descriptions renseignées. * * * -* Description : Constitue les champs destinés à une insertion / modification.* +* Description : Charge les valeurs utiles pour un signet. * * * -* Retour : Etat du besoin en sauvegarde. * +* Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ -static bool g_db_bookmark_prepare_db_statement(const GDbBookmark *bookmark, bound_value **values, size_t *count) +static bool g_db_bookmark_load(GDbBookmark *bookmark, const bound_value *values, size_t count) { - bool status; /* Bilan d'opération initiale */ + bool result; /* Bilan à faire remonter */ - status = G_DB_ITEM_CLASS(g_db_bookmark_parent_class)->prepare_stmt(G_DB_ITEM(bookmark), values, count); - if (!status) return false; + result = G_DB_ITEM_CLASS(g_db_bookmark_parent_class)->load(G_DB_ITEM(bookmark), values, count); - status = prepare_vmpa_db_statement(&bookmark->addr, NULL, values, count); - if (!status) return false; + result &= load_vmpa(&bookmark->addr, NULL, values, count); - status &= prepare_db_statement_for_rle_string(&bookmark->comment, "comment", values, count); - if (!status) return false; + result &= load_rle_string(&bookmark->comment, "comment", values, count); - return true; + return result; } /****************************************************************************** * * -* Paramètres : bookmark = bascule d'affichage à charger depuis les réponses.* -* values = tableau d'éléments à consulter. * -* count = nombre de descriptions renseignées. * +* Paramètres : bookmark = base d'éléments sur laquelle s'appuyer. * +* values = couples de champs et de valeurs à lier. [OUT] * +* count = nombre de ces couples. [OUT] * * * -* Description : Charge les valeurs utiles pour un signet. * +* Description : Constitue les champs destinés à une insertion / modification.* * * -* Retour : Bilan de l'opération. * +* Retour : Etat du besoin en sauvegarde. * * * * Remarques : - * * * ******************************************************************************/ -static bool g_db_bookmark_load(GDbBookmark *bookmark, const bound_value *values, size_t count) +static bool g_db_bookmark_store(const GDbBookmark *bookmark, bound_value **values, size_t *count) { - bool result; /* Bilan à faire remonter */ + bool status; /* Bilan d'opération initiale */ - result = G_DB_ITEM_CLASS(g_db_bookmark_parent_class)->load(G_DB_ITEM(bookmark), values, count); + if (bookmark == NULL) + status = G_DB_ITEM_CLASS(g_db_bookmark_parent_class)->store(NULL, values, count); + else + status = G_DB_ITEM_CLASS(g_db_bookmark_parent_class)->store(G_DB_ITEM(bookmark), values, count); - result &= load_vmpa(&bookmark->addr, NULL, values, count); + if (!status) return false; - result &= load_rle_string(&bookmark->comment, "comment", values, count); + if (bookmark == NULL) + status = store_vmpa(NULL, NULL, values, count); + else + status = store_vmpa(&bookmark->addr, NULL, values, count); - return result; + if (!status) return false; + + if (bookmark == NULL) + status &= store_rle_string(NULL, "comment", values, count); + else + status &= store_rle_string(&bookmark->comment, "comment", values, count); + + if (!status) return false; + + return true; } @@ -801,10 +813,10 @@ static bool g_bookmark_collection_setup_load(GBookmarkCollection *collec, bound_ values, count); if (!status) return false; - if (!setup_load_for_vmpa(NULL, values, count)) + if (!store_vmpa(NULL, NULL, values, count)) return false; - if (!setup_load_of_rle_string(NULL, "comment", values, count)) + if (!store_rle_string(NULL, "comment", values, count)) return false; return true; diff --git a/src/analysis/db/items/comment.c b/src/analysis/db/items/comment.c index 7eb7906..6ac37fd 100644 --- a/src/analysis/db/items/comment.c +++ b/src/analysis/db/items/comment.c @@ -113,12 +113,12 @@ static bool g_db_comment_apply(GDbComment *, GLoadedBinary *); /* Annule l'impression d'un commentaire dans du code de binaire. */ static bool g_db_comment_cancel(GDbComment *, GLoadedBinary *); -/* Constitue les champs destinés à une insertion / modification. */ -static bool g_db_comment_prepare_db_statement(GDbComment *, bound_value **, size_t *); - /* Charge les valeurs utiles pour un commentaire. */ static bool g_db_comment_load(GDbComment *, const bound_value *, size_t); +/* Constitue les champs destinés à une insertion / modification. */ +static bool g_db_comment_store(GDbComment *, bound_value **, size_t *); + /* Associe un contenu formaté supplémentaire à un commentaire. */ static void g_db_comment_add_rle_string(GDbComment *, const rle_string *); @@ -236,8 +236,8 @@ static void g_db_comment_class_init(GDbCommentClass *klass) item->apply = (run_item_fc)g_db_comment_apply; item->cancel = (run_item_fc)g_db_comment_cancel; - item->prepare_stmt = (prepare_db_statement)g_db_comment_prepare_db_statement; item->load = (load_db_item_fc)g_db_comment_load; + item->store = (store_db_item_fc)g_db_comment_store; } @@ -694,8 +694,7 @@ static bool g_db_comment_run(GDbComment *comment, GLoadedBinary *binary, bool ap if (apply) { comment->old_count = scount; - comment->old_inlined = (GLineGenerator **)realloc(comment->old_inlined, - comment->old_count * sizeof(GLineGenerator *)); + comment->old_inlined = realloc(comment->old_inlined, comment->old_count * sizeof(GLineGenerator *)); } for (i = 0; i < scount && result; i++) @@ -805,7 +804,7 @@ static bool g_db_comment_run(GDbComment *comment, GLoadedBinary *binary, bool ap assert(comment->old_count == 0); comment->old_count = 1; - comment->oldies = (GDbComment **)calloc(comment->old_count, sizeof(GDbComment *)); + comment->oldies = calloc(comment->old_count, sizeof(GDbComment *)); } @@ -876,8 +875,7 @@ static bool g_db_comment_run(GDbComment *comment, GLoadedBinary *binary, bool ap if (apply) { comment->old_count += scount; - comment->oldies = (GDbComment **)realloc(comment->oldies, - comment->old_count * sizeof(GDbComment *)); + comment->oldies = realloc(comment->oldies, comment->old_count * sizeof(GDbComment *)); } for (i = 0; i < scount && result; i++) @@ -970,73 +968,6 @@ static bool g_db_comment_cancel(GDbComment *comment, GLoadedBinary *binary) /****************************************************************************** * * -* 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(GDbComment *comment, bound_value **values, size_t *count) -{ - bool status; /* Bilan d'opération initiale */ - bound_value *value; /* Valeur à éditer / définir */ - rle_string text; /* Texte brut récupéré */ - - 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, NULL, values, count); - if (!status) return false; - - *count += 1; - *values = (bound_value *)realloc(*values, *count * sizeof(bound_value)); - - value = &(*values)[*count - 1]; - - value->cname = "flags"; - value->built_name = false; - value->type = SQLITE_INTEGER; - value->integer = comment->flags; - value->delete = NULL; - - init_dynamic_rle_string(&text, g_db_comment_get_text(comment)); - status &= prepare_db_statement_for_rle_string(&text, "text", values, count); - exit_rle_string(&text); - - if (!status) return false; - - *count += 2; - *values = (bound_value *)realloc(*values, *count * sizeof(bound_value)); - - value = &(*values)[*count - 2]; - - value->cname = "inlined"; - value->built_name = false; - value->type = SQLITE_BOOLEAN; - value->boolean = comment->inlined; - value->delete = NULL; - - value = &(*values)[*count - 1]; - - value->cname = "repeatable"; - value->built_name = false; - value->type = SQLITE_BOOLEAN; - value->boolean = comment->repeatable; - value->delete = NULL; - - return true; - -} - - -/****************************************************************************** -* * * Paramètres : comment = commentaire textuel à charger depuis les réponses. * * values = tableau d'éléments à consulter. * * count = nombre de descriptions renseignées. * @@ -1101,6 +1032,98 @@ static bool g_db_comment_load(GDbComment *comment, const bound_value *values, si /****************************************************************************** * * +* 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_store(GDbComment *comment, bound_value **values, size_t *count) +{ + bool status; /* Bilan d'opération initiale */ + bound_value *value; /* Valeur à éditer / définir */ + rle_string text; /* Texte brut récupéré */ + + if (comment == NULL) + status = G_DB_ITEM_CLASS(g_db_comment_parent_class)->store(NULL, values, count); + else + status = G_DB_ITEM_CLASS(g_db_comment_parent_class)->store(G_DB_ITEM(comment), values, count); + + if (!status) return false; + + if (comment == NULL) + status = store_vmpa(NULL, NULL, values, count); + else + status = store_vmpa(&comment->addr, NULL, values, count); + + if (!status) return false; + + *count += 1; + *values = realloc(*values, *count * sizeof(bound_value)); + + value = &(*values)[*count - 1]; + + value->cname = "flags"; + value->built_name = false; + value->type = SQLITE_INTEGER; + value->integer = comment->flags; + value->delete = NULL; + + value->has_value = (comment != NULL); + + if (value->has_value) + { + init_dynamic_rle_string(&text, g_db_comment_get_text(comment)); + status = store_rle_string(&text, "text", values, count); + exit_rle_string(&text); + } + + if (!status) return false; + + *count += 2; + *values = realloc(*values, *count * sizeof(bound_value)); + + value = &(*values)[*count - 2]; + + value->cname = "inlined"; + value->built_name = false; + value->type = SQLITE_BOOLEAN; + + value->has_value = (comment != NULL); + + if (value->has_value) + { + value->boolean = comment->inlined; + value->delete = NULL; + } + + value = &(*values)[*count - 1]; + + value->cname = "repeatable"; + value->built_name = false; + value->type = SQLITE_BOOLEAN; + + value->has_value = (comment != NULL); + + if (value->has_value) + { + value->boolean = comment->repeatable; + value->delete = NULL; + } + + return true; + +} + + +/****************************************************************************** +* * * Paramètres : comment = informations à consulter. * * * * Description : Fournit l'adresse associée à un commentaire. * @@ -1649,11 +1672,11 @@ static bool g_comment_collection_setup_load(GCommentCollection *collec, bound_va values, count); if (!status) return false; - if (!setup_load_for_vmpa(NULL, values, count)) + if (!store_vmpa(NULL, NULL, values, count)) return false; *count += 1; - *values = (bound_value *)realloc(*values, *count * sizeof(bound_value)); + *values = realloc(*values, *count * sizeof(bound_value)); value = &(*values)[*count - 1]; @@ -1661,11 +1684,11 @@ static bool g_comment_collection_setup_load(GCommentCollection *collec, bound_va value->built_name = false; value->type = SQLITE_INTEGER; - if (!setup_load_of_rle_string(NULL, "text", values, count)) + if (!store_rle_string(NULL, "text", values, count)) return false; *count += 2; - *values = (bound_value *)realloc(*values, *count * sizeof(bound_value)); + *values = realloc(*values, *count * sizeof(bound_value)); value = &(*values)[*count - 2]; diff --git a/src/analysis/db/items/move.c b/src/analysis/db/items/move.c index 6929ec3..286215b 100644 --- a/src/analysis/db/items/move.c +++ b/src/analysis/db/items/move.c @@ -95,12 +95,12 @@ static bool g_db_move_apply(GDbMove *, GLoadedBinary *); /* Annule un déplacement au sein d'une zone de code. */ static bool g_db_move_cancel(GDbMove *, GLoadedBinary *); -/* Constitue les champs destinés à une insertion / modification. */ -static bool g_db_move_prepare_db_statement(const GDbMove *, bound_value **, size_t *); - /* Charge les valeurs utiles pour un déplacement dans du code. */ static bool g_db_move_load(GDbMove *, const bound_value *, size_t); +/* Constitue les champs destinés à une insertion / modification. */ +static bool g_db_move_store(const GDbMove *, bound_value **, size_t *); + /* ---------------------- DEFINITION DE LA COLLECTION ASSOCIEE ---------------------- */ @@ -188,8 +188,8 @@ static void g_db_move_class_init(GDbMoveClass *klass) item->apply = (run_item_fc)g_db_move_apply; item->cancel = (run_item_fc)g_db_move_cancel; - item->prepare_stmt = (prepare_db_statement)g_db_move_prepare_db_statement; item->load = (load_db_item_fc)g_db_move_load; + item->store = (store_db_item_fc)g_db_move_store; } @@ -455,7 +455,7 @@ static bool g_db_move_run(const GDbMove *move, GLineCursor *cursor) if (G_IS_LOADED_PANEL(panel)) { - params = (move_params *)calloc(1, sizeof(move_params)); + params = calloc(1, sizeof(move_params)); params->panel = panel; params->cursor = cursor; @@ -527,63 +527,75 @@ static bool g_db_move_cancel(GDbMove *move, GLoadedBinary *binary) /****************************************************************************** * * -* Paramètres : move = base d'éléments sur laquelle s'appuyer. * -* values = couples de champs et de valeurs à lier. [OUT] * -* count = nombre de ces couples. [OUT] * +* Paramètres : move = bascule d'affichage à charger depuis les réponses. * +* values = tableau d'éléments à consulter. * +* count = nombre de descriptions renseignées. * * * -* Description : Constitue les champs destinés à une insertion / modification.* +* Description : Charge les valeurs utiles pour un déplacement dans du code. * * * -* Retour : Etat du besoin en sauvegarde. * +* Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ -static bool g_db_move_prepare_db_statement(const GDbMove *move, bound_value **values, size_t *count) +static bool g_db_move_load(GDbMove *move, const bound_value *values, size_t count) { - bool status; /* Bilan d'opération initiale */ + bool result; /* Bilan à faire remonter */ - status = G_DB_ITEM_CLASS(g_db_move_parent_class)->prepare_stmt(G_DB_ITEM(move), values, count); - if (!status) return false; + result = G_DB_ITEM_CLASS(g_db_move_parent_class)->load(G_DB_ITEM(move), values, count); - status = g_line_cursor_prepare_db_statement(move->src, "src", values, count); - if (!status) return false; + if (result) + result = g_line_cursor_load(move->src, "src", values, count); - status = g_line_cursor_prepare_db_statement(move->src, "dest", values, count); - if (!status) return false; + if (result) + result = g_line_cursor_load(move->dest, "dest", values, count); - return true; + return result; } /****************************************************************************** * * -* Paramètres : move = bascule d'affichage à charger depuis les réponses. * -* values = tableau d'éléments à consulter. * -* count = nombre de descriptions renseignées. * +* Paramètres : move = base d'éléments sur laquelle s'appuyer. * +* values = couples de champs et de valeurs à lier. [OUT] * +* count = nombre de ces couples. [OUT] * * * -* Description : Charge les valeurs utiles pour un déplacement dans du code. * +* Description : Constitue les champs destinés à une insertion / modification.* * * -* Retour : Bilan de l'opération. * +* Retour : Etat du besoin en sauvegarde. * * * * Remarques : - * * * ******************************************************************************/ -static bool g_db_move_load(GDbMove *move, const bound_value *values, size_t count) +static bool g_db_move_store(const GDbMove *move, bound_value **values, size_t *count) { - bool result; /* Bilan à faire remonter */ + bool status; /* Bilan d'opération initiale */ - result = G_DB_ITEM_CLASS(g_db_move_parent_class)->load(G_DB_ITEM(move), values, count); + if (move == NULL) + status = G_DB_ITEM_CLASS(g_db_move_parent_class)->store(NULL, values, count); + else + status = G_DB_ITEM_CLASS(g_db_move_parent_class)->store(G_DB_ITEM(move), values, count); - if (result) - result = g_line_cursor_load(move->src, "src", values, count); + if (!status) return false; - if (result) - result = g_line_cursor_load(move->dest, "dest", values, count); + if (move == NULL) + status = g_line_cursor_setup_load(move->src, "src", values, count); + else + status = g_line_cursor_store(move->src, "src", values, count); - return result; + if (!status) return false; + + if (move == NULL) + status = g_line_cursor_setup_load(move->dest, "dest", values, count); + else + status = g_line_cursor_store(move->dest, "dest", values, count); + + if (!status) return false; + + return true; } @@ -783,10 +795,10 @@ static bool g_move_collection_setup_load(GMoveCollection *collec, bound_value ** values, count); if (!status) return false; - if (!g_binary_cursor_setup_load("src", values, count)) + if (!g_binary_cursor_store(NULL, "src", values, count)) return false; - if (!g_binary_cursor_setup_load("dest", values, count)) + if (!g_binary_cursor_store(NULL, "dest", values, count)) return false; return true; diff --git a/src/analysis/db/items/switcher.c b/src/analysis/db/items/switcher.c index b4f0379..e086b14 100644 --- a/src/analysis/db/items/switcher.c +++ b/src/analysis/db/items/switcher.c @@ -95,12 +95,11 @@ static bool g_db_switcher_apply(GDbSwitcher *, GLoadedBinary *); /* Annule une bascule d'affichage d'opérande sur un binaire. */ static bool g_db_switcher_cancel(GDbSwitcher *, GLoadedBinary *); -/* Constitue les champs destinés à une insertion / modification. */ -static bool g_db_switcher_prepare_db_statement(const GDbSwitcher *, bound_value **, size_t *); - /* Charge les valeurs utiles pour un basculement d'affichage. */ static bool g_db_switcher_load(GDbSwitcher *, const bound_value *, size_t); +/* Constitue les champs destinés à une insertion / modification. */ +static bool g_db_switcher_store(const GDbSwitcher *, bound_value **, size_t *); @@ -189,8 +188,8 @@ static void g_db_switcher_class_init(GDbSwitcherClass *klass) item->apply = (run_item_fc)g_db_switcher_apply; item->cancel = (run_item_fc)g_db_switcher_cancel; - item->prepare_stmt = (prepare_db_statement)g_db_switcher_prepare_db_statement; item->load = (load_db_item_fc)g_db_switcher_load; + item->store = (store_db_item_fc)g_db_switcher_store; } @@ -638,55 +637,6 @@ static bool g_db_switcher_cancel(GDbSwitcher *switcher, GLoadedBinary *binary) /****************************************************************************** * * -* Paramètres : switcher = 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_switcher_prepare_db_statement(const GDbSwitcher *switcher, 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_switcher_parent_class)->prepare_stmt(G_DB_ITEM(switcher), values, count); - if (!status) return false; - - status = prepare_vmpa_db_statement(&switcher->addr, NULL, values, count); - if (!status) return false; - - *count += 2; - *values = (bound_value *)realloc(*values, *count * sizeof(bound_value)); - - value = &(*values)[*count - 2]; - - value->cname = "op_index"; - value->built_name = false; - value->type = SQLITE_INTEGER; - value->integer = switcher->index; - value->delete = NULL; - - value = &(*values)[*count - 1]; - - value->cname = "type"; - value->built_name = false; - value->type = SQLITE_INTEGER; - value->integer = switcher->display; - value->delete = NULL; - - return true; - -} - - -/****************************************************************************** -* * * Paramètres : switcher = bascule d'affichage à charger depuis les réponses.* * values = tableau d'éléments à consulter. * * count = nombre de descriptions renseignées. * @@ -733,6 +683,75 @@ static bool g_db_switcher_load(GDbSwitcher *switcher, const bound_value *values, } +/****************************************************************************** +* * +* Paramètres : switcher = 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_switcher_store(const GDbSwitcher *switcher, bound_value **values, size_t *count) +{ + bool status; /* Bilan d'opération initiale */ + bound_value *value; /* Valeur à éditer / définir */ + + if (switcher == NULL) + status = G_DB_ITEM_CLASS(g_db_switcher_parent_class)->store(NULL, values, count); + else + status = G_DB_ITEM_CLASS(g_db_switcher_parent_class)->store(G_DB_ITEM(switcher), values, count); + + if (!status) return false; + + if (switcher == NULL) + status = store_vmpa(NULL, NULL, values, count); + else + status = store_vmpa(&switcher->addr, NULL, values, count); + + if (!status) return false; + + *count += 2; + *values = realloc(*values, *count * sizeof(bound_value)); + + value = &(*values)[*count - 2]; + + value->cname = "op_index"; + value->built_name = false; + value->type = SQLITE_INTEGER; + + value->has_value = (switcher != NULL); + + if (value->has_value) + { + value->integer = switcher->index; + value->delete = NULL; + } + + value = &(*values)[*count - 1]; + + value->cname = "type"; + value->built_name = false; + value->type = SQLITE_INTEGER; + + value->has_value = (switcher != NULL); + + if (value->has_value) + { + value->integer = switcher->display; + value->delete = NULL; + } + + return true; + +} + + /* ---------------------------------------------------------------------------------- */ /* DEFINITION DE LA COLLECTION ASSOCIEE */ @@ -927,11 +946,11 @@ static bool g_switcher_collection_setup_load(GSwitcherCollection *collec, bound_ values, count); if (!status) return false; - if (!setup_load_for_vmpa(NULL, values, count)) + if (!store_vmpa(NULL, NULL, values, count)) return false; *count += 2; - *values = (bound_value *)realloc(*values, *count * sizeof(bound_value)); + *values = realloc(*values, *count * sizeof(bound_value)); value = &(*values)[*count - 2]; diff --git a/src/analysis/db/misc/rlestr.c b/src/analysis/db/misc/rlestr.c index 196b934..f26c146 100644 --- a/src/analysis/db/misc/rlestr.c +++ b/src/analysis/db/misc/rlestr.c @@ -326,31 +326,42 @@ bool pack_rle_string(const rle_string *str, packed_buffer *pbuf) /****************************************************************************** * * -* Paramètres : str = chaîne de caractères aux informations inutiles. * +* Paramètres : str = chaîne de caractères à compléter. * * name = désignation personnalisée du champ dans la BD. * -* values = couples de champs et de valeurs à lier. [OUT] * -* count = nombre de ces couples. [OUT] * +* values = tableau d'éléments à consulter. * +* count = nombre de descriptions renseignées. * * * -* Description : Constitue les champs destinés à une insertion / modification.* +* Description : Charge les valeurs utiles pour une chaîne de caractères. * * * -* Retour : Bilan de l'opération : succès ou non. * +* Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ -bool prepare_db_statement_for_rle_string(const rle_string *str, const char *name, bound_value **values, size_t *count) +bool load_rle_string(rle_string *str, const char *name, const bound_value *values, size_t count) { - bound_value *value; /* Valeur à éditer / définir */ + const bound_value *value; /* Valeur à intégrer */ - *values = (bound_value *)realloc(*values, ++(*count) * sizeof(bound_value)); - value = &(*values)[*count - 1]; + value = find_bound_value(values, count, name); + if (value == NULL) return false; - value->cname = name; - value->built_name = false; - value->type = (get_rle_string(str) != NULL ? SQLITE_TEXT : SQLITE_NULL); - value->cstring = get_rle_string(str); - value->delete = SQLITE_STATIC; + switch (value->type) + { + case SQLITE_TEXT: + unset_rle_string(str); + dup_into_rle_string(str, value->cstring); + break; + + case SQLITE_NULL: + unset_rle_string(str); + break; + + default: + return false; + break; + + } return true; @@ -361,71 +372,39 @@ bool prepare_db_statement_for_rle_string(const rle_string *str, const char *name * * * Paramètres : str = chaîne de caractères aux informations inutiles. * * name = désignation personnalisée du champ dans la BD. * -* values = tableau d'éléments à compléter. [OUT] * -* count = nombre de descriptions renseignées. [OUT] * +* values = couples de champs et de valeurs à lier. [OUT] * +* count = nombre de ces couples. [OUT] * * * -* Description : Décrit les colonnes utiles à une chaîne de caractères. * +* Description : Constitue les champs destinés à une insertion / modification.* * * -* Retour : Bilan de l'opération. * +* Retour : Bilan de l'opération : succès ou non. * * * * Remarques : - * * * ******************************************************************************/ -bool setup_load_of_rle_string(const rle_string *str, const char *name, bound_value **values, size_t *count) +bool store_rle_string(const rle_string *str, const char *name, bound_value **values, size_t *count) { bound_value *value; /* Valeur à éditer / définir */ - *values = (bound_value *)realloc(*values, ++(*count) * sizeof(bound_value)); + *values = realloc(*values, ++(*count) * sizeof(bound_value)); + value = &(*values)[*count - 1]; value->cname = name; value->built_name = false; - value->type = SQLITE_NATIVE; - return true; + value->has_value = (str != NULL); + if (value->has_value) + value->type = (get_rle_string(str) != NULL ? SQLITE_TEXT : SQLITE_NULL); + else + value->type = SQLITE_NATIVE; -} - - -/****************************************************************************** -* * -* Paramètres : str = chaîne de caractères à compléter. * -* name = désignation personnalisée du champ dans la BD. * -* values = tableau d'éléments à consulter. * -* count = nombre de descriptions renseignées. * -* * -* Description : Charge les valeurs utiles pour une chaîne de caractères. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool load_rle_string(rle_string *str, const char *name, const bound_value *values, size_t count) -{ - const bound_value *value; /* Valeur à intégrer */ - - value = find_bound_value(values, count, name); - if (value == NULL) return false; - - switch (value->type) + if (value->has_value) { - case SQLITE_TEXT: - unset_rle_string(str); - dup_into_rle_string(str, value->cstring); - break; - - case SQLITE_NULL: - unset_rle_string(str); - break; - - default: - return false; - break; - + value->cstring = get_rle_string(str); + value->delete = SQLITE_STATIC; } return true; diff --git a/src/analysis/db/misc/rlestr.h b/src/analysis/db/misc/rlestr.h index 7b317b6..eb71582 100644 --- a/src/analysis/db/misc/rlestr.h +++ b/src/analysis/db/misc/rlestr.h @@ -94,15 +94,12 @@ bool pack_rle_string(const rle_string *, packed_buffer *); #define SQLITE_RLESTR_CREATE(n) \ n " TEXT" -/* Constitue les champs destinés à une insertion / modification. */ -bool prepare_db_statement_for_rle_string(const rle_string *, const char *, bound_value **, size_t *); - -/* Décrit les colonnes utiles à une chaîne de caractères. */ -bool setup_load_of_rle_string(const rle_string *, const char *, bound_value **, size_t *); - /* Charge les valeurs utiles pour une chaîne de caractères. */ bool load_rle_string(rle_string *, const char *, const bound_value *, size_t); +/* Constitue les champs destinés à une insertion / modification. */ +bool store_rle_string(const rle_string *, const char *, bound_value **, size_t *); + #endif /* _ANALYSIS_DB_MISC_RLESTR_H */ diff --git a/src/analysis/db/misc/timestamp.c b/src/analysis/db/misc/timestamp.c index 5302c60..1d2fcd9 100644 --- a/src/analysis/db/misc/timestamp.c +++ b/src/analysis/db/misc/timestamp.c @@ -166,30 +166,28 @@ bool pack_timestamp(const timestamp_t *timestamp, packed_buffer *pbuf) /****************************************************************************** * * -* Paramètres : timestamp = horodatage aux informations inutiles. * +* Paramètres : timestamp = horodatage à compléter. * * name = désignation personnalisée du champ dans la BD. * -* values = couples de champs et de valeurs à lier. [OUT] * -* count = nombre de ces couples. [OUT] * +* values = tableau d'éléments à consulter. * +* count = nombre de descriptions renseignées. * * * -* Description : Constitue les champs destinés à une insertion / modification.* +* Description : Charge les valeurs utiles pour un horodatage. * * * -* Retour : Bilan de l'opération : succès ou non. * +* Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ -bool prepare_db_statement_for_timestamp(const timestamp_t *timestamp, const char *name, bound_value **values, size_t *count) +bool load_timestamp(timestamp_t *timestamp, const char *name, const bound_value *values, size_t count) { - bound_value *value; /* Valeur à éditer / définir */ + const bound_value *value; /* Valeur à intégrer */ - *values = (bound_value *)realloc(*values, ++(*count) * sizeof(bound_value)); - value = &(*values)[*count - 1]; + value = find_bound_value(values, count, name); + if (value == NULL) return false; + if (value->type != SQLITE_INT64) return false; - value->cname = name; - value->built_name = false; - value->type = SQLITE_INT64; - value->integer64 = *timestamp; + *timestamp = value->integer64; return true; @@ -200,58 +198,33 @@ bool prepare_db_statement_for_timestamp(const timestamp_t *timestamp, const char * * * Paramètres : timestamp = horodatage aux informations inutiles. * * name = désignation personnalisée du champ dans la BD. * -* values = tableau d'éléments à compléter. [OUT] * -* count = nombre de descriptions renseignées. [OUT] * +* values = couples de champs et de valeurs à lier. [OUT] * +* count = nombre de ces couples. [OUT] * * * -* Description : Décrit les colonnes utiles à un horodatage. * +* Description : Constitue les champs destinés à une insertion / modification.* * * -* Retour : Bilan de l'opération. * +* Retour : Bilan de l'opération : succès ou non. * * * * Remarques : - * * * ******************************************************************************/ -bool setup_load_of_timestamp(const timestamp_t *timestamp, const char *name, bound_value **values, size_t *count) +bool store_timestamp(const timestamp_t *timestamp, const char *name, bound_value **values, size_t *count) { bound_value *value; /* Valeur à éditer / définir */ - *values = (bound_value *)realloc(*values, ++(*count) * sizeof(bound_value)); + *values = realloc(*values, ++(*count) * sizeof(bound_value)); + value = &(*values)[*count - 1]; value->cname = name; value->built_name = false; value->type = SQLITE_INT64; - return true; - - -} - - -/****************************************************************************** -* * -* Paramètres : timestamp = horodatage à compléter. * -* name = désignation personnalisée du champ dans la BD. * -* values = tableau d'éléments à consulter. * -* count = nombre de descriptions renseignées. * -* * -* Description : Charge les valeurs utiles pour un horodatage. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool load_timestamp(timestamp_t *timestamp, const char *name, const bound_value *values, size_t count) -{ - const bound_value *value; /* Valeur à intégrer */ - - value = find_bound_value(values, count, name); - if (value == NULL) return false; - if (value->type != SQLITE_INT64) return false; + value->has_value = (timestamp != NULL); - *timestamp = value->integer64; + if (value->has_value) + value->integer64 = *timestamp; return true; diff --git a/src/analysis/db/misc/timestamp.h b/src/analysis/db/misc/timestamp.h index 076a4e0..eba0fa7 100644 --- a/src/analysis/db/misc/timestamp.h +++ b/src/analysis/db/misc/timestamp.h @@ -67,15 +67,12 @@ bool pack_timestamp(const timestamp_t *, packed_buffer *); #define SQLITE_TIMESTAMP_CREATE(n) \ n " INTEGER" -/* Constitue les champs destinés à une insertion / modification. */ -bool prepare_db_statement_for_timestamp(const timestamp_t *, const char *, bound_value **, size_t *); - -/* Décrit les colonnes utiles à un horodatage. */ -bool setup_load_of_timestamp(const timestamp_t *, const char *, bound_value **, size_t *); - /* Charge les valeurs utiles pour un horodatage. */ bool load_timestamp(timestamp_t *, const char *, const bound_value *, size_t); +/* Constitue les champs destinés à une insertion / modification. */ +bool store_timestamp(const timestamp_t *, const char *, bound_value **, size_t *); + #endif /* _ANALYSIS_DB_MISC_TIMESTAMP_H */ diff --git a/src/arch/vmpa.c b/src/arch/vmpa.c index 0c0511b..a2a3ba5 100644 --- a/src/arch/vmpa.c +++ b/src/arch/vmpa.c @@ -715,44 +715,6 @@ char *create_vmpa_db_table(const char *base) /****************************************************************************** * * -* Paramètres : base = tronc commun pour les champs de la base de données. * -* 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 : - * -* * -******************************************************************************/ - -bool setup_load_for_vmpa(const char *base, bound_value **values, size_t *count) -{ - bound_value *value; /* Valeur à éditer / définir */ - - (*count) += 2; - *values = (bound_value *)realloc(*values, (*count) * sizeof(bound_value)); - - value = &(*values)[*count - 2]; - - asprintf(&value->name, "%s%sphys", base != NULL ? base : "", base != NULL ? "_" : ""); - value->built_name = true; - value->type = SQLITE_NATIVE; - - value = &(*values)[*count - 1]; - - asprintf(&value->name, "%s%svirt", base != NULL ? base : "", base != NULL ? "_" : ""); - value->built_name = true; - value->type = SQLITE_NATIVE; - - return true; - -} - - -/****************************************************************************** -* * * Paramètres : addr = localisation dont la définition est à définir. * * base = tronc commun pour les champs de la base de données. * * values = tableau d'éléments à consulter. * @@ -839,40 +801,47 @@ bool load_vmpa(vmpa2t *addr, const char *base, const bound_value *values, size_t * * ******************************************************************************/ -bool prepare_vmpa_db_statement(const vmpa2t *addr, const char *base, bound_value **values, size_t *count) +bool store_vmpa(const vmpa2t *addr, const char *base, bound_value **values, size_t *count) { bound_value *value; /* Valeur à éditer / définir */ - *values = (bound_value *)realloc(*values, ++(*count) * sizeof(bound_value)); - value = &(*values)[*count - 1]; + *count += 2; + *values = realloc(*values, *count * sizeof(bound_value)); + + value = &(*values)[*count - 2]; asprintf(&value->name, "%s%sphys", base != NULL ? base : "", base != NULL ? "_" : ""); value->built_name = true; - if (addr->physical != VMPA_NO_PHYSICAL) - { - value->type = SQLITE_INT64; - value->integer64 = addr->physical; - } - else + value->has_value = (addr != NULL); + + if (value->has_value) { - value->type = SQLITE_NULL; + if (addr->physical != VMPA_NO_PHYSICAL) + { + value->type = SQLITE_INT64; + value->integer64 = addr->physical; + } + else + value->type = SQLITE_NULL; } - *values = (bound_value *)realloc(*values, ++(*count) * sizeof(bound_value)); value = &(*values)[*count - 1]; asprintf(&value->name, "%s%svirt", base != NULL ? base : "", base != NULL ? "_" : ""); value->built_name = true; - if (addr->virtual != VMPA_NO_VIRTUAL) - { - value->type = SQLITE_INT64; - value->integer64 = addr->virtual; - } - else + value->has_value = (addr != NULL); + + if (value->has_value) { - value->type = SQLITE_NULL; + if (addr->virtual != VMPA_NO_VIRTUAL) + { + value->type = SQLITE_INT64; + value->integer64 = addr->virtual; + } + else + value->type = SQLITE_NULL; } return true; diff --git a/src/arch/vmpa.h b/src/arch/vmpa.h index fc997e5..8dfc646 100644 --- a/src/arch/vmpa.h +++ b/src/arch/vmpa.h @@ -145,14 +145,11 @@ vmpa2t *string_to_vmpa_virt(const char *); /* Donne les éléments requis pour la construction d'une table. */ char *create_vmpa_db_table(const char *); -/* Décrit les colonnes utiles à un chargement de données. */ -bool setup_load_for_vmpa(const char *, bound_value **, size_t *); - /* Charge les valeurs utiles pour une localisation. */ bool load_vmpa(vmpa2t *, const char *, const bound_value *, size_t); /* Constitue les champs destinés à une insertion / modification. */ -bool prepare_vmpa_db_statement(const vmpa2t *, const char *, bound_value **, size_t *); +bool store_vmpa(const vmpa2t *, const char *, bound_value **, size_t *); diff --git a/src/common/sqlite.c b/src/common/sqlite.c index a3b97b0..af2af9f 100644 --- a/src/common/sqlite.c +++ b/src/common/sqlite.c @@ -24,10 +24,19 @@ #include "sqlite.h" +#include #include #include +#include "extstr.h" + + + +/* Attribue une définition aux valeurs paramétrées. */ +static bool bind_bound_values(sqlite3 *, sqlite3_stmt *, const char *, const bound_value *, size_t, bool, int *); + + /****************************************************************************** * * @@ -92,3 +101,376 @@ const bound_value *find_bound_value(const bound_value *values, size_t count, con return result; } + + +/****************************************************************************** +* * +* Paramètres : db = base de données à consulter. * +* stmt = requête SQL en préparation à faire évoluer. * +* sql = définition brute de cette requête SQL. * +* values = tableau d'éléments à consulter. * +* count = nombre de descriptions renseignées. * +* has_value = fitre sur la définition des valeurs. * +* index = indice évolutif des valeurs paramétrées. [OUT] * +* * +* Description : Attribue une définition aux valeurs paramétrées. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool bind_bound_values(sqlite3 *db, sqlite3_stmt *stmt, const char *sql, const bound_value *values, size_t count, bool has_value, int *index) +{ + bool result; /* Bilan à retourner */ + size_t i; /* Boucle de parcours */ + int ret; /* Bilan d'un appel à SQLite */ + + result = true; + + for (i = 0; i < count && result; i++) + { + if (values[i].has_value != has_value) + continue; + + switch (values[i].type) + { + case SQLITE_BOOLEAN: + ret = sqlite3_bind_int(stmt, *index, values[i].boolean); + break; + + case SQLITE_INTEGER: + ret = sqlite3_bind_int(stmt, *index, values[i].integer); + break; + + case SQLITE_INT64: + ret = sqlite3_bind_int64(stmt, *index, values[i].integer64); + break; + + case SQLITE_TEXT: + ret = sqlite3_bind_text(stmt, *index, values[i].string, -1, values[i].delete); + break; + + case SQLITE_NULL: + ret = sqlite3_bind_null(stmt, *index); + break; + + default: + assert(false); + ret = SQLITE_ERROR; + break; + + } + + if (ret == SQLITE_OK) + (*index)++; + + else + { + result = false; + + fprintf(stderr, "Can't bind value for parameter nb %d in '%s' (ret=%d): %s\n", + *index, sql, ret, sqlite3_errmsg(db)); + + } + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : db = base de données à consulter. * +* table = nom de la table concernée. * +* values = champs avec leur valeur. * +* count = quantité de ces champs. * +* cb = procédure à appeler pour chaque nouvelle série. * +* data = éventuelles données associées à transmettre. * +* * +* Description : Charge une série de valeurs depuis une base de données. * +* * +* Retour : Bilan de l'exécution de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool load_db_values(sqlite3 *db, const char *table, bound_value *values, size_t count, db_load_cb cb, void *data) +{ + bool result; /* Conclusion à faire remonter */ + char *sql; /* Requête SQL à construire */ + bool first; /* Marque du premier passage */ + 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 */ + int native_type; /* Type de valeur dans la base */ + + result = false; + + /* Préparation de la requête */ + + sql = strdup("SELECT "); + + first = true; + + for (i = 0; i < count; i++) + { + if (values[i].has_value) + continue; + + if (!first) sql = stradd(sql, ", "); + + sql = stradd(sql, values[i].name); + + first = false; + + } + + assert(!first); + + sql = stradd(sql, " FROM "); + sql = stradd(sql, table); + + first = true; + + for (i = 0; i < count; i++) + { + if (!values[i].has_value) + continue; + + if (first) + sql = stradd(sql, " WHERE "); + else + sql = stradd(sql, " AND "); + + sql = stradd(sql, values[i].name); + + sql = stradd(sql, " = ?"); + + first = false; + + } + + 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 prepare_error; + } + + /* Attribution des valeurs */ + + index = 1; + + if (!bind_bound_values(db, stmt, sql, values, count, true, &index)) + goto bind_error; + + /* Chargement des valeurs existantes */ + + result = true; + + for (ret = sqlite3_step(stmt); ret == SQLITE_ROW && result; ret = sqlite3_step(stmt)) + { + /* Conversion des valeurs */ + + index = 0; + + for (i = 0; i < count; i++) + { + if (values[i].has_value) + continue; + + native_type = sqlite3_column_type(stmt, index); + + /** + * On réalise une petite conversion selon le champ. + * + * Le filtre SQLITE_NATIVE est destiné à conserver le type choisi par + * SQLite. Typiquement, une chaîne peut être à SQLITE_NULL ou SQLITE_TEXT + * selon la valeur conservée dans la base. + * + * D'autres éléments, comme les localisations en mémoire, peuvent aussi + * avoir un champ éventuellement nul, donc la définition à partir des + * indications de la base de données reste importante. + * + * En ce qui concerne les valeurs numériques, SQLite ne fait pas de + * distinction : tout passe par la fonction sqlite3VdbeIntValue(), + * qui effectue des transtypages au besoin pour tout ce qui n'est + * pas numérique. + * + * Pour les types internes SQLITE_INTEGER et SQLITE_BOOLEAN, + * il est donc nécessaire d'ajuster en interne. + */ + + if (native_type == SQLITE_INTEGER) + native_type = SQLITE_INT64; + + if (values[i].type == SQLITE_NATIVE) + values[i].type = native_type; + + else + assert(values[i].type == native_type + || values[i].type == SQLITE_INTEGER + || values[i].type == SQLITE_BOOLEAN); + + switch (values[i].type) + { + case SQLITE_BOOLEAN: + values[i].boolean = (bool)sqlite3_column_int(stmt, index); + break; + + case SQLITE_INTEGER: + values[i].integer = sqlite3_column_int(stmt, index); + break; + + case SQLITE_INT64: + values[i].integer64 = sqlite3_column_int64(stmt, index); + break; + + case SQLITE_FLOAT: + assert(0); + break; + + case SQLITE_TEXT: + values[i].cstring = (const char *)sqlite3_column_text(stmt, index); + break; + + case SQLITE_BLOB: + assert(0); + break; + + case SQLITE_NULL: + break; + + default: + assert(0); + break; + + } + + } + + /* Chargement d'un nouvel élément */ + + cb(values, count, data); + + index++; + + } + + bind_error: + + sqlite3_finalize(stmt); + + prepare_error: + + free(sql); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : db = base de données à mettre à jour. * +* table = nom de la table concernée. * +* values = champs avec leur valeur. * +* count = quantité de ces champs. * +* * +* Description : Enregistre une série de valeurs dans une base de données. * +* * +* Retour : Bilan de l'exécution de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool store_db_values(sqlite3 *db, const char *table, const bound_value *values, size_t count) +{ + bool result; /* Conclusion à faire remonter */ + 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 */ + + result = false; + + /* Préparation de la requête */ + + sql = strdup("INSERT INTO "); + sql = stradd(sql, table); + sql = stradd(sql, " ("); + + for (i = 0; i < count; i++) + { + assert(values[i].has_value); + + 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 prepare_error; + } + + /* Attribution des valeurs */ + + index = 1; + + if (!bind_bound_values(db, stmt, sql, values, count, true, &index)) + goto bind_error; + + /* 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 insert_error; + } + + result = true; + + insert_error: + + bind_error: + + sqlite3_finalize(stmt); + + prepare_error: + + free(sql); + + return result; + +} diff --git a/src/common/sqlite.h b/src/common/sqlite.h index 1d31746..291eec8 100644 --- a/src/common/sqlite.h +++ b/src/common/sqlite.h @@ -25,6 +25,7 @@ #define _COMMON_SQLITE_H +#include #include #include #include @@ -51,6 +52,8 @@ typedef struct _bound_value unsigned int type; /* Type de valeur à associer */ + bool has_value; /* Validité des champs suivants*/ + union { bool boolean; /* Etat sur 1 bit */ @@ -72,6 +75,15 @@ void free_all_bound_values(bound_value *, size_t); /* Effectue une recherche au sein d'un ensemble de valeurs. */ const bound_value *find_bound_value(const bound_value *, size_t, const char *); +/* Interagit avec des valeurs chargées. */ +typedef bool (* db_load_cb) (const bound_value *, size_t, void *); + +/* Charge une série de valeurs depuis une base de données. */ +bool load_db_values(sqlite3 *, const char *, bound_value *, size_t, db_load_cb, void *); + +/* Enregistre une série de valeurs dans une base de données. */ +bool store_db_values(sqlite3 *, const char *, const bound_value *, size_t); + #endif /* _COMMON_SQLITE_H */ diff --git a/src/glibext/gbinarycursor.c b/src/glibext/gbinarycursor.c index ee9eb5f..9c4e82b 100644 --- a/src/glibext/gbinarycursor.c +++ b/src/glibext/gbinarycursor.c @@ -97,9 +97,6 @@ static bool g_binary_cursor_unserialize(GBinaryCursor *, packed_buffer *); /* Charge les valeurs utiles pour une localisation. */ static bool g_binary_cursor_load(GBinaryCursor *, const char *, const bound_value *, size_t); -/* Constitue les champs destinés à une insertion / modification. */ -static bool g_binary_cursor_prepare_db_statement(const GBinaryCursor *, const char *, bound_value **, size_t *); - /* ---------------------------------------------------------------------------------- */ @@ -145,9 +142,8 @@ static void g_binary_cursor_class_init(GBinaryCursorClass *class) line->unserialize = (unserialize_cursor_fc)g_binary_cursor_unserialize; line->create_db = (create_cursor_db_table_fc)g_binary_cursor_create_db_table; - line->setup_load = (setup_cursor_load_fc)g_binary_cursor_setup_load; line->load = (load_cursor_fc)g_binary_cursor_load; - line->prepare = (prepare_cursor_db_statement_fc)g_binary_cursor_prepare_db_statement; + line->store = (store_cursor_fc)g_binary_cursor_store; } @@ -500,31 +496,6 @@ char *g_binary_cursor_create_db_table(const char *base) /****************************************************************************** * * -* Paramètres : base = tronc commun pour les champs de la base de données. * -* 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 : - * -* * -******************************************************************************/ - -bool g_binary_cursor_setup_load(const char *base, bound_value **values, size_t *count) -{ - bool result; /* Bilan à renvoyer */ - - result = setup_load_for_vmpa(base, values, count); - - return result; - -} - - -/****************************************************************************** -* * * Paramètres : cursor = suivi de positions dont la définition est à définir.* * base = tronc commun pour les champs de la base de données. * * values = tableau d'éléments à consulter. * @@ -564,11 +535,14 @@ static bool g_binary_cursor_load(GBinaryCursor *cursor, const char *base, const * * ******************************************************************************/ -static bool g_binary_cursor_prepare_db_statement(const GBinaryCursor *cursor, const char *base, bound_value **values, size_t *count) +bool g_binary_cursor_store(const GBinaryCursor *cursor, const char *base, bound_value **values, size_t *count) { bool result; /* Bilan à renvoyer */ - result = prepare_vmpa_db_statement(&cursor->addr, base, values, count); + if (cursor == NULL) + result = store_vmpa(NULL, base, values, count); + else + result = store_vmpa(&cursor->addr, base, values, count); return result; diff --git a/src/glibext/gbinarycursor.h b/src/glibext/gbinarycursor.h index 63a6f1b..ffac19a 100644 --- a/src/glibext/gbinarycursor.h +++ b/src/glibext/gbinarycursor.h @@ -71,8 +71,8 @@ void g_binary_cursor_get_info(const GBinaryCursor *, vmpa2t *); /* Donne les éléments requis pour la construction d'une table. */ char *g_binary_cursor_create_db_table(const char *); -/* Décrit les colonnes utiles à un chargement de données. */ -bool g_binary_cursor_setup_load(const char *, bound_value **, size_t *); +/* Constitue les champs destinés à une insertion / modification. */ +bool g_binary_cursor_store(const GBinaryCursor *, const char *, bound_value **, size_t *); diff --git a/src/glibext/glinecursor-int.h b/src/glibext/glinecursor-int.h index 18ec147..b6a0f19 100644 --- a/src/glibext/glinecursor-int.h +++ b/src/glibext/glinecursor-int.h @@ -54,14 +54,11 @@ typedef bool (* unserialize_cursor_fc) (GLineCursor *, packed_buffer *); /* Donne les éléments requis pour la construction d'une table. */ typedef char *(* create_cursor_db_table_fc) (const char *); -/* Décrit les colonnes utiles à un chargement de données. */ -typedef bool (* setup_cursor_load_fc) (const char *, bound_value **, size_t *); - /* Charge les valeurs utiles pour une localisation. */ typedef bool (* load_cursor_fc) (GLineCursor *, const char *, const bound_value *, size_t); /* Constitue les champs destinés à une insertion / modification. */ -typedef bool (* prepare_cursor_db_statement_fc) (const GLineCursor *, const char *, bound_value **, size_t *); +typedef bool (* store_cursor_fc) (const GLineCursor *, const char *, bound_value **, size_t *); /* Suivi de positions dans un panneau de chargement (instance) */ @@ -86,9 +83,8 @@ struct _GLineCursorClass unserialize_cursor_fc unserialize; /* Chargement d'un emplacement */ create_cursor_db_table_fc create_db; /* Création de table */ - setup_cursor_load_fc setup_load; /* Préparation du chargement */ load_cursor_fc load; /* Chargement de valeurs */ - prepare_cursor_db_statement_fc prepare; /* Préparation d'enregistrement*/ + store_cursor_fc store; /* Préparation d'enregistrement*/ }; diff --git a/src/glibext/glinecursor.c b/src/glibext/glinecursor.c index 64521f4..bef9cb6 100644 --- a/src/glibext/glinecursor.c +++ b/src/glibext/glinecursor.c @@ -356,7 +356,7 @@ bool g_line_cursor_setup_load(const GLineCursor *cursor, const char *base, bound { bool result; /* Bilan à renvoyer */ - result = G_LINE_CURSOR_GET_CLASS(cursor)->setup_load(base, values, count); + result = G_LINE_CURSOR_GET_CLASS(cursor)->store(NULL, base, values, count); return result; @@ -404,11 +404,11 @@ bool g_line_cursor_load(GLineCursor *cursor, const char *base, const bound_value * * ******************************************************************************/ -bool g_line_cursor_prepare_db_statement(const GLineCursor *cursor, const char *base, bound_value **values, size_t *count) +bool g_line_cursor_store(const GLineCursor *cursor, const char *base, bound_value **values, size_t *count) { bool result; /* Bilan à renvoyer */ - result = G_LINE_CURSOR_GET_CLASS(cursor)->prepare(cursor, base, values, count); + result = G_LINE_CURSOR_GET_CLASS(cursor)->store(cursor, base, values, count); return result; diff --git a/src/glibext/glinecursor.h b/src/glibext/glinecursor.h index 4fa93c1..c373562 100644 --- a/src/glibext/glinecursor.h +++ b/src/glibext/glinecursor.h @@ -102,7 +102,7 @@ bool g_line_cursor_setup_load(const GLineCursor *, const char *, bound_value **, bool g_line_cursor_load(GLineCursor *, const char *, const bound_value *, size_t); /* Constitue les champs destinés à une insertion / modification. */ -bool g_line_cursor_prepare_db_statement(const GLineCursor *, const char *, bound_value **, size_t *); +bool g_line_cursor_store(const GLineCursor *, const char *, bound_value **, size_t *); -- cgit v0.11.2-87-g4458