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