Better source change detection using find instead of single file check. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
84 lines
3.0 KiB
Plaintext
84 lines
3.0 KiB
Plaintext
// 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 {}
|