icydb_core/db/schema_evolution/registry.rs
1//! Module: db::schema_evolution::registry
2//! Responsibility: completed schema-migration registry contract.
3//! Does not own: durable commit layout or in-progress migration cursor storage.
4//! Boundary: schema-evolution guard state consumed before migration execution.
5
6use crate::db::identity::EntityName;
7use std::collections::BTreeSet;
8
9///
10/// MigrationRegistryKey
11///
12/// MigrationRegistryKey names one completed schema migration by canonical
13/// migration identity plus monotonic version.
14/// The registry uses this key to reject repeat execution before the lower
15/// migration engine is invoked.
16///
17
18#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
19pub struct MigrationRegistryKey {
20 migration_id: EntityName,
21 version: u64,
22}
23
24impl MigrationRegistryKey {
25 /// Build one registry key from canonical migration identity.
26 #[must_use]
27 pub const fn new(migration_id: EntityName, version: u64) -> Self {
28 Self {
29 migration_id,
30 version,
31 }
32 }
33
34 /// Return the canonical migration identity.
35 #[must_use]
36 pub const fn migration_id(self) -> EntityName {
37 self.migration_id
38 }
39
40 /// Return the monotonic migration version.
41 #[must_use]
42 pub const fn version(self) -> u64 {
43 self.version
44 }
45}
46
47///
48/// MigrationRegistry
49///
50/// MigrationRegistry tracks schema migrations that have completed above the
51/// lower `db::migration` execution engine.
52/// This first implementation is an explicit owner object so no commit/storage
53/// layout changes are required by the schema-evolution slice.
54///
55
56#[derive(Clone, Debug, Default)]
57pub struct MigrationRegistry {
58 completed: BTreeSet<MigrationRegistryKey>,
59}
60
61impl MigrationRegistry {
62 /// Build one empty completed-migration registry.
63 #[must_use]
64 pub const fn new() -> Self {
65 Self {
66 completed: BTreeSet::new(),
67 }
68 }
69
70 /// Return whether the migration id/version is already recorded as complete.
71 #[must_use]
72 pub fn is_applied(&self, migration_id: EntityName, version: u64) -> bool {
73 self.completed
74 .contains(&MigrationRegistryKey::new(migration_id, version))
75 }
76
77 /// Record one migration id/version as complete.
78 pub fn record_applied(&mut self, migration_id: EntityName, version: u64) {
79 self.completed
80 .insert(MigrationRegistryKey::new(migration_id, version));
81 }
82
83 /// Return the number of completed migration keys tracked by this registry.
84 #[must_use]
85 pub fn len(&self) -> usize {
86 self.completed.len()
87 }
88
89 /// Return whether this registry currently has no completed migration keys.
90 #[must_use]
91 pub fn is_empty(&self) -> bool {
92 self.completed.is_empty()
93 }
94}