diff --git a/examples/schema_evolution.lux b/examples/schema_evolution.lux index fec0a6f..9834d39 100644 --- a/examples/schema_evolution.lux +++ b/examples/schema_evolution.lux @@ -1,21 +1,42 @@ // Schema Evolution Demo -// Demonstrates version tracking using runtime Schema operations +// Demonstrates version tracking and automatic migrations // ============================================================ -// PART 1: Runtime Schema Operations +// PART 1: Type-Declared Migrations // ============================================================ -// Create versioned values at runtime -let user1 = Schema.versioned("User", 1, "Alice") -let user2 = Schema.versioned("User", 2, "Bob") +// Define a versioned type with a migration from v1 to v2 +type User @v2 { + name: String, + email: String, + + // Migration from v1: add default email + from @v1 = { name: old.name, email: "unknown@example.com" } +} + +// Create a v1 user +let v1_user = Schema.versioned("User", 1, { name: "Alice" }) +let v1_version = Schema.getVersion(v1_user) // 1 + +// Migrate to v2 - uses the declared migration automatically +let v2_user = Schema.migrate(v1_user, 2) +let v2_version = Schema.getVersion(v2_user) // 2 + +// ============================================================ +// PART 2: Runtime Schema Operations (separate type) +// ============================================================ + +// Create versioned values for a different type (no migration) +let config1 = Schema.versioned("Config", 1, "debug") +let config2 = Schema.versioned("Config", 2, "release") // Check versions -let v1 = Schema.getVersion(user1) // 1 -let v2 = Schema.getVersion(user2) // 2 +let c1 = Schema.getVersion(config1) // 1 +let c2 = Schema.getVersion(config2) // 2 -// Migrate to newer version (upgrade) -let upgraded = Schema.migrate(user1, 2) -let upgradedVersion = Schema.getVersion(upgraded) // 2 +// Migrate config (auto-migration since no explicit migration defined) +let upgradedConfig = Schema.migrate(config1, 2) +let upgradedConfigVersion = Schema.getVersion(upgradedConfig) // 2 // ============================================================ // PART 2: Practical Example - API Versioning @@ -45,12 +66,16 @@ let payload2 = resp2.payload fn main(): Unit with {Console} = { Console.print("=== Schema Evolution Demo ===") Console.print("") - Console.print("Part 1: Runtime schema operations") - Console.print(" User v1 version: " + toString(v1)) - Console.print(" User v2 version: " + toString(v2)) - Console.print(" After upgrade: " + toString(upgradedVersion)) + Console.print("Part 1: Type-declared migrations") + Console.print(" User before migration: v" + toString(v1_version)) + Console.print(" User after migration: v" + toString(v2_version)) Console.print("") - Console.print("Part 2: API versioning") + Console.print("Part 2: Runtime schema operations") + Console.print(" Config v1 version: " + toString(c1)) + Console.print(" Config v2 version: " + toString(c2)) + Console.print(" After upgrade: " + toString(upgradedConfigVersion)) + Console.print("") + Console.print("Part 3: API versioning") Console.print(" Response v1 payload: " + payload1) Console.print(" Response v2 payload: " + payload2) } diff --git a/flake.nix b/flake.nix index f5ef40b..ded4279 100644 --- a/flake.nix +++ b/flake.nix @@ -31,7 +31,7 @@ shellHook = '' # Build and add lux to PATH - if [ ! -f target/release/lux ] || [ Cargo.toml -nt target/release/lux ] || [ src/main.rs -nt target/release/lux ]; then + if [ ! -f target/release/lux ] || [ Cargo.toml -nt target/release/lux ] || [ -n "$(find src -name '*.rs' -newer target/release/lux 2>/dev/null | head -1)" ]; then echo "Building lux..." cargo build --release fi