Database
Basil ships with an in-process SQLite database โ no separate server to run. Configure a path, and every handler can query it as @DB.
database:
path: ./db/data.db
let users = @DB <=??=> "SELECT * FROM users ORDER BY name"
<ul>
for (user in users) {
<li>user.name</li>
}
</ul>
@DB is a managed connection: Basil opens it (WAL mode, sensible timeouts), shares it across handlers, and handlers cannot close it.
Query Operators
The database operators visually distinguish reads from writes and one row from many โ see the Parsley database docs for the full set:
let user = @DB <=?=> "SELECT * FROM users WHERE id = ?" <- [42] // one row (or null)
let users = @DB <=??=> "SELECT * FROM users" // all rows (table)
@DB <=!=> "INSERT INTO users (name) VALUES (?)" <- ["Alice"] // execute
Prefer the declarative Query DSL for schema-bound tables:
@schema User {
id: int
name: string
status: string
}
let Users = @DB.bind(User, "users")
let active = @query(Users | status == "active" ??-> name, email)
The Database Inspector
In dev mode, Basil serves a web-based database inspector at /__/db โ browse tables, run queries, and download or upload CSVs while you develop.
Other Databases
@DB is the configured SQLite database, but handlers can open connections to anything:
let pg = @postgres("postgres://user:pass@host:5432/dbname")
let my = @mysql("user:pass@tcp(host:3306)/dbname")
let mem = @sqlite(":memory:")
See Also
- Parsley: Database โ operators, transactions, SQL tag
- Parsley: Query DSL โ
@query,@insert,@update,@delete - Basil Reference ยง1โ2 โ connection literals and operations in full