summaryrefslogtreecommitdiff
path: root/src/analysis/db/collection.c
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2019-05-08 09:28:58 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2019-05-08 09:28:58 (GMT)
commit86ba53836168bcc591f532f2419fa290de601572 (patch)
tree91c96614d6f7e3fd75800a52c0166c91c7f8ef31 /src/analysis/db/collection.c
parent28e53c2498903090182ebeb128347fcd92896cd9 (diff)
Updated the core functions dealing with SQLite databases.
Diffstat (limited to 'src/analysis/db/collection.c')
-rw-r--r--src/analysis/db/collection.c291
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 */