diff options
Diffstat (limited to 'src/analysis/db/collection.c')
-rw-r--r-- | src/analysis/db/collection.c | 291 |
1 files changed, 45 insertions, 246 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 */ |