RovaDB

A small, idiomatic embedded SQL database for Go.

Status: Pre-release — v0.10.x is the current practical baseline

Overview

RovaDB is a Go-first embedded relational database engine built for clarity, portability, and long-term extensibility. It is intended to feel natural to Go developers, stay understandable to contributors, and grow without boxing itself into a dead-end architecture.

Intended Use

  • Embedded database for small applications
  • Local, single-process usage
  • Relational storage for embedded Go applications
  • Useful for tools, prototypes, and lightweight persistence

Current Limits

  • No advanced query optimization
  • No full SQL compliance
  • No multi-table querying
  • Focused scope by design

Guarantees

  • Deterministic query behavior
  • Stable error surface
  • Crash-safe writes
  • Explicit corruption detection

Supported Features

Supported SQL

Statements

  • CREATE TABLE
  • ALTER TABLE <table> ADD COLUMN <column> <type>
  • INSERT INTO ... VALUES (...)
  • SELECT ...
  • UPDATE ... SET ...
  • DELETE FROM ...

SELECT Support

  • Literal selects such as SELECT 1 and SELECT TRUE
  • Column projection
  • Single-table FROM
  • Flat left-to-right AND / OR evaluation
  • Comparison operators = != < <= > >=
  • ORDER BY and COUNT(*)

Not Supported Today

  • JOIN, GROUP BY, HAVING
  • Subqueries
  • Multi-table queries
  • Aggregate forms other than COUNT(*)
  • Public CREATE INDEX SQL

Schema Types

INT, TEXT, BOOL, and REAL.

Positional Arguments

The public API supports one-shot positional argument binding on Exec(query string, args ...any), Query(query string, args ...any), and QueryRow(query string, args ...any). Use ? placeholders only. Binding is positional, left-to-right, and the argument count must match exactly.

Canonical Example

db, err := rovadb.Open("app.db")
if err != nil {
    log.Fatal(err)
}
defer db.Close()

if _, err := db.Exec("CREATE TABLE users (id INT, name TEXT, active BOOL)"); err != nil {
    log.Fatal(err)
}

if _, err := db.Exec("INSERT INTO users VALUES (?, ?, ?)", 1, "Alice", true); err != nil {
    log.Fatal(err)
}

rows, err := db.Query("SELECT id, name FROM users WHERE active = ? ORDER BY id", true)
if err != nil {
    log.Fatal(err)
}
defer rows.Close()

The repository includes a fuller example that covers open, write, close, reopen, and query flow.

Why RovaDB Exists

RovaDB exists to provide a pure Go embedded relational database with practical SQL support. It is not trying to outcompete mature databases on breadth or raw performance. The goal is to offer a practical embedded SQL engine for Go that is straightforward to understand, realistic to adopt, and structured to grow carefully over time.

Project Goals

Architectural Direction

RovaDB grows around these major layers:

The intended execution path is:

SQL -> AST -> Bound AST -> Logical Plan -> Physical Plan -> Executor

Even in a deliberately small engine, those boundaries matter. They reduce coupling and make it possible to add features later without tearing the engine apart.

Audience

Adopters

Go developers who want an embedded SQL database with a straightforward mental model and a clean integration story.

Contributors

Engineers who want to work on a real database engine in Go without needing to wade into an enormous, opaque codebase.