v0.3.3-pre.003-fix.003
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<!-- file: crates/ksp-store-postgres-lib/README.md -->
|
||||
<!-- version: 1 -->
|
||||
<!-- version: 2 -->
|
||||
|
||||
# ksp-store-postgres-lib
|
||||
|
||||
@@ -17,7 +17,7 @@ La crate possède seule pour PostgreSQL :
|
||||
- les roots système et le provider cryptographique AWS-LC ;
|
||||
- le bootstrap/moteur de migrations privé KSP ;
|
||||
- la table metadata `ksp_store_schema_migrations` ;
|
||||
- le sentinel `V000__bootstrap.sql` et son checksum SHA-256 ;
|
||||
- la migration logique V000 relocalisée sous `migrations/v000_bootstrap/` et son checksum SHA-256 historique ;
|
||||
- l'advisory transaction lock borné des migrations ;
|
||||
- les snapshots runtime/health sûrs destinés au bridge de façade ;
|
||||
- la fermeture explicite du pool et son fallback `Drop` best-effort ;
|
||||
@@ -69,13 +69,13 @@ Les configurations ne permettant pas de vérifier une identité serveur, comme `
|
||||
|
||||
## Migrations
|
||||
|
||||
La fondation embarque uniquement :
|
||||
La fondation historique V000 est embarquée sous :
|
||||
|
||||
```text
|
||||
migrations/V000__bootstrap.sql
|
||||
migrations/v000_bootstrap/tables/001_ksp_store_schema_migrations.sql
|
||||
```
|
||||
|
||||
Elle crée la metadata privée :
|
||||
La vertical slice V001 est ensuite répartie sous `migrations/v001_raw_transaction/{tables,constraints,indexes}/` tout en restant une migration logique unique. V000 crée la metadata privée :
|
||||
|
||||
```text
|
||||
ksp_store_schema_migrations
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: crates/ksp-store-postgres-lib/USAGE.md -->
|
||||
<!-- version: 1 -->
|
||||
<!-- version: 2 -->
|
||||
|
||||
# Utilisation de ksp-store-postgres-lib
|
||||
|
||||
@@ -98,13 +98,13 @@ 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. Le seul artefact initial est :
|
||||
Le backend embarque son propre moteur de migrations. La migration historique V000 est désormais matérialisée par :
|
||||
|
||||
```text
|
||||
migrations/V000__bootstrap.sql
|
||||
migrations/v000_bootstrap/tables/001_ksp_store_schema_migrations.sql
|
||||
```
|
||||
|
||||
Le bootstrap maintient :
|
||||
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
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-store-postgres-lib/src/schema.rs
|
||||
// version: 3
|
||||
// version: 4
|
||||
|
||||
/// Immutable V000 physical schema resource inventory.
|
||||
pub(crate) const V000_RESOURCES: &[SchemaResource] = &[SchemaResource {
|
||||
@@ -798,7 +798,7 @@ pub(crate) async fn verify_v001_external_compatibility(
|
||||
for row in unique_rows {
|
||||
let name = row.try_get::<usize, std::string::String>(0);
|
||||
let constraint_backed = row.try_get::<usize, bool>(1);
|
||||
let (name, constraint_backed) = match (name, constraint_backed) {
|
||||
let (_name, constraint_backed) = match (name, constraint_backed) {
|
||||
(std::result::Result::Ok(name), std::result::Result::Ok(constraint_backed)) => (name, constraint_backed),
|
||||
_ => return schema_query_error("schema_unique_index_inventory_decode"),
|
||||
};
|
||||
@@ -1082,10 +1082,26 @@ async fn inspect_equivalent_constraint(
|
||||
|
||||
fn expected_constraint_definition(resource_sql: &str, name: &str) -> std::option::Option<std::string::String> {
|
||||
let marker = std::format!("ADD CONSTRAINT {name} ");
|
||||
let start = resource_sql.find(marker.as_str())?.checked_add(marker.len())?;
|
||||
let tail = resource_sql.get(start..)?;
|
||||
let end = tail.find(';')?;
|
||||
let definition = tail.get(..end)?;
|
||||
let marker_start = match resource_sql.find(marker.as_str()) {
|
||||
std::option::Option::Some(value) => value,
|
||||
std::option::Option::None => return std::option::Option::None,
|
||||
};
|
||||
let start = match marker_start.checked_add(marker.len()) {
|
||||
std::option::Option::Some(value) => value,
|
||||
std::option::Option::None => return std::option::Option::None,
|
||||
};
|
||||
let tail = match resource_sql.get(start..) {
|
||||
std::option::Option::Some(value) => value,
|
||||
std::option::Option::None => return std::option::Option::None,
|
||||
};
|
||||
let end = match tail.find(';') {
|
||||
std::option::Option::Some(value) => value,
|
||||
std::option::Option::None => return std::option::Option::None,
|
||||
};
|
||||
let definition = match tail.get(..end) {
|
||||
std::option::Option::Some(value) => value,
|
||||
std::option::Option::None => return std::option::Option::None,
|
||||
};
|
||||
return std::option::Option::Some(normalize_catalog_sql(definition));
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-store-postgres-lib/tests/postgres_foundation_live.rs
|
||||
// version: 2
|
||||
// version: 3
|
||||
|
||||
#![warn(missing_docs)]
|
||||
#![deny(unreachable_pub)]
|
||||
@@ -12,7 +12,7 @@
|
||||
//! the URI, and cleans up only the isolated schema it proved absent first. It
|
||||
//! validates migration/bootstrap behavior, not RawTransaction capabilities.
|
||||
|
||||
const LIVE_BOOTSTRAP_SQL: &str = include_str!("../migrations/V000__bootstrap.sql");
|
||||
const LIVE_BOOTSTRAP_SQL: &str = include_str!("../migrations/v000_bootstrap/tables/001_ksp_store_schema_migrations.sql");
|
||||
const LIVE_BROKEN_CHECKSUM_A: &str = "0000000000000000000000000000000000000000000000000000000000000000";
|
||||
const LIVE_BROKEN_CHECKSUM_B: &str = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
|
||||
const LIVE_MANAGED_SCHEMA_DROP_SQL: &str = r#"DROP TABLE IF EXISTS ksp_raw_transaction_observations;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-store-postgres-lib/unit_tests/schema.rs
|
||||
// version: 1
|
||||
// version: 2
|
||||
|
||||
fn actual_column(name: &str, udt_name: &str, nullable: bool) -> super::ActualColumn {
|
||||
return super::ActualColumn {
|
||||
@@ -100,12 +100,10 @@ fn pre_003_fix_001_catalog_normalization_and_resource_owned_constraint_definitio
|
||||
let normalized = super::normalize_catalog_sql("CHECK ((slot >= (0)::numeric) AND (slot <= (18446744073709551615)::numeric))");
|
||||
assert_eq!(normalized, "checkslot>=0andslot<=18446744073709551615");
|
||||
let resource = crate::V001_RESOURCES.iter().find(|resource| return resource.id == "constraints/006_ck_ksp_raw_transactions_slot.sql");
|
||||
assert!(resource.is_some(), "V001 slot constraint resource must remain embedded");
|
||||
let resource = match resource {
|
||||
std::option::Option::Some(value) => value,
|
||||
std::option::Option::None => {
|
||||
assert!(false, "V001 slot constraint resource must remain embedded");
|
||||
return;
|
||||
},
|
||||
std::option::Option::None => return,
|
||||
};
|
||||
let expected = super::expected_constraint_definition(resource.sql, "ck_ksp_raw_transactions_slot");
|
||||
assert_eq!(expected.as_deref(), std::option::Option::Some(normalized.as_str()));
|
||||
|
||||
Reference in New Issue
Block a user