Premiere commit - Omika
This commit is contained in:
@@ -0,0 +1,129 @@
|
||||
# Détecteur de schéma HFSQL (DatabaseSchemaDetector)
|
||||
|
||||
## Stratégie générale
|
||||
|
||||
Le détecteur détermine la version réelle du schéma de base (Batik ou Omika) à
|
||||
partir de la **structure physique** exposée par HFSQL OLE DB, et uniquement à
|
||||
partir de celle-ci.
|
||||
|
||||
La décision ne repose **jamais** sur :
|
||||
|
||||
- le nom de la base (`BATIK_TEST`, `OMIKA_TEST`, ou tout autre nom client) ;
|
||||
- le nom du serveur ;
|
||||
- la présence d'un mot de passe ;
|
||||
- le nombre de tables ;
|
||||
- OpenSchema (`GetSchema`).
|
||||
|
||||
Chaque canari est testé par une requête structurelle réelle et contrôlée :
|
||||
|
||||
```sql
|
||||
SELECT TOP 0 <colonne> FROM <table>
|
||||
```
|
||||
|
||||
Le **succès / échec structurel** de la requête indique la présence ou l'absence
|
||||
de la colonne. Aucune donnée métier n'est lue (`TOP 0` ne retourne aucune ligne).
|
||||
|
||||
## Canaris utilisés
|
||||
|
||||
### Socle commun (présent dans Batik et Omika)
|
||||
|
||||
| Table | Colonne | Rôle |
|
||||
|-------|---------|------|
|
||||
| `Client` | `CL_PKID` | Confirme que la base est une base Omika/Batik compatible |
|
||||
|
||||
### Canaris Omika (colonnes Omika-only de `Client`)
|
||||
|
||||
| Table | Colonne | Rôle |
|
||||
|-------|---------|------|
|
||||
| `Client` | `CL_CleType` | Marqueur Omika (colonne absente de Batik) |
|
||||
| `Client` | `GUID` | Marqueur Omika (colonne absente de Batik) |
|
||||
|
||||
### Canari de confirmation Omika (table Omika-only)
|
||||
|
||||
| Table | Colonne | Rôle |
|
||||
|-------|---------|------|
|
||||
| `Role` | `R_PKID` | Confirme la migration Omika en cas d'ambiguïté |
|
||||
|
||||
## Pourquoi ces canaris discriminent Batik / Omika
|
||||
|
||||
Les colonnes `CL_CleType` et `GUID` de la table `Client` sont marquées
|
||||
`IsOmikaOnly` dans les modèles physiques générés et ont été **confirmées par le
|
||||
model-audit** :
|
||||
|
||||
- présentes physiquement dans `OMIKA_TEST` (statut `VERIFIED`) ;
|
||||
- absentes de `BATIK_TEST`.
|
||||
|
||||
La table `Role` est une table réellement Omika-only (absente de Batik), confirmée
|
||||
par le model-audit. Elle sert de canari de confirmation indépendant.
|
||||
|
||||
La table `Client` est accessible en accès direct dans les deux bases, ce qui rend
|
||||
la détection possible sans dépendre des mots de passe de fichiers protégés.
|
||||
|
||||
## Algorithme de décision
|
||||
|
||||
1. **Socle commun** : `SELECT TOP 0 CL_PKID FROM Client` doit réussir.
|
||||
Sinon → échec explicite (base non reconnue).
|
||||
2. **Canaris Omika** : tester `CL_CleType` et `GUID` dans `Client`.
|
||||
3. **Canari de confirmation** : tester `R_PKID` dans `Role`.
|
||||
|
||||
Décision :
|
||||
|
||||
- `CL_CleType` **et** `GUID` présents → **Omika**.
|
||||
- Un seul des deux présent → ambiguïté :
|
||||
- si `Role` présent → **Omika** ;
|
||||
- sinon → échec explicite (structure incohérente).
|
||||
- Aucun canari Omika présent (socle commun valide) → **Batik**.
|
||||
|
||||
La base n'est jamais déclarée Batik ou Omika par défaut : la décision repose
|
||||
toujours sur la structure réellement observée.
|
||||
|
||||
## Résultats d'intégration
|
||||
|
||||
| Base | Résultat attendu | Résultat observé |
|
||||
|------|------------------|------------------|
|
||||
| `BATIK_TEST` | `DatabaseSchemaVersion.Batik` | `Batik` |
|
||||
| `OMIKA_TEST` | `DatabaseSchemaVersion.Omika` | `Omika` |
|
||||
|
||||
Les tests d'intégration réels utilisent `config/hfsql-test.local.json` et le
|
||||
provider OLE DB `PCSOFT.HFSQL`. Ils sont ignorés automatiquement si la
|
||||
configuration locale ou le serveur sont indisponibles.
|
||||
|
||||
Aucun secret, aucune chaîne de connexion, aucune donnée métier n'est exposée.
|
||||
|
||||
## Tests d'intégration du chemin de création (CreateAsync)
|
||||
|
||||
En complément de la détection de schéma, des tests d'intégration réels couvrent
|
||||
le chemin d'écriture `CreateAsync` sur les deux schémas (Batik et Omika) :
|
||||
|
||||
- `CreateAsync_Batik_PersistsAndRollsBack`
|
||||
- `CreateAsync_Omika_PersistsAndRollsBack`
|
||||
|
||||
### Principe
|
||||
|
||||
1. Les mots de passe de fichiers (Extended Properties) sont résolus par
|
||||
`HfSqlFileAccessResolver` pour les fichiers nécessaires au chemin Create
|
||||
(`Client`, `ParametreMetier`, `Adresse`, `Client_Adresse`).
|
||||
2. Une connexion physique OLE DB est ouverte avec ces mots de passe.
|
||||
3. Une **transaction externe** est créée sur cette connexion.
|
||||
4. `CreateAsync` est exécuté **dans cette transaction** via le repository
|
||||
(Batik ou Omika).
|
||||
5. Le client canonique retourné est vérifié (nom, identifiant non vide).
|
||||
6. La transaction est **annulée (rollback)** : aucune trace n'est laissée en base.
|
||||
|
||||
### Pourquoi une transaction externe
|
||||
|
||||
Les repositories `BatikClientRepository` et `OmikaClientRepository` exposent une
|
||||
surcharge `CreateAsync(command, DbTransaction?, cancellationToken)` qui réutilise
|
||||
une transaction externe fournie par l'appelant. En production, la surcharge
|
||||
standard `CreateAsync(command, cancellationToken)` est utilisée et une transaction
|
||||
interne est créée puis commitée. Dans les tests, la transaction externe permet de
|
||||
**vérifier la persistance réelle puis de l'annuler** sans polluer la base.
|
||||
|
||||
### Garanties
|
||||
|
||||
- Aucune donnée métier n'est laissée en base (rollback systématique).
|
||||
- Aucun secret, aucune chaîne de connexion, aucun mot de passe n'est exposé.
|
||||
- Les tests sont ignorés automatiquement si la configuration locale ou le
|
||||
serveur sont indisponibles.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user