fadodb

module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 6, 2026 License: MIT

README

FadoDB

ci Go Reference Go Report Card

An embeddable active document database, written in Go, MIT licensed.

Status: Phase 1, the formula engine, is done and released as v0.1.0. fadodb formula eval evaluates a formula on the Go VM and shows the SQL the engine generates for SQLite and DuckDB. Documents, storage and the server come in later phases. See ROADMAP.md.

What it will be

A document class declares typed variables, Excel-like formulas, a statechart, and rules that fire actions when the state changes. FadoDB keeps an append-only event log with a snapshot on every transition, evaluates formulas on the server and in the browser from one compiled bytecode, exposes every document class as a queryable SQL table, and enforces user and group access rules that are themselves formulas. Analytics and process mining are SQL over the event log.

A class is one JSON document:

{
  "name": "Invoice",
  "title": "\"Invoice for \" & customer",
  "variables": {
    "customer": {"type": "text", "required": true},
    "due":      {"type": "date", "default": "ADDDAYS(TODAY(), 30)"},
    "discount": {"type": "number", "default": "0"},
    "lines":    {"type": "rows", "schema": {"sku": "text", "qty": "number", "price": "number"}},
    "subtotal": {"formula": "SUM(lines.qty * lines.price)"},
    "total":    {"formula": "ROUND(subtotal * (1 - discount), 2)"}
  },
  "states": {"initial": "draft", "list": ["draft", "submitted", "approved", "paid"]},
  "transitions": [
    {"name": "submit",  "from": "draft",     "to": "submitted", "guard": "total > 0"},
    {"name": "approve", "from": "submitted", "to": "approved",  "guard": "INGROUP(\"finance\")"},
    {"name": "pay",     "from": "approved",  "to": "paid"}
  ],
  "rules": [
    {"on": "enter", "state": "paid",
     "do": [{"action": "create", "class": "Receipt", "values": {"invoice": "ID()", "amount": "total"}}]}
  ],
  "access": {"read": "INGROUP(\"finance\") OR customer = USER().name"}
}

Planned Go API, not implemented:

db, _ := fado.Open("app.fado", fado.Options{})
db.DefineClass(ctx, invoiceJSON)
id, _ := db.Create(ctx, "Invoice", fado.Values{"customer": "ACME"}, fado.As(user))
db.Transition(ctx, "Invoice", id, "submit", fado.As(user))
rows, _ := db.Query(ctx, `SELECT id, total FROM Invoice WHERE state = 'submitted'`, fado.As(user))

Try the formula engine

$ fadodb formula eval -var qty:number=3 -var price:number=9.99 'ROUND(qty * price * (1 - 10%), 2)'
26.97
$ fadodb formula eval -var name:text=invoice 'UPPER(LEFT(name, 3)) & "-" & TEXT(42)'
"INV-42"
$ fadodb formula eval -sql duckdb -var due:date 'DAYS(due, TODAY())'
value  (floor(CAST("due" AS DOUBLE) / CAST(86400 AS DOUBLE)) - floor((floor(CAST($now AS DOUBLE) / CAST(86400 AS DOUBLE)) * CAST(86400 AS DOUBLE)) / CAST(86400 AS DOUBLE)))
error  NULL
params now

The same formula gives the same result on the VM, on SQLite and on DuckDB: the conformance suite under conformance/ is the specification, and the property tests generate formulas to check that the three agree. The semantics are in ADR-0019, the size limits in ADR-0021, and the numbers in docs/perf/.

Design principles

  • Fast by construction. Every feature has a performance budget, and CI fails on benchmark regressions.
  • Small. Pure Go core on the standard library plus modernc.org/sqlite. No cgo in the core. DuckDB analytics and Postgres are separate modules.
  • Deterministic. Same class, same values, same user: same result on the server, in SQL, and in the browser.
  • Protocol first. One JSON command set over HTTP, WebSocket, a C ABI and the Go API, so any frontend or language can attach.
  • Honest status. Docs describe what works today.

The reasoning is in docs/architecture.md and the architecture decision records.

Build

Go 1.26 or newer.

make tools    # staticcheck, govulncheck, benchstat
make build    # bin/fadodb
make gates    # what CI runs

Layout

cmd/fadodb/        command-line tool and server entry point
fado/              public Go API (planned)
internal/formula/  lexer, parser, binder, bytecode, VM, SQL generator
internal/model/    document classes, typed variables, defaults, validation, migrations
internal/store/    SQLite store, event log, outbox
internal/state/    statechart engine
internal/rules/    event-condition-action rules and built-in actions
internal/auth/     users, groups, access rules as predicates
internal/query/    filter DSL and read-only SQL
internal/server/   HTTP and WebSocket
docs/              architecture, ADRs, dependency budget, benchmarks
scripts/           the gates CI runs

Contributing

See CONTRIBUTING.md. Design review and conformance cases are the most useful contributions at this stage.

License

MIT, see LICENSE.

Directories

Path Synopsis
cmd
fadodb command
Command fadodb is the FadoDB command-line tool and, later, its server.
Command fadodb is the FadoDB command-line tool and, later, its server.
Package fado is the public Go API for embedding FadoDB.
Package fado is the public Go API for embedding FadoDB.
internal
auth
Package auth holds users, groups, API keys and sessions, and compiles access rules into SQL predicates.
Package auth holds users, groups, API keys and sessions, and compiles access rules into SQL predicates.
formula
Package formula holds the formula language: lexer, parser, function catalog, binder, bytecode, the Go virtual machine and the SQL generator with its SQLite dialect; the DuckDB dialect follows as Phase 1 continues.
Package formula holds the formula language: lexer, parser, function catalog, binder, bytecode, the Go virtual machine and the SQL generator with its SQLite dialect; the DuckDB dialect follows as Phase 1 continues.
formula/fuzz
Package fuzz generates random, well-typed formulas with inputs and runs each one on the Go VM and on a SQL dialect, reporting any divergence.
Package fuzz generates random, well-typed formulas with inputs and runs each one on the Go VM and on a SQL dialect, reporting any divergence.
formula/sqlitefn
Package sqlitefn registers the formula engine's Go functions into the pure-Go SQLite driver, so that the SQLite dialect of the SQL generator agrees with the Go VM by construction (ADR-0019).
Package sqlitefn registers the formula engine's Go functions into the pure-Go SQLite driver, so that the SQLite dialect of the SQL generator agrees with the Go VM by construction (ADR-0019).
model
Package model defines document classes: typed named values, formulas, states, transitions, rules and access rules, with validation and versioning.
Package model defines document classes: typed named values, formulas, states, transitions, rules and access rules, with validation and versioning.
query
Package query implements the JSON filter DSL and the read-only SQL endpoint with predicate injection.
Package query implements the JSON filter DSL and the read-only SQL endpoint with predicate injection.
rules
Package rules evaluates event-condition-action rules and runs built-in actions, synchronously inside the transaction or through the outbox.
Package rules evaluates event-condition-action rules and runs built-in actions, synchronously inside the transaction or through the outbox.
server
Package server exposes the JSON command set over HTTP and WebSocket.
Package server exposes the JSON command set over HTTP and WebSocket.
state
Package state is the statechart engine: guards, entry and exit effects, eventless transitions and snapshots.
Package state is the statechart engine: guards, entry and exit effects, eventless transitions and snapshots.
store
Package store is the SQLite storage layer: one table per document class, the append-only event log, the action outbox and schema migrations.
Package store is the SQLite storage layer: one table per document class, the append-only event log, the action outbox and schema migrations.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL