// Schema Evolution Demo // Demonstrates version tracking and automatic migrations // ============================================================ // PART 1: Type-Declared Migrations // ============================================================ // 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 c1 = Schema.getVersion(config1) // 1 let c2 = Schema.getVersion(config2) // 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 // ============================================================ // Simulate different API response versions fn createResponseV1(data: String): { version: Int, payload: String } = { version: 1, payload: data } fn createResponseV2(data: String, timestamp: Int): { version: Int, payload: String, meta: { ts: Int } } = { version: 2, payload: data, meta: { ts: timestamp } } // Version-aware processing fn getPayload(response: { version: Int, payload: String }): String = response.payload let resp1 = createResponseV1("Hello") let resp2 = createResponseV2("World", 1234567890) let payload1 = getPayload(resp1) let payload2 = resp2.payload // ============================================================ // RESULTS // ============================================================ fn main(): Unit with {Console} = { Console.print("=== Schema Evolution Demo ===") Console.print("") 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: 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) } let output = run main() with {}