Files
khadhroony-solana-project/crates/ksp-store-postgres-lib/USAGE.md
2026-08-30 11:00:07 +02:00

181 lines
6.8 KiB
Markdown

<!-- file: crates/ksp-store-postgres-lib/USAGE.md -->
<!-- version: 3 -->
# Utilisation de ksp-store-postgres-lib
## 1. Quand utiliser cette crate directement
Le consumer applicatif normal utilise `ksp-store-lib`.
Une dépendance directe à `ksp-store-postgres-lib` est réservée aux composants qui implémentent ou testent le bridge physique PostgreSQL. La crate backend ne doit pas devenir une façade parallèle.
Un tel composant doit déclarer explicitement le backend et `ksp-store-api`, car `PostgresBackendSettings::new` reçoit le `RawNetworkId` backend-neutral sans le réexporter :
```toml
[dependencies]
ksp-store-api = { path = "../ksp-store-api" }
ksp-store-postgres-lib = { path = "../ksp-store-postgres-lib" }
```
## 2. Construire le bridge physique
`PostgresBackendSettings` reçoit des valeurs déjà possédées et validées par la couche appelante. L'URI est sensible et son `Debug` est redacted.
```rust
fn backend_settings(
network: ksp_store_api::RawNetworkId,
connection_uri: std::string::String,
) -> ksp_store_postgres_lib::PostgresBackendSettings {
return ksp_store_postgres_lib::PostgresBackendSettings::new(
network,
connection_uri,
8,
std::time::Duration::from_secs(10),
std::time::Duration::from_secs(5),
std::time::Duration::from_secs(10),
std::time::Duration::from_secs(5),
ksp_store_postgres_lib::PostgresBackendTlsMode::VerifyFull,
true,
std::time::Duration::from_secs(30),
std::time::Duration::from_secs(10),
);
}
```
Le backend reçoit un seul `RawNetworkId`. Une instance physique n'est pas un routeur multi-réseau.
## 3. Ouvrir, sonder et fermer
```rust
async fn use_backend(
settings: ksp_store_postgres_lib::PostgresBackendSettings,
) -> std::result::Result<(), ksp_store_postgres_lib::PostgresBackendError> {
let backend = ksp_store_postgres_lib::PostgresBackend::open(settings).await;
let backend = match backend {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let runtime = backend.runtime_snapshot();
let _capacity = runtime.pool_capacity();
let _size = runtime.pool_size();
let _available = runtime.pool_available();
let _waiting = runtime.pool_waiting();
let health = backend.health().await;
let _ready = health.ready();
let _migration_version = health.migration_version();
let _pending = health.pending_migration_count();
let _safe_error_kind = health.last_error_kind();
return backend.close(std::time::Duration::from_secs(5)).await;
}
```
`open` prouve la connexion et le bootstrap avant de retourner. `close` ferme le pool puis attend son drain dans la deadline fournie.
## 4. Choisir le mode TLS
### `VerifyFull`
À utiliser pour les connexions PostgreSQL protégées :
```rust
ksp_store_postgres_lib::PostgresBackendTlsMode::VerifyFull
```
Le backend charge les roots système et vérifie certificat + identité serveur. Il rejette une configuration ne fournissant pas d'identité vérifiable.
### `Disabled`
```rust
ksp_store_postgres_lib::PostgresBackendTlsMode::Disabled
```
Ce mode désactive explicitement TLS. Il ne doit être utilisé que lorsque la topologie de déploiement justifie clairement une connexion non chiffrée.
La valeur typée choisie par KSP prime sur les paramètres SSL de l'URI.
## 5. Bootstrap et migrations
Le backend embarque son propre moteur de migrations. La migration historique V000 est désormais matérialisée par :
```text
migrations/v000_bootstrap/tables/001_ksp_store_schema_migrations.sql
```
Les migrations suivantes conservent une version logique unique tout en séparant leurs ressources physiques par famille sous `migrations/vNNN_name/{tables,constraints,indexes}/`. Le bootstrap maintient :
```text
ksp_store_schema_migrations
version
name
checksum SHA-256
```
Le runner est transactionnel et sérialisé par advisory transaction lock. Une divergence de checksum/nom/version ou une history plus récente est terminale ; aucun down migration automatique n'est exécuté.
`schema_autocreate` contrôle l'initialisation/adoption du schéma et `schema_autoupdate` les migrations pending ainsi que les réparations additives sûres. Le constructeur legacy `auto_migrate` mappe encore les deux politiques pour compatibilité source.
## 6. Classifier les erreurs sans fuite
```rust
match error.kind() {
ksp_store_postgres_lib::PostgresBackendErrorKind::ConfigInvalid => {}
ksp_store_postgres_lib::PostgresBackendErrorKind::ConnectFailed => {}
ksp_store_postgres_lib::PostgresBackendErrorKind::DataInvalid => {}
ksp_store_postgres_lib::PostgresBackendErrorKind::PoolTimeout => {}
ksp_store_postgres_lib::PostgresBackendErrorKind::HealthFailed => {}
ksp_store_postgres_lib::PostgresBackendErrorKind::MigrationFailed => {}
ksp_store_postgres_lib::PostgresBackendErrorKind::MigrationMismatch => {}
ksp_store_postgres_lib::PostgresBackendErrorKind::ReadFailed => {}
ksp_store_postgres_lib::PostgresBackendErrorKind::SchemaNewer => {}
ksp_store_postgres_lib::PostgresBackendErrorKind::ShutdownTimeout => {}
ksp_store_postgres_lib::PostgresBackendErrorKind::TlsFailed => {}
ksp_store_postgres_lib::PostgresBackendErrorKind::WrongNetwork => {}
_ => {}
}
let _safe_phase = error.phase();
```
Ne pas reconstruire un diagnostic utilisateur à partir de l'erreur brute PostgreSQL : cette erreur n'est volontairement pas conservée par le bridge.
## 7. Lectures RAW transaction
Depuis `0.3.3-pre.004`, un backend ouvert expose quatre lectures backend-specific retournant exclusivement les modèles communs :
```rust
let transaction = backend.get_raw_transaction(&reference).await;
let observation = backend.get_raw_transaction_observation(&observation_key).await;
let retention = backend.get_raw_transaction_retention_state(&reference).await;
let tombstone = backend.get_raw_transaction_tombstone(&reference).await;
```
Le backend ne rend jamais `tokio_postgres::Row`, SQL, SQLSTATE ou valeur de bind. Pour les références réseau-scopées, un mauvais réseau est rejeté avant acquisition d'un client du pool. Une corruption de row est projetée vers `DataInvalid`, un échec physique de lecture vers `ReadFailed`, et les erreurs de pool conservent leur classification bornée existante.
`get_raw_transaction` retourne :
```text
Full -> payload chaud
Archived -> payload archive reconstruit
Purged -> None
absent -> None
```
Le tombstone `Purged` reste lisible séparément.
## 8. Ce que cette crate ne permet pas encore
La tranche ne fournit pas encore :
```text
list_raw_transactions / cursor
écritures canonique + observation
transitions de rétention
implémentations complètes des six traits RawTransaction*
capabilities RawAccount*
```
Ces surfaces sont ajoutées dans les prereleases suivantes avant le dispatch `ksp-store-lib`.