Archibald ☁️
A type-safe, async SQL query builder for Rust, inspired by knex.js.
Named after Archibald Query, the inventor of fluff, because your database deserves queries with character.
✨ Features
- 🔗 Fluent API: Clean, chainable query builder inspired by knex.js
- ⚡ Async-first: Built for
tokiowith async/await throughout - 🏦 Transactions: Full transaction support with savepoints and isolation levels
- 📊 Rich Queries: JOINs, aggregations, GROUP BY, HAVING, ORDER BY, DISTINCT
- 🔍 Subqueries: IN, NOT IN, EXISTS, NOT EXISTS, and SELECT subqueries
- 🎯 Parameter Binding: Automatic SQL injection prevention
- 🗄️ Multi-Database: PostgreSQL support (MySQL, SQLite planned)
🛡️ Compile-Time Safety for Dangerous Operations
Archibald is strongly opinionated about naked updates and deletes. UPDATE and DELETE operations require WHERE clauses at compile time:
// ❌ Won't compile - missing WHERE clause
update.set.execute.await?; // Compile error!
// ❌ Won't compile - missing WHERE clause
delete.execute.await?; // Compile error!
// ✅ Safe - both SET and WHERE required
update
.set
.where_
.execute.await?; // ✅ Compiles!
// ✅ Explicit mass updates allowed - if you really mean it
update
.set
.where_ // Explicit "update everything" signal
.execute.await?;
Why this matters: Many SQL data disasters come from missing WHERE clauses. Archibald makes it impossible to forget them.
🚀 Quick Start
Add to your Cargo.toml:
# For PostgreSQL
[]
= { = "0.1", = ["postgres"] }
= { = "0.7", = ["runtime-tokio", "postgres"] }
= { = "1.0", = ["macros", "rt-multi-thread"] }
= { = "1.0", = ["derive"] }
# For SQLite
[]
= { = "0.1", = ["sqlite"] }
= { = "0.7", = ["runtime-tokio", "sqlite"] }
= { = "1.0", = ["macros", "rt-multi-thread"] }
= { = "1.0", = ["derive"] }
📖 Basic Usage
use ;
use PostgresPool;
use ;
async
SQLite Usage
use ;
use SqlitePool;
use ;
async
🔍 Query Examples
SELECT with WHERE conditions
let adults = from
.select
.where_ // age >= 18
.and_where // status = 'active' (defaults to EQ)
.and_where // name LIKE '%john%'
.fetch_all
.await?;
JOINs and aggregations
let user_stats = from
.select
.inner_join
.where_
.group_by
.having
.order_by
.fetch_all
.await?;
Subqueries
// WHERE IN subquery
let active_commenters = from
.select
.where_in
.fetch_all
.await?;
// EXISTS subquery
let users_with_orders = from
.select
.where_exists
.fetch_all
.await?;
INSERT
use HashMap;
let mut user_data = new;
user_data.insert;
user_data.insert;
user_data.insert;
let affected = insert
.values
.execute
.await?;
println!;
UPDATE
let mut updates = new;
updates.insert;
updates.insert;
let affected = update
.set
.where_
.and_where
.execute
.await?;
DELETE
let affected = delete
.where_
.or_where
.execute
.await?;
🏦 Transactions
Archibald provides full transaction support with automatic commit/rollback:
use transaction;
// Simple transaction with automatic commit/rollback
let result = transaction.await?;
println!;
Manual transaction control
let mut txn = pool.begin_transaction.await?;
// Use savepoints for nested transaction logic
txn.savepoint.await?;
match risky_operation.await
Transaction isolation levels
use IsolationLevel;
let txn = pool.begin_transaction_with_isolation.await?;
// ... use transaction
txn.commit.await?;
🔧 Advanced Features
Custom operators for database-specific features
// PostgreSQL full-text search
let documents = from
.select
.where_
.fetch_all
.await?;
// PostGIS distance queries
let nearby = from
.select
.where_
.limit
.fetch_all
.await?;
Deferred validation
// Build queries without Result handling
let query = from
.where_ // Stored, not validated yet
.and_where;
// Validation happens at SQL generation
match query.to_sql
🛡️ Parameter Binding & Safety
Archibald provides safety through:
- Automatic parameter binding - All values are parameterized
- Compile Time Where clauses - UPDATE / DELETE statements require where clauses at compile time
- Validated SQL generation - Invalid queries fail at runtime, not in database
// ✅ Safe - parameters are automatically bound
let users = from
.where_ // Automatically parameterized as $1
.and_where // Automatically parameterized as $2
.fetch_all
.await?;
// ✅ Safe - generates: SELECT * FROM users WHERE name = $1 AND age > $2
// Parameters: ["some_user_input", 18]
🗄️ Database Support
| Database | Status | Features |
|---|---|---|
| PostgreSQL | ✅ Full | All features, parameter binding, transactions |
| SQLite | ✅ Full | All features, JSON as TEXT, limited isolation levels |
| MySQL | 🔄 Planned | Coming soon |
📚 Documentation
- API Documentation
- Examples
- Migration from knex.js (coming soon)
🚧 Roadmap
- Core query builder (SELECT, INSERT, UPDATE, DELETE)
- JOINs, subqueries, aggregations
- SQL parameter binding & injection prevention
- Transaction support with savepoints
- Deferred validation architecture
- SQLite support
- Schema builder (CREATE TABLE, ALTER TABLE, etc.)
- Migration system
- MySQL support
- Compile-time schema validation
- Query optimization and caching
📄 License
Licensed under the LICENSE-MIT or http://opensource.org/licenses/MIT