From 564d67a65b6ae4f8762b20baa62e83de4d22f4c0 Mon Sep 17 00:00:00 2001 From: grayTerminal-sh Date: Thu, 16 Jul 2026 11:17:06 +0200 Subject: [PATCH] refactor(database): migrate initialization to database layer --- Makefile | 11 +- docs/tickets/open/TICKET-026.md | 366 +++++++++++++++++++++++++++++++ include/database/database.h | 17 +- include/database/schema.h | 8 +- labfy-investigation | Bin 144504 -> 144768 bytes src/database/database.c | 335 ++++++++-------------------- src/database/schema.c | 57 ++++- src/database/statement.c | 140 ++++++++++-- src/database/transaction.c | 90 +++++++- tests/test_database | Bin 31592 -> 41112 bytes tests/test_database.c | 160 ++++++++++++++ tests/test_error | Bin 32104 -> 32648 bytes tests/test_error.c | 323 +++++++++++++++++++++++++++ tests/test_investigation_project | Bin 45608 -> 50984 bytes tests/test_statement | Bin 37208 -> 37456 bytes tests/test_transaction | Bin 32440 -> 32720 bytes tests/test_transaction.c | 83 +++++++ 17 files changed, 1297 insertions(+), 293 deletions(-) create mode 100644 docs/tickets/open/TICKET-026.md diff --git a/Makefile b/Makefile index 6876067..ac4c089 100644 --- a/Makefile +++ b/Makefile @@ -66,12 +66,16 @@ $(TEST_PROJECT): \ tests/test_investigation_project.c \ src/core/investigation_project.c \ src/database/database.c \ - src/database/schema.c + src/database/schema.c \ + src/database/statement.c \ + src/database/transaction.c $(CC) $(TEST_CFLAGS) $^ -o $@ $(TEST_LDFLAGS) -lsqlite3 $(TEST_DATABASE): \ tests/test_database.c \ src/database/database.c \ + src/database/transaction.c \ + src/database/statement.c \ src/database/schema.c $(CC) $(TEST_CFLAGS) $^ -o $@ $(TEST_LDFLAGS) -lsqlite3 @@ -79,6 +83,7 @@ $(TEST_STATEMENT): \ tests/test_statement.c \ src/database/database.c \ src/database/schema.c \ + src/database/transaction.c \ src/database/statement.c $(CC) $(TEST_CFLAGS) $^ -o $@ $(TEST_LDFLAGS) -lsqlite3 @@ -87,7 +92,8 @@ $(TEST_TRANSACTION): \ src/database/database.c \ src/database/schema.c \ src/database/statement.c \ - src/database/transaction.c + src/database/transaction.c \ + src/database/error.c $(CC) $(TEST_CFLAGS) $^ -o $@ $(TEST_LDFLAGS) -lsqlite3 $(TEST_ERROR): \ @@ -95,6 +101,7 @@ $(TEST_ERROR): \ src/database/database.c \ src/database/schema.c \ src/database/statement.c \ + src/database/transaction.c \ src/database/error.c $(CC) $(TEST_CFLAGS) $^ -o $@ $(TEST_LDFLAGS) -lsqlite3 diff --git a/docs/tickets/open/TICKET-026.md b/docs/tickets/open/TICKET-026.md new file mode 100644 index 0000000..4d56a63 --- /dev/null +++ b/docs/tickets/open/TICKET-026.md @@ -0,0 +1,366 @@ +# Ticket #026 — Migrer l’initialisation vers la couche Database + +## Contexte + +Le ticket #025 a introduit l’infrastructure principale de la couche Database : + +- contexte opaque `Database` ; +- ouverture et fermeture des connexions ; +- requêtes préparées avec `DatabaseStatement` ; +- bindings et lecture typée ; +- gestion des transactions ; +- infrastructure d’erreurs. + +Cependant, `database_initialize()` utilise encore directement plusieurs fonctions de l’API SQLite : + +```c +sqlite3_open_v2() +sqlite3_prepare_v2() +sqlite3_bind_text() +sqlite3_step() +sqlite3_reset() +sqlite3_clear_bindings() +sqlite3_finalize() +sqlite3_close() + +La fonction exécute également directement les commandes SQL suivantes : + +```sql + +BEGIN IMMEDIATE; +COMMIT; +ROLLBACK; +``` + +De son côté, `schema_install_v1()` reçoit toujours directement un `sqlite3 *`, ce qui contourne l’abstraction `Database`. + +## Objectif + +Réécrire l’initialisation d’une nouvelle enquête afin qu’elle utilise l’infrastructure créée au ticket #025. + +L’initialisation doit rester atomique : + +- soit la base est entièrement initialisée ; +- soit aucune donnée partielle n’est conservée. + +## Travail à réaliser + +### Adapter l’installation du schéma + +Modifier la signature actuelle : + +```C +bool schema_install_v1( + sqlite3 *database +); +``` + +afin qu’elle reçoive un contexte Database : + +```C +bool schema_install_v1( + Database *database +); +``` + +L’installation du fichier SQL complet pourra continuer à utiliser `sqlite3_exec()` en interne, car le schéma contient plusieurs instructions SQL. + +L’accès au handle SQLite devra passer par l’API interne : + +```C +database_get_handle() +``` + +La fonction ne devra réaliser ni `COMMIT` ni `ROLLBACK`. + +### Migrer l’insertion des métadonnées + +Réécrire les fonctions responsables de l’insertion dans la table `metadata` avec `DatabaseStatement`. + +Les opérations devront utiliser l’API suivante : + +```C +database_statement_prepare() +database_statement_bind_text() +database_statement_step() +database_statement_reset() +database_statement_clear_bindings() +database_statement_finalize() +``` + +Les métadonnées obligatoires restent : + +``` +schema_version +application +created_at +investigation_uuid +``` + +Une seule requête préparée devra pouvoir être réutilisée pour insérer les quatre métadonnées. + +### Migrer l’insertion de l’enquête + +Réécrire l’insertion dans la table `investigation` avec `DatabaseStatement`. + +Les champs insérés restent : + +```C +database_open() +database_transaction_begin() +schema_install_v1() +database_transaction_commit() +database_transaction_rollback() +database_close() +``` + +Le déroulement attendu est : + +``` +validation des paramètres + ↓ +création du timestamp UTC + ↓ +création de l’UUID + ↓ +ouverture de Database + ↓ +début de transaction + ↓ +installation du schéma V1 + ↓ +insertion des métadonnées + ↓ +insertion de l’enquête + ↓ +commit + ↓ +fermeture de Database +``` + +Tout échec après le début de la transaction doit provoquer un rollback. + +### Utiliser l’infrastructure d’erreurs + +Les erreurs rencontrées pendant : + +- l’installation du schéma ; +- la préparation d’une requête ; +- le binding d’un paramètre ; +- l’exécution d’une requête ; +- le début d’une transaction ; +- le commit ; +- le rollback ; + +doivent être enregistrées dans le contexte Database lorsque celui-ci est disponible. + +L’infrastructure interne existante pourra être utilisée : + +```C +database_set_error() +database_clear_error_internal() +``` + +```C +DATABASE_ERROR_SQLITE +``` + +```C +DATABASE_ERROR_INVALID_ARGUMENT +``` + +```C +DATABASE_ERROR_INVALID_STATE +``` + +### Nettoyer l’ancien code SQLite + +Supprimer de la logique d’initialisation les appels directs à : + +```C +sqlite3_open_v2() +sqlite3_prepare_v2() +sqlite3_bind_text() +sqlite3_step() +sqlite3_reset() +sqlite3_clear_bindings() +sqlite3_finalize() +sqlite3_close() +``` + +Supprimer également les commandes manuelles : + +```SQL +BEGIN IMMEDIATE; +COMMIT; +ROLLBACK; +``` + +La fonction utilitaire `database_execute_sql()` pourra être conservée uniquement si elle reste nécessaire à `database_open()` pour l’activation des clés étrangères. + +### Mettre à jour la documentation publique + +Dans `include/database/database.h`, supprimer la mention temporaire : + +``` +Cette fonction conserve temporairement son rôle actuel pendant le +refactoring du ticket #025. +``` + +La documentation de `database_initialize()` devra préciser que : + +- l’initialisation est transactionnelle ; +- un échec provoque un rollback ; +- la base est fermée avant le retour de la fonction. + +## Tests à ajouter ou adapter + +### Initialisation réussie + +Vérifier qu’une initialisation valide crée : + +- le schéma V1 ; +- les tables attendues ; +- les métadonnées obligatoires ; +- une seule ligne dans investigation ; +- le bon nom d’enquête ; +- le bon chemin racine ; +- un UUID non vide ; +- une date de création non vide ; +- une date de modification non vide. + +### Paramètres invalides + +Vérifier le refus des cas suivants : + +``` +database_path == NULL +database_path vide +investigation_name == NULL +investigation_name vide +investigation_root_path == NULL +investigation_root_path vide +``` + +### Rollback + +Provoquer un échec après le démarrage de la transaction. + +Une seconde tentative d’initialisation sur une base déjà initialisée pourra être utilisée pour provoquer une erreur de contrainte ou de création de schéma. + +Après l’échec, vérifier que : + +- aucune donnée partielle supplémentaire n’est conservée ; +- aucune seconde enquête n’est ajoutée ; +- les métadonnées existantes ne sont pas dupliquées ; +- la transaction est annulée ; +- la base reste lisible ; +- la connexion peut être fermée proprement. + +### Régression + +Tous les tests existants doivent rester valides : + +``` +InvestigationNode +InvestigationTreeModel +InvestigationTreeBuilder +InvestigationProject +Database +DatabaseStatement +DatabaseTransaction +DatabaseError +``` + +## Critères d’acceptation + +- [ ] `database_initialize()` n’appelle plus directement `sqlite3_open_v2()`. +- [ ] `database_initialize()` utilise `database_open()`. +- [ ] `database_initialize()` utilise `database_close()`. +- [ ] Les transactions utilisent le module `transaction`. +- [ ] Les insertions utilisent `DatabaseStatement`. +- [ ] `InvestigationNode` Investigation `schema_install_v1()` reçoit un `Database *`. +InvestigationNode +Investigation `schema_install_v1()` reçoit un `Database *`. +- [ ] `schema_install_v1()` récupère le handle avec l’API interne. +- [ ] Aucun `sqlite3_stmt *` n’est manipulé dans le code d’initialisation. +- [ ] Aucun `BEGIN`, `COMMIT` ou `ROLLBACK` manuel ne reste dans `database.c`. +- [ ] Tout échec après le début de la transaction provoque un rollback. +- [ ] Les erreurs sont enregistrées dans la couche Database. +- [ ] Les tests de réussite sont valides. +- [ ] Les tests de paramètres invalides sont valides. +- [ ] Les tests de rollback sont valides. +- [ ] Les tests de régression sont valides. +- [ ] `make` réussit sans erreur. +- [ ] `make test` réussit. +- [ ] `git diff --check` ne retourne aucune erreur. + +## Hors périmètre + +Ce ticket ne doit pas ajouter : + +- de CRUD métier ; +- de dépôt ou repository métier ; +- de migration entre plusieurs versions de schéma ; +- de système GResource pour embarquer `schema_v1.sql` ; +- de création automatique des dossiers parents ; +- de modification du schéma SQL V1 ; +- de nouvelles tables ; +- de logique d’interface graphique ; +- de nouvelles fonctionnalités utilisateur. + +## Fichiers principalement concernés + +```text +include/database/database.h +include/database/schema.h + +src/database/database.c +src/database/database_internal.h +src/database/schema.c + +tests/test_database.c + +Makefile +``` + +## Résultat attendu + +À la fin du ticket, `database_initialize()` doit être un utilisateur normal de la couche Database. + +La fonction ne doit plus contourner cette couche avec des appels SQLite directs. + +L’initialisation d’une enquête doit être entièrement transactionnelle, testée et cohérente avec l’architecture mise en place au ticket #025. + +## Commit attendu + +Une fois tous les critères d’acceptation validés, le ticket pourra être enregistré avec le commit suivant : + +```text +refactor(database): migrate initialization to database layer +``` + +Le commit doit principalement contenir : + +``` +include/database/database.h +include/database/schema.h + +src/database/database.c +src/database/database_internal.h +src/database/schema.c + +tests/test_database.c + +Makefile +``` +Avant le commit, exécuter : + +```bash +make clean +make +make test +git diff --check +git status --short +``` + diff --git a/include/database/database.h b/include/database/database.h index 585b079..d80e87c 100644 --- a/include/database/database.h +++ b/include/database/database.h @@ -45,8 +45,21 @@ void database_close( /** * @brief Initialise la base SQLite d'une nouvelle enquête. * - * Cette fonction conserve temporairement son rôle actuel pendant le - * refactoring du ticket #025. + * Cette fonction : + * + * - valide les paramètres ; + * - ouvre la connexion Database ; + * - démarre une transaction ; + * - installe le schéma SQLite V1 ; + * - insère les métadonnées obligatoires ; + * - insère l'enquête courante ; + * - valide la transaction ; + * - ferme la connexion avant de retourner. + * + * Tout échec survenant après le début de la transaction provoque + * l'annulation des modifications. + * + * La fonction ne crée pas les dossiers parents du fichier SQLite. * * @param database_path Chemin complet du fichier Enquete.sqlite. * @param investigation_name Nom de l'enquête. diff --git a/include/database/schema.h b/include/database/schema.h index e3f5295..276765d 100644 --- a/include/database/schema.h +++ b/include/database/schema.h @@ -6,9 +6,9 @@ #ifndef LABFY_INVESTIGATION_SCHEMA_H #define LABFY_INVESTIGATION_SCHEMA_H -#include +#include "database/database.h" -#include +#include /** * @brief Installe le schéma SQLite V1 dans une base ouverte. @@ -23,12 +23,12 @@ * * Elle ne réalise ni COMMIT ni ROLLBACK. * - * @param database Connexion SQLite ouverte. + * @param database Connexion Database ouverte. * * @return true si le schéma a été correctement installé, sinon false. */ bool schema_install_v1( - sqlite3 *database + Database *database ); #endif diff --git a/labfy-investigation b/labfy-investigation index 56a51c4567f5f048bb5fb9a9d9592a3f024e4d1b..21dd01225dabba0b9dd581fa20e4e8ea95b5cab8 100755 GIT binary patch delta 19272 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 delta 19156 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 +#include /** - * @brief Charge le schéma SQL V1 depuis les ressources intégrées. + * @brief Charge le schéma SQL V1 depuis le fichier du projet. + * + * @param database Connexion utilisée pour enregistrer une éventuelle erreur. * * @return Une nouvelle chaîne terminée par zéro, à libérer avec g_free(), * ou NULL en cas d'échec. */ -static char *schema_load_v1_sql(void) +static char *schema_load_v1_sql( + Database *database +) { char *schema_sql = NULL; GError *error = NULL; @@ -25,6 +32,14 @@ static char *schema_load_v1_sql(void) &error )) { + database_set_error( + database, + DATABASE_ERROR_INVALID_STATE, + error != NULL + ? error->message + : "Impossible de charger le schéma SQLite V1." + ); + g_warning( "Impossible de charger database/schema_v1.sql : %s", error != NULL @@ -41,9 +56,10 @@ static char *schema_load_v1_sql(void) } bool schema_install_v1( - sqlite3 *database + Database *database ) { + sqlite3 *database_handle = NULL; char *schema_sql = NULL; char *error_message = NULL; @@ -54,7 +70,24 @@ bool schema_install_v1( return false; } - schema_sql = schema_load_v1_sql(); + database_handle = database_get_handle( + database + ); + + if (database_handle == NULL) + { + database_set_error( + database, + DATABASE_ERROR_INVALID_STATE, + "La connexion SQLite est absente." + ); + + return false; + } + + schema_sql = schema_load_v1_sql( + database + ); if (schema_sql == NULL) { @@ -62,7 +95,7 @@ bool schema_install_v1( } result = sqlite3_exec( - database, + database_handle, schema_sql, NULL, NULL, @@ -73,11 +106,19 @@ bool schema_install_v1( if (result != SQLITE_OK) { + database_set_error( + database, + DATABASE_ERROR_SQLITE, + error_message != NULL + ? error_message + : sqlite3_errmsg(database_handle) + ); + g_warning( "Impossible d'installer le schéma SQLite V1 : %s", error_message != NULL ? error_message - : sqlite3_errmsg(database) + : sqlite3_errmsg(database_handle) ); sqlite3_free(error_message); @@ -87,5 +128,9 @@ bool schema_install_v1( sqlite3_free(error_message); + database_clear_error_internal( + database + ); + return true; } diff --git a/src/database/statement.c b/src/database/statement.c index f0bb005..67b4c03 100644 --- a/src/database/statement.c +++ b/src/database/statement.c @@ -110,13 +110,24 @@ bool database_statement_bind_text( ) { sqlite3 *database_handle = NULL; + const char *error_message = NULL; int result = SQLITE_ERROR; - if (statement == NULL || - statement->handle == NULL || + if (statement == NULL) + { + return false; + } + + if (statement->handle == NULL || index <= 0 || value == NULL) { + database_set_error( + statement->database, + DATABASE_ERROR_INVALID_ARGUMENT, + "Paramètres invalides pour la liaison d'un texte." + ); + return false; } @@ -134,17 +145,30 @@ bool database_statement_bind_text( statement->database ); + error_message = + database_handle != NULL + ? sqlite3_errmsg(database_handle) + : sqlite3_errstr(result); + + database_set_error( + statement->database, + DATABASE_ERROR_SQLITE, + error_message + ); + g_warning( "Impossible de lier le paramètre texte %d : %s", index, - database_handle != NULL - ? sqlite3_errmsg(database_handle) - : sqlite3_errstr(result) + error_message ); return false; } + database_clear_error_internal( + statement->database + ); + return true; } @@ -155,12 +179,23 @@ bool database_statement_bind_int64( ) { sqlite3 *database_handle = NULL; + const char *error_message = NULL; int result = SQLITE_ERROR; - if (statement == NULL || - statement->handle == NULL || + if (statement == NULL) + { + return false; + } + + if (statement->handle == NULL || index <= 0) { + database_set_error( + statement->database, + DATABASE_ERROR_INVALID_ARGUMENT, + "Paramètres invalides pour la liaison d'un entier." + ); + return false; } @@ -176,17 +211,30 @@ bool database_statement_bind_int64( statement->database ); + error_message = + database_handle != NULL + ? sqlite3_errmsg(database_handle) + : sqlite3_errstr(result); + + database_set_error( + statement->database, + DATABASE_ERROR_SQLITE, + error_message + ); + g_warning( "Impossible de lier le paramètre entier %d : %s", index, - database_handle != NULL - ? sqlite3_errmsg(database_handle) - : sqlite3_errstr(result) + error_message ); return false; } + database_clear_error_internal( + statement->database + ); + return true; } @@ -196,12 +244,23 @@ bool database_statement_bind_null( ) { sqlite3 *database_handle = NULL; + const char *error_message = NULL; int result = SQLITE_ERROR; - if (statement == NULL || - statement->handle == NULL || + if (statement == NULL) + { + return false; + } + + if (statement->handle == NULL || index <= 0) { + database_set_error( + statement->database, + DATABASE_ERROR_INVALID_ARGUMENT, + "Paramètres invalides pour la liaison de NULL." + ); + return false; } @@ -216,17 +275,30 @@ bool database_statement_bind_null( statement->database ); + error_message = + database_handle != NULL + ? sqlite3_errmsg(database_handle) + : sqlite3_errstr(result); + + database_set_error( + statement->database, + DATABASE_ERROR_SQLITE, + error_message + ); + g_warning( "Impossible de lier le paramètre NULL %d : %s", index, - database_handle != NULL - ? sqlite3_errmsg(database_handle) - : sqlite3_errstr(result) + error_message ); return false; } + database_clear_error_internal( + statement->database + ); + return true; } @@ -235,25 +307,44 @@ DatabaseStatementStepResult database_statement_step( ) { sqlite3 *database_handle = NULL; + const char *error_message = NULL; int result = SQLITE_ERROR; - if (statement == NULL || - statement->handle == NULL) + if (statement == NULL) { return DATABASE_STATEMENT_STEP_ERROR; } + if (statement->handle == NULL) + { + database_set_error( + statement->database, + DATABASE_ERROR_INVALID_STATE, + "La requête préparée SQLite est absente." + ); + + return DATABASE_STATEMENT_STEP_ERROR; + } + result = sqlite3_step( statement->handle ); if (result == SQLITE_ROW) { + database_clear_error_internal( + statement->database + ); + return DATABASE_STATEMENT_STEP_ROW; } if (result == SQLITE_DONE) { + database_clear_error_internal( + statement->database + ); + return DATABASE_STATEMENT_STEP_DONE; } @@ -261,11 +352,20 @@ DatabaseStatementStepResult database_statement_step( statement->database ); - g_warning( - "Impossible d'exécuter la requête SQL : %s", + error_message = database_handle != NULL ? sqlite3_errmsg(database_handle) - : sqlite3_errstr(result) + : sqlite3_errstr(result); + + database_set_error( + statement->database, + DATABASE_ERROR_SQLITE, + error_message + ); + + g_warning( + "Impossible d'exécuter la requête SQL : %s", + error_message ); return DATABASE_STATEMENT_STEP_ERROR; diff --git a/src/database/transaction.c b/src/database/transaction.c index fcc9845..33d2c6f 100644 --- a/src/database/transaction.c +++ b/src/database/transaction.c @@ -22,17 +22,34 @@ static bool database_transaction_execute( char *error_message = NULL; int result = SQLITE_ERROR; - if (database == NULL || - sql == NULL || - sql[0] == '\0') + if (database == NULL) { return false; } - database_handle = database_get_handle(database); + if (sql == NULL || sql[0] == '\0') + { + database_set_error( + database, + DATABASE_ERROR_INVALID_ARGUMENT, + "La commande SQL de transaction est absente." + ); + + return false; + } + + database_handle = database_get_handle( + database + ); if (database_handle == NULL) { + database_set_error( + database, + DATABASE_ERROR_INVALID_STATE, + "La connexion SQLite est absente." + ); + return false; } @@ -46,6 +63,14 @@ static bool database_transaction_execute( if (result != SQLITE_OK) { + database_set_error( + database, + DATABASE_ERROR_SQLITE, + error_message != NULL + ? error_message + : sqlite3_errmsg(database_handle) + ); + g_warning( "Impossible d'exécuter la transaction SQL : %s", error_message != NULL @@ -67,12 +92,22 @@ bool database_transaction_begin( Database *database ) { - if (database == NULL || - database_get_transaction_active(database)) + if (database == NULL) { return false; } + if (database_get_transaction_active(database)) + { + database_set_error( + database, + DATABASE_ERROR_INVALID_STATE, + "Une transaction est déjà active." + ); + + return false; + } + if (!database_transaction_execute( database, "BEGIN IMMEDIATE;" @@ -86,6 +121,10 @@ bool database_transaction_begin( true ); + database_clear_error_internal( + database + ); + return true; } @@ -93,12 +132,22 @@ bool database_transaction_commit( Database *database ) { - if (database == NULL || - !database_get_transaction_active(database)) + if (database == NULL) { return false; } + if (!database_get_transaction_active(database)) + { + database_set_error( + database, + DATABASE_ERROR_INVALID_STATE, + "Aucune transaction active à valider." + ); + + return false; + } + if (!database_transaction_execute( database, "COMMIT;" @@ -112,6 +161,10 @@ bool database_transaction_commit( false ); + database_clear_error_internal( + database + ); + return true; } @@ -119,12 +172,22 @@ bool database_transaction_rollback( Database *database ) { - if (database == NULL || - !database_get_transaction_active(database)) + if (database == NULL) { return false; } + if (!database_get_transaction_active(database)) + { + database_set_error( + database, + DATABASE_ERROR_INVALID_STATE, + "Aucune transaction active à annuler." + ); + + return false; + } + if (!database_transaction_execute( database, "ROLLBACK;" @@ -138,5 +201,12 @@ bool database_transaction_rollback( false ); + /* + * On n'efface pas automatiquement l'erreur précédente. + * + * Un rollback est souvent exécuté à la suite d'une autre erreur. + * Cette erreur initiale doit rester disponible pour le diagnostic. + */ + return true; } diff --git a/tests/test_database b/tests/test_database index adf363d47e6308e8852c3d95338aef03b1439e29..c402d3f3d89dde2c5a0895c071c7b44eaa2e94f2 100755 GIT binary patch literal 41112 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 b9lBnPIv6Lq?HWgL<#$x+ literal 31592 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 literal 32104 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 #include +#include /** * @brief Vérifie l'état initial d'une connexion. @@ -121,11 +122,333 @@ static void test_success_clears_previous_error(void) database_close(database); } +/** + * @brief Vérifie les erreurs produites par un binding texte. + */ +static void test_statement_bind_error(void) +{ + Database *database = NULL; + DatabaseStatement *statement = NULL; + const char *error_message = NULL; + + database = database_open(":memory:"); + + assert(database != NULL); + + statement = database_statement_prepare( + database, + "SELECT ?;" + ); + + assert(statement != NULL); + + /* + * La requête ne possède qu'un seul paramètre. + */ + assert( + !database_statement_bind_text( + statement, + 2, + "hors limite" + ) + ); + + assert( + database_error_get_code(database) == + DATABASE_ERROR_SQLITE + ); + + error_message = database_error_get_message( + database + ); + + assert(error_message != NULL); + assert(error_message[0] != '\0'); + + /* + * Un binding valide efface l'erreur précédente. + */ + assert( + database_statement_bind_text( + statement, + 1, + "valeur valide" + ) + ); + + assert( + database_error_get_code(database) == + DATABASE_ERROR_NONE + ); + + /* + * Un indice invalide appartient aux erreurs d'argument. + */ + assert( + !database_statement_bind_text( + statement, + 0, + "valeur" + ) + ); + + assert( + database_error_get_code(database) == + DATABASE_ERROR_INVALID_ARGUMENT + ); + + database_statement_finalize(statement); + database_close(database); +} + +/** + * @brief Vérifie les erreurs produites par les bindings entier et NULL. + */ +static void test_statement_other_bind_errors(void) +{ + Database *database = NULL; + DatabaseStatement *statement = NULL; + + database = database_open(":memory:"); + + assert(database != NULL); + + statement = database_statement_prepare( + database, + "SELECT ?;" + ); + + assert(statement != NULL); + + /* + * Indice hors limite : erreur SQLite. + */ + assert( + !database_statement_bind_int64( + statement, + 2, + INT64_C(42) + ) + ); + + assert( + database_error_get_code(database) == + DATABASE_ERROR_SQLITE + ); + + /* + * Un binding valide efface l'erreur précédente. + */ + assert( + database_statement_bind_int64( + statement, + 1, + INT64_C(42) + ) + ); + + assert( + database_error_get_code(database) == + DATABASE_ERROR_NONE + ); + + /* + * Indice invalide : erreur d'argument. + */ + assert( + !database_statement_bind_int64( + statement, + 0, + INT64_C(42) + ) + ); + + assert( + database_error_get_code(database) == + DATABASE_ERROR_INVALID_ARGUMENT + ); + + /* + * Le binding NULL valide efface l'erreur précédente. + */ + assert( + database_statement_bind_null( + statement, + 1 + ) + ); + + assert( + database_error_get_code(database) == + DATABASE_ERROR_NONE + ); + + /* + * Indice hors limite : erreur SQLite. + */ + assert( + !database_statement_bind_null( + statement, + 2 + ) + ); + + assert( + database_error_get_code(database) == + DATABASE_ERROR_SQLITE + ); + + /* + * Indice invalide : erreur d'argument. + */ + assert( + !database_statement_bind_null( + statement, + 0 + ) + ); + + assert( + database_error_get_code(database) == + DATABASE_ERROR_INVALID_ARGUMENT + ); + + database_statement_finalize(statement); + database_close(database); +} + +/** + * @brief Vérifie l'enregistrement d'une erreur pendant sqlite3_step(). + */ +static void test_statement_step_error(void) +{ + Database *database = NULL; + DatabaseStatement *statement = NULL; + const char *error_message = NULL; + + database = database_open(":memory:"); + + assert(database != NULL); + + statement = database_statement_prepare( + database, + "CREATE TABLE step_error_test" + "(" + " value TEXT NOT NULL UNIQUE" + ");" + ); + + assert(statement != NULL); + + assert( + database_statement_step(statement) == + DATABASE_STATEMENT_STEP_DONE + ); + + database_statement_finalize(statement); + + /* + * Première insertion valide. + */ + statement = database_statement_prepare( + database, + "INSERT INTO step_error_test (value) " + "VALUES (?);" + ); + + assert(statement != NULL); + + assert( + database_statement_bind_text( + statement, + 1, + "valeur unique" + ) + ); + + assert( + database_statement_step(statement) == + DATABASE_STATEMENT_STEP_DONE + ); + + database_statement_finalize(statement); + + /* + * La seconde insertion viole la contrainte UNIQUE. + * La préparation et le binding réussissent, mais step() échoue. + */ + statement = database_statement_prepare( + database, + "INSERT INTO step_error_test (value) " + "VALUES (?);" + ); + + assert(statement != NULL); + + assert( + database_statement_bind_text( + statement, + 1, + "valeur unique" + ) + ); + + assert( + database_statement_step(statement) == + DATABASE_STATEMENT_STEP_ERROR + ); + + assert( + database_error_get_code(database) == + DATABASE_ERROR_SQLITE + ); + + error_message = database_error_get_message( + database + ); + + assert(error_message != NULL); + assert(error_message[0] != '\0'); + + database_statement_finalize(statement); + + /* + * Une opération valide ultérieure efface l'erreur. + */ + statement = database_statement_prepare( + database, + "SELECT 1;" + ); + + assert(statement != NULL); + + assert( + database_error_get_code(database) == + DATABASE_ERROR_NONE + ); + + assert( + database_statement_step(statement) == + DATABASE_STATEMENT_STEP_ROW + ); + + assert( + database_error_get_code(database) == + DATABASE_ERROR_NONE + ); + + database_statement_finalize(statement); + database_close(database); +} + int main(void) { test_initial_error_state(); test_statement_error(); test_success_clears_previous_error(); + test_statement_bind_error(); + test_statement_other_bind_errors(); + test_statement_step_error(); printf( "DatabaseError : tous les tests sont valides.\n" diff --git a/tests/test_investigation_project b/tests/test_investigation_project index ee880919fb46300e47cb5fc16b75e647e726b029..ebee53a658b444bd200dad801ff183a8392366a5 100755 GIT binary patch literal 50984 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 delta 8374 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 W^lcq#-@2DBzcfJ}wSh7=r~W@%VD#Pq diff --git a/tests/test_transaction b/tests/test_transaction index 004b7cd4dd92706f1f428c38ede573d485915683..7291ecd12d3923831bc624b835fc5dc28291b9bd 100755 GIT binary patch literal 32720 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�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 delta 9892 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 diff --git a/tests/test_transaction.c b/tests/test_transaction.c index 27c694d..f3149f2 100644 --- a/tests/test_transaction.c +++ b/tests/test_transaction.c @@ -6,6 +6,7 @@ #include "database/database.h" #include "database/statement.h" #include "database/transaction.h" +#include "database/error.h" #include #include @@ -224,11 +225,93 @@ static void test_invalid_transaction_states(void) database_close(database); } +/** + * @brief Vérifie l'enregistrement des erreurs de transaction. + */ +static void test_transaction_error_state(void) +{ + Database *database = NULL; + const char *error_message = NULL; + + database = database_open(":memory:"); + + assert(database != NULL); + + /* + * Aucun commit n'est possible sans transaction active. + */ + assert( + !database_transaction_commit(database) + ); + + assert( + database_error_get_code(database) == + DATABASE_ERROR_INVALID_STATE + ); + + error_message = database_error_get_message( + database + ); + + assert(error_message != NULL); + assert(error_message[0] != '\0'); + + /* + * Un début de transaction valide efface l'erreur précédente. + */ + assert( + database_transaction_begin(database) + ); + + assert( + database_error_get_code(database) == + DATABASE_ERROR_NONE + ); + + /* + * Une transaction imbriquée est refusée. + */ + assert( + !database_transaction_begin(database) + ); + + assert( + database_error_get_code(database) == + DATABASE_ERROR_INVALID_STATE + ); + + database_error_clear(database); + + assert( + database_transaction_rollback(database) + ); + + assert( + database_error_get_code(database) == + DATABASE_ERROR_NONE + ); + + /* + * Un second rollback est impossible. + */ + assert( + !database_transaction_rollback(database) + ); + + assert( + database_error_get_code(database) == + DATABASE_ERROR_INVALID_STATE + ); + + database_close(database); +} + int main(void) { test_transaction_commit(); test_transaction_rollback(); test_invalid_transaction_states(); + test_transaction_error_state(); printf( "DatabaseTransaction : tous les tests sont valides.\n"