The Struggle: "Polyglot Hell"
We are polyglot developers. On Monday, we write Rust. On Tuesday, Go. On Wednesday, we maintain a legacy PHP system.
Every time we switch languages, we have to switch our paradigms:
- In Rust, we choose between Diesel's strict compile-time types or SQLx's raw flexibility.
- In Go, we balance GORM's convenience with the performance of raw
database/sql. - In Node.js, we rely on Prisma for safety but pay the cost of heavy binary sidecars.
- In Python, we leverage Django's speed of development but hit performance walls at scale.
- In PHP, we love Eloquent's expressiveness but sometimes need lighter, faster query options.
The problem isn't the data. The problem is the string layer. Every ORM generates SQL strings. Every driver parses them again. Why not skip strings entirely?
The Origin: "I Don't Want You to Suffer"
"I originally built QAIL for internal use to solve my own polyglot headaches. But I realized that keeping it private meant letting other engineers suffer through the same 'Database Dilemma'. I decided to open-source it so we can all skip the string layer."
The Realization: "SQL is Assembly"
We realized something profound: SQL is not source code. SQL is Assembly.
SQL is verbose, powerful, and dangerous. It is the low-level instruction set of the database engine.
- Raw SQL offers ultimate control, but maintaining raw strings across a large codebase requires immense discipline.
- ORMs provide fantastic productivity, but the abstraction sometimes comes at the cost of fine-grained performance control.
We didn't need a compromise. We needed a Universal AST.
The Savior: QAIL
QAIL is the "Universal AST for Databases". It is not a text syntax that compiles to SQL—it is a native data structure that encodes directly to database wire protocols.
It separates the Code (your query AST) from the Data (your parameters). It creates a unified structure that works the same way in Rust, Go, Node, and PHP.
QailCmd::get("users")
.columns(["id", "email"])
.filter("active", Eq, true)
.limit(10)
SELECT id, email FROM users WHERE active = true LIMIT 10
Now, your team builds with one AST. The Rust dev, the Go dev, and the Frontend dev all use the same data structure.
"Safety shouldn't require a prison of boilerplate. We moved validation from the 'String' layer to the 'AST' layer. Code is data. Data is typed. Injection is structurally impossible."
By preventing SQL injection at the AST level, QAIL ensures your queries are safe before they even reach the database. Unlike ORMs that generate strings at runtime, QAIL encodes directly to wire protocol bytes—no string layer at all.
The Architecture: Native Power
QAIL is written in Pure Rust. It exposes:
- A C-API for Go, Python, and Java (via FFI).
- A WASM Module for Node.js and Browsers.
- A Native Crate for Rust users.
It runs in-process. It has zero network overhead. It turns your query generation into a simple CPU function call.
The AST Builder API
We designed the builder API for Type Safety and Clarity. Every method is purposeful. No strings to parse.
| Method | Purpose | Example |
|---|---|---|
QailCmd::get() |
SELECT query | QailCmd::get("users") |
.columns() |
Select specific columns | .columns(["id", "email"]) |
.filter() |
WHERE condition | .filter("active", Eq, true) |
.order_by() |
Sort results | .order_by("created_at", Desc) |
.limit() |
Pagination | .limit(10) |
.left_join() |
Join tables | .left_join("profiles", "users.id", "profiles.user_id") |