AST Builder API

The recommended way to use QAIL. Build queries as typed Rust structs. No parsing. No strings.

Method Description Example
QailCmd::get() SELECT query QailCmd::get("users")
QailCmd::add() INSERT query QailCmd::add("users")
QailCmd::set() UPDATE query QailCmd::set("users")
QailCmd::del() DELETE query QailCmd::del("users")
.select_all() SELECT * .select_all()
.columns() Select specific columns .columns(["id", "email"])
.filter() WHERE condition .filter("active", Eq, true)
.where_eq() WHERE = shorthand .where_eq("id", 42)
.order_by() ORDER BY .order_by("created_at", Desc)
.limit() LIMIT .limit(10)
.offset() OFFSET .offset(20)
.left_join() LEFT JOIN .left_join("profiles", "users.id", "profiles.user_id")
.returning_all() RETURNING * .returning_all()

Installation

Rust (Recommended)

[dependencies] qail-core = "*" # AST and Builder qail-pg = "*" # PostgreSQL driver (WIP)

CLI

cargo install qail

JavaScript/TypeScript (WASM)

npm install qail-wasm

Usage

// Rust - AST Builder (recommended) use qail_core::ast::{QailCmd, Operator, SortOrder}; let cmd = QailCmd::get("users") .columns(["id", "email"]) .filter("active", Operator::Eq, true) .order_by("created_at", SortOrder::Desc) .limit(10); // Encode to PostgreSQL wire protocol bytes use qail_pg::protocol::PgEncoder; let bytes = PgEncoder::encode_simple_query(&cmd);
// JavaScript - Text syntax (CLI, playground) import { parseAndTranspile } from 'qail-wasm'; const sql = parseAndTranspile("get users fields * where active = true");

Text Syntax Reference

For CLI, LSP, and WASM playground. Parses to AST internally.

Keyword Description Example SQL Equivalent
get Select query get users fields * SELECT * FROM users
set Update query set users values ... UPDATE users SET ...
del Delete query del users where ... DELETE FROM users
add Insert query add users values ... INSERT INTO users
fields Select columns fields id, email, * SELECT id, email, *
where Filter conditions where active = true WHERE active = true
order by Sort results order by name desc ORDER BY name DESC
limit / offset Pagination limit 10 offset 20 LIMIT 10 OFFSET 20
left join Left outer join left join profiles LEFT JOIN profiles
ilike Fuzzy match where name ilike john WHERE name ILIKE '%john%'

Examples

AST Builder - Complete Flow

// Build the query let cmd = QailCmd::get("users") .columns(["id", "email", "name"]) .filter("active", Operator::Eq, true) .filter("role", Operator::In, vec!["admin", "mod"]) .order_by("created_at", SortOrder::Desc) .limit(50); // Validate against schema (optional) validator.validate_command(&cmd)?; // Encode to PostgreSQL bytes let bytes = PgEncoder::encode_simple_query(&cmd); // Send to database (qail-pg driver - WIP) driver.execute(bytes).await?;

Text Syntax - Complex Query

get users 
    inner join bookings
    fields id, email, bookings.total
    where created_at >= 2024-01-01
    and email_verified = true
    order by created_at desc
    limit 50
SELECT id, email, bookings.total FROM users INNER JOIN bookings ON ... WHERE created_at >= '2024-01-01' AND email_verified = true ORDER BY created_at DESC LIMIT 50

Insert with Returning

let cmd = QailCmd::add("users") .columns(["email", "name"]) .values(["alice@example.com", "Alice"]) .returning(["id", "created_at"]);
INSERT INTO users (email, name) VALUES ('alice@example.com', 'Alice') RETURNING id, created_at

Update with Filter

let cmd = QailCmd::set("users") .set_value("status", "active") .set_value("verified_at", "now()") .where_eq("id", 42);
UPDATE users SET status = 'active', verified_at = now() WHERE id = 42