Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

CLI Commands

The qail command-line tool.

Installation

cargo install qail

Commands

qail parse

Parse QAIL text syntax to SQL:

qail parse "get users fields * where active = true"
# SELECT * FROM users WHERE active = true

qail pull

Extract schema from database:

qail pull postgres://user:pass@localhost/db > schema.qail

qail diff

Compare two schemas and show migration commands:

qail diff old.qail new.qail

qail check

Validate a schema file or preview migration safety:

# Validate schema
qail check schema.qail
# ✓ Schema is valid
#   Tables: 80
#   Columns: 1110
#   Indexes: 287
#   ✓ 82 primary key(s)

# Check migration safety
qail check old.qail:new.qail
# ✓ Both schemas are valid
# Migration preview: 4 operation(s)
#   ✓ 3 safe operation(s)
#   ⚠️  1 reversible operation(s)

qail migrate up

Apply migrations:

qail migrate up old.qail:new.qail postgres://...

qail migrate down

Rollback migrations:

qail migrate down old.qail:new.qail postgres://...

qail migrate plan

Preview migration SQL without executing (dry-run):

qail migrate plan old.qail:new.qail
# 📋 Migration Plan (dry-run)
# ┌─ UP (2 operations) ─────────────────────────────────┐
# │ 1. ALTER TABLE users ADD COLUMN verified BOOLEAN
# │ 2. CREATE INDEX idx_users_email ON users (email)
# └─────────────────────────────────────────────────────┘
# ┌─ DOWN (2 operations) ───────────────────────────────┐
# │ 1. ALTER TABLE users DROP COLUMN verified
# │ 2. DROP INDEX IF EXISTS idx_users_email
# └─────────────────────────────────────────────────────┘

# Save to file
qail migrate plan old.qail:new.qail --output migration.sql

qail migrate analyze

Analyze codebase for breaking changes before migrating:

qail migrate analyze old.qail:new.qail --codebase ./src
# 🔍 Migration Impact Analyzer
# Scanning codebase...
#   Found 395 query references
#
# ⚠️  BREAKING CHANGES DETECTED
# ┌─ DROP TABLE promotions (6 references) ─────────────┐
# │ ❌ src/repository/promotion.rs:89 → INSERT INTO...
# │ ❌ src/repository/promotion.rs:264 → SELECT...
# └────────────────────────────────────────────────────┘

qail watch

Watch schema file for changes and auto-generate migrations:

qail watch schema.qail
# 👀 QAIL Schema Watch Mode
#    Watching: schema.qail
#    Press Ctrl+C to stop
# [14:32:15] ✓ Detected 2 change(s):
#        ALTER TABLE users ADD COLUMN avatar_url TEXT

# With database connection
qail watch schema.qail --url postgres://... --auto-apply

qail lint

Check schema for best practices and potential issues:

qail lint schema.qail
# 🔍 Schema Linter
# ⚠ 144 warning(s)
# ℹ 266 info(s)
#
# ⚠ users.customer_id Possible FK column without references()
#   → Consider adding '.references("table", "id")' for referential integrity
#
# ⚠ orders Missing updated_at column
#   → Add 'updated_at TIMESTAMPTZ not_null' for audit trail

# Strict mode (errors only, for CI)
qail lint schema.qail --strict

Lint Checks:

CheckLevelDescription
Missing primary key🔴 ERROREvery table needs a PK
Missing created_at/updated_at⚠️ WARNINGAudit trail columns
_id column without references()⚠️ WARNINGFK integrity
Uppercase table names⚠️ WARNINGUse snake_case
SERIAL vs UUIDℹ️ INFOConsider UUID for distributed
Nullable without defaultℹ️ INFOConsider default value

qail migrate status

View migration history for a database:

qail migrate status postgres://...
# 📋 Migration Status
#   Database: mydb
#   Migration table: _qail_migrations
#   ✓ Migration history table is ready

qail fmt

Format QAIL text:

qail fmt "get users fields *" --indent

Options

FlagDescription
-d, --dialectTarget SQL dialect (pg, mysql)
-f, --formatOutput format (sql, ast, json)
-v, --verboseVerbose output
--versionShow version
--helpShow help