summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2019-09-29 13:45:14 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2019-09-29 13:45:14 (GMT)
commit522298cf50e67d92b0aa85a85177ed7c16b00e08 (patch)
tree134a48dfc67584fb8e147d326135f2bd109bdfac /src
parent034fda4f2b0eb1c2093b24eb749733ce1ea8791e (diff)
Provided a generic way to update DB values.
Diffstat (limited to 'src')
-rw-r--r--src/analysis/db/collection.c142
-rw-r--r--src/common/sqlite.c131
-rw-r--r--src/common/sqlite.h3
3 files changed, 142 insertions, 134 deletions
diff --git a/src/analysis/db/collection.c b/src/analysis/db/collection.c
index 9ae7b9c..7b2082a 100644
--- a/src/analysis/db/collection.c
+++ b/src/analysis/db/collection.c
@@ -1219,147 +1219,43 @@ static bool g_db_collection_store_updated_item(const GDbCollection *collec, cons
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 */
- bool first; /* Première valeur ? */
+ bound_value *updates; /* Champs à mettre à jour */
+ size_t ucount; /* Nombre de ces champs */
+ bound_value *conds; /* Champs de condition */
+ size_t ccount; /* Nombre de ces champs */
+ const bound_value *flags_ptr; /* Emplacement des fanions */
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 */
- const bound_value *timestamp; /* Valeur de l'horodatage */
result = false;
if (!g_db_item_store(item, &values, &count))
- goto gdcsui_building_values;
+ goto building_values;
- /* Préparation de la requête */
+ updates = malloc(1 * sizeof(bound_value));
+ ucount = 0;
- sql = strdup("UPDATE ");
- sql = stradd(sql, collec->name);
+ conds = malloc((count - 1) * sizeof(bound_value));
+ ccount = 0;
- sql = stradd(sql, " SET timestamp = ? ");
-
- sql = stradd(sql, "WHERE ");
-
- first = true;
+ flags_ptr = find_bound_value(values, count, "flags");
for (i = 0; i < count; i++)
{
- if (strcmp(values[i].name, "timestamp") == 0)
- continue;
-
- if (first)
- first = false;
- else
- sql = stradd(sql, " AND ");
-
- sql = stradd(sql, values[i].name);
-
- if (values[i].type == SQLITE_NULL)
- sql = stradd(sql, " IS ");
- else
- 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 UPDATE statment '%s' (ret=%d): %s\n", sql, ret, sqlite3_errmsg(db));
- goto gdcsui_exit;
- }
-
- /* Attribution des valeurs */
-
- index = 1;
-
- timestamp = find_bound_value(values, count, "timestamp");
- assert(timestamp->type == SQLITE_INT64);
-
- ret = sqlite3_bind_int64(stmt, index, timestamp->integer64);
- index++;
-
- 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 gdcsui_exit;
- }
-
- for (i = 0; i < count; i++)
- {
- if (strcmp(values[i].name, "timestamp") == 0)
- continue;
-
- switch (values[i].type)
+ if (&values[i] == flags_ptr)
{
- 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;
-
+ assert(ucount < 1);
+ memcpy(&updates[ucount++], &values[i], sizeof(bound_value));
}
-
- if (ret != SQLITE_OK)
+ else
{
- fprintf(stderr, "Can't bind value for parameter nb %d in '%s' (ret=%d): %s\n",
- index - 1, sql, ret, sqlite3_errmsg(db));
- goto gdcsui_exit;
+ assert(ccount < (count - 1));
+ memcpy(&conds[ccount++], &values[i], sizeof(bound_value));
}
-
- }
-
- /* Exécution finale */
-
- ret = sqlite3_step(stmt);
-
- if (ret != SQLITE_DONE)
- {
- fprintf(stderr, "UPDATE statement '%s' didn't return DONE (ret=%d): %s\n", sql, ret, sqlite3_errmsg(db));
- goto gdcsui_exit;
}
- sqlite3_finalize(stmt);
-
- result = true;
-
- gdcsui_exit:
-
- free(sql);
+ result = update_db_values(db, collec->name, updates, ucount, conds, ccount);
- gdcsui_building_values:
+ building_values:
free_all_bound_values(values, count);
diff --git a/src/common/sqlite.c b/src/common/sqlite.c
index d497c81..3a94623 100644
--- a/src/common/sqlite.c
+++ b/src/common/sqlite.c
@@ -34,7 +34,7 @@
/* 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 *);
+static bool bind_bound_values(sqlite3 *, sqlite3_stmt *, const char *, const bound_value *, size_t, int *);
@@ -106,12 +106,11 @@ const bound_value *find_bound_value(const bound_value *values, size_t count, con
/******************************************************************************
* *
* 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] *
+* 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. *
+* index = indice évolutif des valeurs paramétrées. [OUT] *
* *
* Description : Attribue une définition aux valeurs paramétrées. *
* *
@@ -121,7 +120,7 @@ const bound_value *find_bound_value(const bound_value *values, size_t count, con
* *
******************************************************************************/
-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)
+static bool bind_bound_values(sqlite3 *db, sqlite3_stmt *stmt, const char *sql, const bound_value *values, size_t count, int *index)
{
bool result; /* Bilan à retourner */
size_t i; /* Boucle de parcours */
@@ -131,7 +130,7 @@ static bool bind_bound_values(sqlite3 *db, sqlite3_stmt *stmt, const char *sql,
for (i = 0; i < count && result; i++)
{
- if (values[i].has_value != has_value)
+ if (!values[i].has_value)
continue;
switch (values[i].type)
@@ -269,7 +268,7 @@ bool load_db_values(sqlite3 *db, const char *table, bound_value *values, size_t
index = 1;
- if (!bind_bound_values(db, stmt, sql, values, count, true, &index))
+ if (!bind_bound_values(db, stmt, sql, values, count, &index))
goto bind_error;
/* Chargement des valeurs existantes */
@@ -446,7 +445,7 @@ bool store_db_values(sqlite3 *db, const char *table, const bound_value *values,
index = 1;
- if (!bind_bound_values(db, stmt, sql, values, count, true, &index))
+ if (!bind_bound_values(db, stmt, sql, values, count, &index))
goto bind_error;
/* Exécution finale */
@@ -474,3 +473,113 @@ bool store_db_values(sqlite3 *db, const char *table, const bound_value *values,
return result;
}
+
+
+/******************************************************************************
+* *
+* Paramètres : db = base de données à mettre à jour. *
+* table = nom de la table concernée. *
+* values = champs avec leur valeur nouvelle. *
+* vcount = quantité de ces champs. *
+* values = champs avec leur valeur de condition. *
+* ccount = quantité de ces champs. *
+* *
+* Description : Met à jour une série de valeurs dans une base de données. *
+* *
+* Retour : Bilan de l'exécution de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool update_db_values(sqlite3 *db, const char *table, const bound_value *values, size_t vcount, const bound_value *conds, size_t ccount)
+{
+ 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("UPDATE ");
+ sql = stradd(sql, table);
+ sql = stradd(sql, " SET");
+
+ for (i = 0; i < vcount; i++)
+ {
+ assert(values[i].has_value);
+
+ if (i > 0) sql = stradd(sql, " ,");
+
+ sql = stradd(sql, " ");
+ sql = stradd(sql, values[i].name);
+
+ sql = stradd(sql, " = ?");
+
+ }
+
+ if (ccount > 0)
+ {
+ sql = stradd(sql, " WHERE");
+
+ for (i = 0; i < ccount; i++)
+ {
+ if (i > 0) sql = stradd(sql, " AND");
+
+ sql = stradd(sql, " ");
+ sql = stradd(sql, conds[i].name);
+
+ sql = stradd(sql, " = ?");
+
+ }
+
+ }
+
+ sql = stradd(sql, ";");
+
+ ret = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
+ if (ret != SQLITE_OK)
+ {
+ fprintf(stderr, "Can't prepare UPDATE 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, vcount, &index))
+ goto bind_error;
+
+ if (!bind_bound_values(db, stmt, sql, conds, ccount, &index))
+ goto bind_error;
+
+ /* Exécution finale */
+
+ ret = sqlite3_step(stmt);
+
+ if (ret != SQLITE_DONE)
+ {
+ fprintf(stderr, "UPDATE statement '%s' didn't return DONE (ret=%d): %s\n", sql, ret, sqlite3_errmsg(db));
+ goto update_error;
+ }
+
+ result = true;
+
+ update_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 291eec8..99de12d 100644
--- a/src/common/sqlite.h
+++ b/src/common/sqlite.h
@@ -84,6 +84,9 @@ bool load_db_values(sqlite3 *, const char *, bound_value *, size_t, db_load_cb,
/* Enregistre une série de valeurs dans une base de données. */
bool store_db_values(sqlite3 *, const char *, const bound_value *, size_t);
+/* Met à jour une série de valeurs dans une base de données. */
+bool update_db_values(sqlite3 *, const char *, const bound_value *, size_t, const bound_value *, size_t);
+
#endif /* _COMMON_SQLITE_H */