Syntax Reference

Complete reference for SchemaLang syntax, types, and modifiers.

Overview

SchemaLang uses a declarative syntax to define data structures. Each definition consists of structs (record types), fields (data members), and optional enums (enumeration types).

Basic Pattern

struct StructName {
    type: fieldName: modifiers: description("text");
}

Struct Definition

Basic Struct

struct User {
    int64: id: primary_key: required: auto_increment: 
        description("User ID");
    string: username: required: 
        description("Username");
}

Versioned Struct

Add versioning for migration support:

struct User: version(1.2.0) {
    int64: id: primary_key: required: auto_increment: 
        description("User ID");
    string: username: required: 
        description("Username");
}

Generator-Specific Structs

Control which generators process this struct:

// Only generate for C++ and SQLite
struct InternalData: gens_enabled(Cpp, SQLite) {
    string: data: required: description("Internal data");
}

// Exclude from JSON generation
struct SecureData: gens_disabled(Json) {
    string: password: required: description("Password");
}

Field Syntax

Field Components

Every field has four required parts:

type: fieldName: modifiers: description("text");
Component Description Required
type Data type (primitive, array, enum, or struct)
fieldName Identifier for the field
modifiers Constraints and attributes (separated by colons) ✓ (at least one)
description Human-readable documentation

Multi-Line Fields

Long field definitions can span multiple lines:

struct Product {
    int64: id: primary_key: required: auto_increment: 
        description("Product identifier");
    string: name: required: unique: 
        description("Product name, must be unique across catalog");
    double: price: required: 
        description("Price in USD");
}

Data Types

Integer Types

Type Size Range
int8 8-bit -128 to 127
int16 16-bit -32,768 to 32,767
int32 32-bit -2,147,483,648 to 2,147,483,647
int64 64-bit -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807
uint8 8-bit unsigned 0 to 255
uint16 16-bit unsigned 0 to 65,535
uint32 32-bit unsigned 0 to 4,294,967,295
uint64 64-bit unsigned 0 to 18,446,744,073,709,551,615

Floating Point Types

Type Precision Use Case
float Single (32-bit) General floating-point numbers
double Double (64-bit) High-precision calculations

Other Primitive Types

Type Description
bool Boolean value (true/false)
string Text string (UTF-8)
void No value (mainly for function returns)

Complex Types

Arrays

struct Post {
    array<string>: tags: optional: 
        description("Post tags");
    array<Comment>: comments: optional: 
        description("Post comments");
}

References

struct Comment {
    int64: postId: required: reference(Post.id): 
        description("Parent post ID");
}

Custom Types (Other Structs)

struct User {
    Profile: profile: required: 
        description("User profile");
}

Modifiers

Core Modifiers

Modifier Description Example
required Field must have a value string: name: required
optional Field can be null/empty string: nickname: optional
unique Value must be unique string: email: unique
primary_key Primary key field int64: id: primary_key
auto_increment Auto-increment on insert int64: id: auto_increment

Relationship Modifiers

Modifier Description Example
reference(Struct.field) Foreign key relationship int64: userId: reference(User.id)

Array Modifiers

Modifier Description Example
unique_items Array elements must be unique array<string>: tags: unique_items
min_items(n) Minimum array length array<string>: tags: min_items(1)
max_items(n) Maximum array length array<string>: tags: max_items(10)

Generator Control Modifiers

Modifier Description Example
gens_enabled(...) Only generate for listed generators string: data: gens_enabled(Cpp,SQLite)
gens_disabled(...) Exclude from listed generators string: password: gens_disabled(Json)

Enumerations

Basic Enum

enum UserRole {
    Guest,
    User,
    Moderator,
    Admin
}

Enum with Explicit Values

enum Status {
    Inactive = 0,
    Active = 1,
    Suspended = 2,
    Banned = 3
}

Using Enums in Structs

enum UserRole {
    Guest,
    User,
    Admin
}

struct User {
    int64: id: primary_key: required: auto_increment: 
        description("User ID");
    string: username: required: 
        description("Username");
    UserRole: role: required: 
        description("User role");
}
Note: Enums must be defined before they are used in struct definitions.

Include Directives

Split your schema across multiple files:

types.schema

enum UserRole {
    Guest,
    User,
    Admin
}

struct Address {
    string: street: required: description("Street address");
    string: city: required: description("City");
    string: country: required: description("Country");
}

user.schema

include "./types.schema"

struct User {
    int64: id: primary_key: required: auto_increment: 
        description("User ID");
    string: username: required: 
        description("Username");
    UserRole: role: required: 
        description("User role");
    Address: address: optional: 
        description("User address");
}

Included files are merged into the same namespace, allowing you to reference types across files.

Best Practices

  • Always include descriptions - They're required and help document your schema
  • Use int64 for IDs - Provides sufficient range for most use cases
  • Explicitly mark required/optional - Makes intent clear
  • Use enums for constrained values - Better than magic numbers or strings
  • Version your structs - Enable automatic migration support
  • Organize with includes - Split large schemas into logical files