prax-schema 0.2.0

Schema parser and AST for the Prax ORM
Documentation

prax-schema

Schema parser and AST for the Prax ORM.

This crate provides:

  • Schema Definition Language (SDL) parser for .prax files
  • Configuration parser for prax.toml files
  • Abstract Syntax Tree (AST) types for schema representation
  • Schema validation and semantic analysis

Quick Start

Parse a schema string:

use prax_schema::parse_schema;

let schema = parse_schema(r#"
model User {
    id    Int    @id @auto
    email String @unique
    name  String?
}
"#).unwrap();

assert!(schema.get_model("User").is_some());

Parsing Models

Models define database tables with typed fields:

use prax_schema::parse_schema;

let schema = parse_schema(r#"
model Post {
    id        Int      @id @auto
    title     String
    content   String?
    published Boolean  @default(false)
    viewCount Int      @default(0)
}
"#).unwrap();

let post = schema.get_model("Post").unwrap();
assert_eq!(post.fields.len(), 5);

// Check field properties
let title = post.fields.get("title").unwrap();
assert!(!title.is_optional());

let content = post.fields.get("content").unwrap();
assert!(content.is_optional());

Parsing Enums

Enums define custom value types:

use prax_schema::parse_schema;

let schema = parse_schema(r#"
enum Role {
    User
    Admin
    Moderator
}

model User {
    id   Int  @id @auto
    role Role @default(User)
}
"#).unwrap();

let role_enum = schema.get_enum("Role").unwrap();
assert_eq!(role_enum.variants.len(), 3);

Parsing Relations

Relations define relationships between models:

use prax_schema::parse_schema;

let schema = parse_schema(r#"
model User {
    id    Int    @id @auto
    posts Post[]
}

model Post {
    id       Int  @id @auto
    authorId Int
    author   User @relation(fields: [authorId], references: [id])
}
"#).unwrap();

let post = schema.get_model("Post").unwrap();
let author_field = post.fields.get("author").unwrap();
assert!(author_field.is_relation());

Parsing Views

Views represent SQL views:

use prax_schema::parse_schema;

let schema = parse_schema(r#"
model User {
    id     Int    @id @auto
    active Boolean
}

view ActiveUsers {
    id Int @unique

    @@map("active_users_view")
}
"#).unwrap();

assert!(schema.get_view("ActiveUsers").is_some());

Parsing Server Groups

Server groups define multi-server configurations:

use prax_schema::parse_schema;

let schema = parse_schema(r#"
serverGroup MainCluster {
    server primary {
        url  = "postgres://primary/db"
        role = "primary"
    }

    server replica1 {
        url    = "postgres://replica1/db"
        role   = "replica"
        weight = 100
    }

    @@strategy("ReadReplica")
    @@loadBalance("RoundRobin")
}
"#).unwrap();

let cluster = schema.get_server_group("MainCluster").unwrap();
assert_eq!(cluster.servers.len(), 2);

Schema Validation

Validate schemas for correctness:

use prax_schema::validate_schema;

// Valid schema passes validation
let result = validate_schema(r#"
model User {
    id    Int    @id @auto
    email String @unique
}
"#);
assert!(result.is_ok());

// Schema with relations validates correctly
let result = validate_schema(r#"
model User {
    id    Int    @id @auto
    posts Post[]
}
model Post {
    id       Int  @id @auto
    authorId Int
    author   User @relation(fields: [authorId], references: [id])
}
"#);
assert!(result.is_ok());

Schema Statistics

Get statistics about a schema:

use prax_schema::parse_schema;

let schema = parse_schema(r#"
model User { id Int @id @auto }
model Post { id Int @id @auto }
enum Role { User Admin }
type Address { street String }
"#).unwrap();

let stats = schema.stats();
assert_eq!(stats.model_count, 2);
assert_eq!(stats.enum_count, 1);
assert_eq!(stats.type_count, 1);

Configuration Parsing

Parse prax.toml configuration:

use prax_schema::config::PraxConfig;

let config: PraxConfig = toml::from_str(r#"
[database]
provider = "postgresql"
url = "postgres://localhost/mydb"

[database.pool]
max_connections = 10

[generator.client]
output = "./src/generated"
"#).unwrap();

assert_eq!(config.database.pool.max_connections, 10);

Prelude

Import commonly used types:

use prax_schema::prelude::*;

// Now you can use parse_schema, Schema, etc.
let schema = parse_schema("model User { id Int @id }").unwrap();