labfy-investigation/docs/tickets/open/TICKET-026.md

366 lines
8.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Ticket #026 — Migrer linitialisation vers la couche Database
## Contexte
Le ticket #025 a introduit linfrastructure 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 derreurs.
Cependant, `database_initialize()` utilise encore directement plusieurs fonctions de lAPI 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 labstraction `Database`.
## Objectif
Réécrire linitialisation dune nouvelle enquête afin quelle utilise linfrastructure créée au ticket #025.
Linitialisation doit rester atomique :
- soit la base est entièrement initialisée ;
- soit aucune donnée partielle nest conservée.
## Travail à réaliser
### Adapter linstallation du schéma
Modifier la signature actuelle :
```C
bool schema_install_v1(
sqlite3 *database
);
```
afin quelle reçoive un contexte Database :
```C
bool schema_install_v1(
Database *database
);
```
Linstallation du fichier SQL complet pourra continuer à utiliser `sqlite3_exec()` en interne, car le schéma contient plusieurs instructions SQL.
Laccès au handle SQLite devra passer par lAPI interne :
```C
database_get_handle()
```
La fonction ne devra réaliser ni `COMMIT` ni `ROLLBACK`.
### Migrer linsertion des métadonnées
Réécrire les fonctions responsables de linsertion dans la table `metadata` avec `DatabaseStatement`.
Les opérations devront utiliser lAPI 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 linsertion de lenquête
Réécrire linsertion 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 lUUID
ouverture de Database
début de transaction
installation du schéma V1
insertion des métadonnées
insertion de lenquête
commit
fermeture de Database
```
Tout échec après le début de la transaction doit provoquer un rollback.
### Utiliser linfrastructure derreurs
Les erreurs rencontrées pendant :
- linstallation du schéma ;
- la préparation dune requête ;
- le binding dun paramètre ;
- lexécution dune requête ;
- le début dune transaction ;
- le commit ;
- le rollback ;
doivent être enregistrées dans le contexte Database lorsque celui-ci est disponible.
Linfrastructure 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 lancien code SQLite
Supprimer de la logique dinitialisation 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 lactivation 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 :
- linitialisation 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 quune initialisation valide crée :
- le schéma V1 ;
- les tables attendues ;
- les métadonnées obligatoires ;
- une seule ligne dans investigation ;
- le bon nom denquê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 dinitialisation 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 nest conservée ;
- aucune seconde enquête nest 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 dacceptation
- [ ] `database_initialize()` nappelle 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 lAPI interne.
- [ ] Aucun `sqlite3_stmt *` nest manipulé dans le code dinitialisation.
- [ ] 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 dinterface 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.
Linitialisation dune enquête doit être entièrement transactionnelle, testée et cohérente avec larchitecture mise en place au ticket #025.
## Commit attendu
Une fois tous les critères dacceptation 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
```