rovadb

package module
v0.48.0-temporal-timez... Latest Latest
Warning

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

Go to latest
Published: Apr 16, 2026 License: MIT Imports: 21 Imported by: 0

README

RovaDB www.rovadb.org

A pure Go embedded SQL database for local applications.

RovaDB is a small relational database engine for Go that aims to be practical, readable, and easy to embed. It is built for single-process applications that want SQL, predictable behavior, and a Go-native implementation without CGO.

Why RovaDB

  • embedded relational database for Go
  • pure Go implementation
  • no CGO dependency
  • small, stable public API
  • readable engine internals
  • practical SQL support for local apps and tools

Good Fit For

  • local Go applications that need embedded relational storage
  • tools, utilities, and prototypes that want SQL instead of ad hoc file formats
  • developers who want a Go-native embedded database with understandable internals
  • contributors who want to work on a real database engine without a massive codebase

Not Aimed At

  • client/server deployments
  • distributed systems
  • full SQL compatibility
  • advanced query optimization workloads
  • replacing mature database servers on breadth or raw performance

Why RovaDB Instead of SQLite or Key-Value Stores?

Choose RovaDB when you want an embedded relational database that feels native in Go and you care about understandable internals, explicit scope, and a small public API.

Compared with SQLite, RovaDB is not trying to match the full breadth, ecosystem maturity, or performance profile of a long-established engine. Its appeal is different: pure Go implementation, no CGO dependency, a smaller surface area, and a codebase that is easier to study and evolve in Go-first projects.

Compared with key-value stores and simple embedded persistence libraries, RovaDB gives you a relational model, SQL queries, joins, ordering, aggregates, catalog visibility, and a more familiar mental model for structured application data.

Status: Pre-release. RovaDB already provides a practical embedded SQL baseline with a small public API, focused SQL support, explicit Go-API transaction control, a hardened physical storage model, enforced architectural boundaries, and strict typed semantics including exact-width integer behavior.

Quick Start

If you already have Go installed, you can try RovaDB without cloning the repo:

go install github.com/Khorlane/RovaDB/cmd/rovadb@latest
rovadb

Then create and open the sample database:

rovadb> sample demo.db
  created sample database demo.db
  sample tables: customers, orders

Run this query:

SELECT a.cust_nbr AS customer_number, a.name, a.city, b.order_nbr, b.item, b.total_amt
FROM customers a
INNER JOIN orders b ON a.cust_nbr = b.cust_nbr
WHERE b.total_amt > 7.0
ORDER BY a.name DESC, b.total_amt;

Or copy/paste this one-line form directly into the CLI:

SELECT a.cust_nbr AS customer_number, a.name, a.city, b.order_nbr, b.item, b.total_amt FROM customers a INNER JOIN orders b ON a.cust_nbr = b.cust_nbr WHERE b.total_amt > 7.0 ORDER BY a.name DESC, b.total_amt;

Equivalent comma-join form:

SELECT a.cust_nbr, a.name, b.order_nbr, b.total_amt FROM customers a, orders b WHERE a.cust_nbr = b.cust_nbr AND b.total_amt > 7.0 ORDER BY a.name DESC, b.total_amt;

You should see:

rovadb> SELECT a.cust_nbr AS customer_number, a.name, a.city, b.order_nbr, b.item, b.total_amt FROM customers a INNER JOIN orders b ON a.cust_nbr = b.cust_nbr WHERE b.total_amt > 7.0 ORDER BY a.name DESC, b.total_amt;
  customer_number | a.name       | a.city   | b.order_nbr | b.item   | b.total_amt
  ----------------|--------------|----------|-------------|----------|------------
  2               | Brian Lewis  | Chicago  | 3           | Stapler  | 15
  1               | Alice Carter | Boston   | 2           | Pens     | 8.25
  1               | Alice Carter | Boston   | 1           | Paper    | 12.5

If you want to embed RovaDB in a Go program instead, see examples/basic_usage/main.go.

Current State

RovaDB is in active pre-release development with a practical embedded-engine baseline already in place.

Recent completed milestones include:

  • physical storage layer and physical storage polish
  • architectural boundary hardening
  • planner/execution boundary separation and outer-seam tightening
  • public transaction API
  • narrow index-only access
  • primary and foreign key support
  • column nullability and literal defaults
  • physical integer widths
  • strict integer semantics
  • temporal core basics

The current engine baseline includes:

  • authoritative TableHeader roots with SpaceMap-owned Data page storage
  • strict open/reopen validation of physical ownership and storage invariants
  • rollback-journal-based crash-safe writes and explicit corruption detection
  • locked parser -> planner -> execution -> storage layering with one-way dependencies
  • explicit public transactions through the Go API
  • named primary and foreign keys with immediate referential integrity enforcement
  • strict value semantics for SMALLINT, INT, BIGINT, TEXT, BOOL, REAL, DATE, TIME, TIMESTAMP, and NULL
  • exact-width integer binding, write, arithmetic, storage, and scan behavior
  • canonical temporal literal parsing, strict temporal writes, persisted temporal storage/catalog metadata, temporal predicates, temporal ORDER BY, and public temporal scan mappings
  • deterministic query behavior, explicit error surfaces, and growing lifecycle coverage

Current development is focused on extending capability without weakening correctness, determinism, storage integrity, or API discipline.

Architectural Boundaries

RovaDB follows a locked layered pipeline: parser -> planner -> execution -> storage, with the root package owning only the public API surface. Each layer has strict ownership, dependencies flow one way, storage-owned value and index details stay behind explicit boundaries, and architectural guardrail tests enforce the dependency direction.

See docs/dev/ARCHITECTURAL_BOUNDARIES.md for the authoritative boundary contract.

Product Boundary

Intended Use
  • Embedded database for small applications
  • Local, single-process usage
  • Simple relational storage for embedded Go applications
  • Useful for tools, prototypes, and lightweight local persistence
Current Limits
  • No advanced query optimization
  • No full SQL compliance
Guarantees
  • Deterministic query behavior
  • Deterministic error surface with stable error messages and types
  • Crash-safe writes via the existing transaction and rollback-journal model
  • Correctness across open, close, reopen, and recovery lifecycle boundaries
  • Explicit corruption detection with no silent recovery
  • Simple, predictable execution model
Supported Features
  • CREATE TABLE
  • CREATE INDEX / CREATE UNIQUE INDEX
  • DROP INDEX
  • DROP TABLE
  • ALTER TABLE ... ADD COLUMN
  • ALTER TABLE ... ADD CONSTRAINT ... PRIMARY KEY
  • ALTER TABLE ... ADD CONSTRAINT ... FOREIGN KEY
  • ALTER TABLE ... DROP PRIMARY KEY
  • ALTER TABLE ... DROP FOREIGN KEY
  • named PRIMARY KEY constraints with explicit supporting indexes
  • named FOREIGN KEY constraints with immediate referential integrity enforcement
  • INSERT INTO ... VALUES
  • SELECT with projection expressions, WHERE, ORDER BY, joins, and the current supported aggregate set
  • UPDATE
  • DELETE
  • positional args via ? in Exec, Query, and QueryRow
  • explicit public transactions via Begin, Tx.Exec, Tx.Query, Tx.QueryRow, Commit, and Rollback
  • public catalog introspection via ListTables and GetTableSchema
  • shared product version via Version()
  • strict value support for SMALLINT, INT, BIGINT, TEXT, BOOL, REAL, DATE, TIME, TIMESTAMP, and NULL
  • temporal basics for canonical literals, strict family-matched writes/comparisons, temporal WHERE, temporal ORDER BY, and public scan targets
  • narrow index-only access for eligible plain single-table COUNT(*) and single-column indexed projection queries
Scope Discipline

The current repo baseline is the practical target for this intended use case. Future changes are expected to preserve strict contracts, data integrity, deterministic behavior, architectural boundary discipline, durability, and API stability ahead of feature expansion. New features should earn their place without weakening those constraints.

Supported SQL

Only the following SQL forms are supported today.

Statements
  • CREATE TABLE
  • CREATE INDEX ...
  • DROP INDEX <name>
  • DROP TABLE <name>
  • ALTER TABLE <table> ADD COLUMN <column-definition>
  • ALTER TABLE <table> ADD CONSTRAINT <name> PRIMARY KEY (...) USING INDEX <index>
  • ALTER TABLE <table> ADD CONSTRAINT <name> FOREIGN KEY (...) REFERENCES <parent> (...) USING INDEX <index> ON DELETE RESTRICT|CASCADE
  • ALTER TABLE <table> DROP PRIMARY KEY
  • ALTER TABLE <table> DROP FOREIGN KEY <name>
  • INSERT INTO ... VALUES (...)
  • SELECT ...
  • UPDATE ... SET ...
  • DELETE FROM ...

Parser-recognized but not executable today:

  • BEGIN
  • COMMIT
  • ROLLBACK

Explicit transactions are supported through the Go API only. SQL BEGIN / COMMIT / ROLLBACK statements are not part of the current public product surface.

Primary and foreign key support

Supported PRIMARY KEY contract:

  • keys are named only
  • at most one primary key may exist per table
  • primary keys may be single-column or composite
  • primary-key columns are implicitly NOT NULL
  • USING INDEX <name> is required
  • the supporting index must be UNIQUE and match the primary-key column list exactly
  • primary-key values cannot be modified with UPDATE
  • ALTER TABLE ... DROP PRIMARY KEY removes dependent foreign keys and keeps the underlying indexes

Supported FOREIGN KEY contract:

  • keys are named only
  • tables may define zero or more foreign keys
  • foreign keys reference the parent table primary key only
  • foreign keys may be single-column or composite
  • USING INDEX <name> is required
  • ON DELETE RESTRICT or ON DELETE CASCADE is required
  • child foreign-key columns may not be NULL
  • foreign-key columns may be updated, but the final row state must remain valid
  • the child supporting index must use the foreign-key columns as a contiguous leftmost prefix
  • ALTER TABLE ... DROP FOREIGN KEY <name> removes the constraint and keeps the supporting index

Referential-integrity behavior:

  • enforcement is immediate
  • statement execution is atomic
  • validation is against the final statement state
  • both RESTRICT and CASCADE deletes are supported
  • self-references are allowed when the cascade graph is legal
  • all-CASCADE cycles are rejected at DDL time
  • multiple cascade paths are rejected at DDL time

Destructive DDL behavior:

  • DROP PRIMARY KEY and DROP TABLE tear down dependent foreign keys instead of blocking
  • DROP INDEX is the dependency-blocking exception and fails while an index is still required by a primary key or foreign key
SELECT support
  • literal selects such as SELECT 1, SELECT 'hello', SELECT TRUE, SELECT FALSE, and arithmetic expressions with + and -
  • projection expressions, column projection, qualified column references, and AS aliases
  • ORDER BY resolution against select-item aliases at the same SELECT level
  • single-table FROM
  • two-table inner equi-joins via explicit INNER JOIN ... ON ... and comma join + WHERE
  • WHERE with NOT, precedence, and parenthesized grouping
  • comparison operators: =, !=, <>, <, <=, >, >=
  • ORDER BY with one or more items
  • scalar functions: LOWER, UPPER, LENGTH, and ABS
  • aggregates: COUNT(*), COUNT(expr), MIN, MAX, AVG, and SUM
Narrow index-only support
  • true index-only means the result is satisfied from index contents plus index-structure metadata without fetching base table rows
  • supported today only for eligible plain single-table COUNT(*)
  • supported today only for eligible plain single-table single-column direct indexed projection such as SELECT id FROM users
  • qualified single-table direct indexed projection such as SELECT users.id FROM users is also supported when eligible
  • unsupported or uncertain shapes fall back to the existing table/index/join paths
  • current fallback examples include aliased projection, ORDER BY on projection, WHERE-bearing projection, multi-column projection, non-column expressions, non-indexed projection, and joins
Not supported today
  • GROUP BY
  • HAVING
  • subqueries
  • joins over more than two tables
  • non-INNER joins
  • non-equality join predicates
  • qualified star projection such as a.* or b.*
  • mixed aggregate and non-aggregate projections
  • alias resolution in WHERE
  • SQL BEGIN
  • public COMMIT / ROLLBACK SQL
  • schema changes other than ALTER TABLE ... ADD COLUMN, ALTER TABLE ... ADD|DROP PRIMARY KEY, and ALTER TABLE ... ADD|DROP FOREIGN KEY
Public API
  • Open(path string) (*DB, error)
  • (*DB).Close() error
  • (*DB).Exec(query string, args ...any) (Result, error)
  • (*DB).Query(query string, args ...any) (*Rows, error)
  • (*DB).QueryRow(query string, args ...any) *Row
  • (*DB).Begin() (*Tx, error)
  • (*DB).ListTables() ([]TableInfo, error)
  • (*DB).GetTableSchema(table string) (TableInfo, error)
  • (*Tx).Exec(query string, args ...any) (Result, error)
  • (*Tx).Query(query string, args ...any) (*Rows, error)
  • (*Tx).QueryRow(query string, args ...any) *Row
  • (*Tx).Commit() error
  • (*Tx).Rollback() error
  • Version() string
Supported data types
  • SMALLINT
  • INT
  • BIGINT
  • TEXT
  • BOOL
  • REAL
  • DATE
  • TIME
  • TIMESTAMP
Column nullability and literal defaults
  • supported column forms are <name> <type>, <name> <type> DEFAULT <literal>, <name> <type> NOT NULL, and <name> <type> NOT NULL DEFAULT <literal>
  • DEFAULT is literal-only for this milestone and applies only when an INSERT omits the column
  • explicit NULL is rejected for NOT NULL columns on both INSERT and UPDATE
  • ALTER TABLE ... ADD COLUMN uses the same supported column forms
  • adding NOT NULL without a default is rejected for non-empty tables
  • adding a defaulted column exposes that default for existing rows and for future inserts, including after reopen

Examples:

  • CREATE TABLE users (id INT NOT NULL, name TEXT DEFAULT 'ready', active BOOL NOT NULL DEFAULT TRUE, score REAL DEFAULT 0.0)
  • INSERT INTO users (id) VALUES (1) stores name='ready', active=TRUE, and score=0.0
  • INSERT INTO users VALUES (2, 'sam', NULL, 1.25) fails because active is NOT NULL
  • ALTER TABLE users ADD COLUMN status TEXT DEFAULT 'new' exposes 'new' for existing rows and later omitted inserts
  • ALTER TABLE users ADD COLUMN active BOOL NOT NULL DEFAULT TRUE backfills existing rows logically and keeps future omitted inserts valid
BOOL semantics
  • BOOL literals are unquoted TRUE and FALSE
  • quoted 'true' and 'false' are TEXT, not BOOL
  • 1 and 0 are INT, not BOOL
  • BOOL columns accept only TRUE, FALSE, or NULL
  • no implicit type coercion
  • BOOL works in CREATE TABLE, strict INSERT / UPDATE validation, SELECT result values, and WHERE equality / inequality within the supported query subset
REAL semantics
  • REAL values are exposed to Go as float64
  • decimal literals such as 3.14 and -2.5 are REAL
  • unquoted whole numbers such as 1 remain INT
  • quoted numeric-looking values such as '3.14' remain TEXT
  • REAL columns accept only REAL or NULL
  • there is no implicit coercion between INT and REAL
  • REAL-to-REAL WHERE comparisons support =, !=, <, <=, >, and >=
  • mixed INT / REAL, TEXT / REAL, and BOOL / REAL comparisons remain strict type mismatches
Temporal semantics
  • supported temporal schema types are DATE, TIME, and TIMESTAMP
  • accepted canonical quoted payloads are 'YYYY-MM-DD' for DATE, 'HH:MM:SS' for TIME, and 'YYYY-MM-DD HH:MM:SS' for TIMESTAMP
  • quoted strings that match those canonical payloads are classified as temporal literals; other quoted strings remain TEXT
  • writes are strict by temporal family: DATE accepts only DATE, TIME accepts only TIME, and TIMESTAMP accepts only TIMESTAMP, plus NULL where allowed
  • temporal WHERE predicates support =, !=, <, <=, >, and >= when both sides are the same temporal family
  • temporal ORDER BY is supported within the current query subset
  • there is no implicit casting or implicit coercion between temporal families or between temporal and non-temporal types
  • public scan contract is DATE -> *time.Time, TIMESTAMP -> *time.Time, and TIME -> *rovadb.Time
  • not supported in this milestone: fractional seconds, alternate literal formats, temporal arithmetic, and built-in temporal functions
Text comparison semantics
  • TEXT comparisons are case-insensitive
  • comparisons are performed using lowercase normalization
  • no locale-aware or accent-aware collation is applied
  • behavior is deterministic and consistent across WHERE and ORDER BY
Indexed TEXT limit
  • indexed TEXT values are limited to <= 512 bytes
  • the limit is measured in bytes, not characters
  • the limit is enforced on INSERT, UPDATE, and CREATE INDEX / CREATE UNIQUE INDEX
  • oversized indexed TEXT values fail with:
    • execution: indexed TEXT column value exceeds 512-byte limit

Positional Arguments

The public API supports one-shot positional argument binding on:

  • Exec(query string, args ...any)
  • Query(query string, args ...any)
  • QueryRow(query string, args ...any)

Use ? placeholders only. Binding is positional, left-to-right, and the arg count must match exactly. Placeholders are allowed only in value positions, and binding happens after parse but before planning and execution.

This is not a prepared statement system. Each call parses, binds, plans, and executes once.

Supported Go argument types are:

  • int16
  • int32
  • int64
  • string
  • bool
  • float64
  • nil

Unsupported argument types fail with an error.

String arguments that exactly match the canonical temporal literal payloads bind as temporal values: YYYY-MM-DD -> DATE, HH:MM:SS -> TIME, and YYYY-MM-DD HH:MM:SS -> TIMESTAMP. Other strings bind as TEXT.

For SQL integer binding, placeholder width is exact: SMALLINT binds through int16, INT through int32, and BIGINT through int64. Go int and other integer-like Go types are rejected rather than widened or narrowed implicitly.

Catalog Introspection

RovaDB exposes a small public catalog API for listing tables and reading table schema metadata:

  • ListTables()
  • GetTableSchema(table)

ListTables() returns table names and column definitions for all tables in the open database. GetTableSchema(table) returns the same metadata for one table. Column definitions include the declared type plus persisted NOT NULL and literal DEFAULT metadata when present.

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 NOT NULL, name TEXT DEFAULT 'ready', active BOOL NOT NULL DEFAULT TRUE, score REAL DEFAULT 0.0)"); err != nil {
	log.Fatal(err)
}

tx, err := db.Begin()
if err != nil {
	log.Fatal(err)
}
if _, err := tx.Exec("INSERT INTO users VALUES (?, ?, ?, ?)", int32(1), "Alice", false, 7.5); err != nil {
	_ = tx.Rollback()
	log.Fatal(err)
}
if _, err := tx.Exec("INSERT INTO users (id) VALUES (?)", int32(2)); err != nil {
	_ = tx.Rollback()
	log.Fatal(err)
}

var activeCount int64
if err := tx.QueryRow("SELECT COUNT(*) FROM users WHERE active = ?", true).Scan(&activeCount); err != nil {
	_ = tx.Rollback()
	log.Fatal(err)
}
fmt.Println("active users in tx:", activeCount)

if err := tx.Commit(); 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()

fmt.Println(rows.Columns())
fmt.Println(rows.ColumnTypes())
for rows.Next() {
	var id int32
	var name string
	if err := rows.Scan(&id, &name); err != nil {
		log.Fatal(err)
	}
	fmt.Println(id, name)
}
if err := rows.Err(); err != nil {
	log.Fatal(err)
}

This stores Alice exactly as provided, while the second row uses the schema defaults because the INSERT omits name, active, and score.

For typed integer columns, public writes and Scan destinations must match the declared SQL width exactly: SMALLINT <-> int16, INT <-> int32, and BIGINT <-> int64. There is no generic Go int interchange for these typed integer columns.

For temporal columns, the public scan contract is DATE <-> time.Time, TIMESTAMP <-> time.Time, and TIME <-> rovadb.Time.

For query-result metadata, Rows.ColumnTypes() returns the projected result types in column order when that metadata is available, using canonical names such as INT, TEXT, DATE, TIME, and TIMESTAMP. This is useful for presentation layers that need to distinguish DATE from TIMESTAMP while both still scan through time.Time.

Untyped integer-expression results remain a narrow exception. Query shapes such as SELECT 1, SELECT 1 + 2, COUNT(*), and LENGTH(name) currently materialize as untyped integer results and scan through *int64, which is why the example above uses int64 for COUNT(*).

Explicit transactions are opt-in through the Go API. Plain DB.Exec, DB.Query, and DB.QueryRow keep their existing autocommit behavior when you do not call Begin().

See examples/basic_usage/main.go for a complete open -> begin -> commit -> close -> reopen -> query flow.

Primary/Foreign Key Example

For a compact example of the supported PK/FK surface, including named constraints, explicit supporting indexes, and ON DELETE CASCADE, see examples/primary_foreign_keys/main.go.

Development Note

This project is developed using AI-assisted tooling, with all design, architecture, and validation decisions owned and reviewed by the author.

Why RovaDB exists

RovaDB exists to provide a pure Go embedded relational database with practical SQL support.

  • embedded database
  • SQL interface
  • Go-native implementation
  • readable internals
  • extensible architecture
  • no dependency on CGO

The project 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

RovaDB is being built to:

  • feel natural to Go developers
  • embed cleanly into Go applications
  • provide a focused SQL feature set first
  • keep the codebase understandable
  • separate major engine layers cleanly
  • allow future growth toward a broader SQL engine

Design principles

1. Go-first

RovaDB should look and feel like a Go project. The code, API, and documentation should serve Go developers directly.

2. Small, but not boxed in

The first versions should stay intentionally small while preserving the seams needed for later growth.

3. Clear layers

The engine should maintain clean boundaries between parsing, planning, execution, storage, and transactions.

4. Readability over cleverness

If contributors cannot understand the code in a reasonable amount of time, the project gives up one of its main advantages.

5. Stable direction

RovaDB should grow through deliberate scope expansion, not feature sprawl.

Intended audience

RovaDB is aimed at two groups:

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.

Architectural direction

RovaDB grows around these locked major layers:

  • root API
  • parser
  • planner
  • execution
  • storage

The engine path is:

SQL -> parser -> planner -> execution -> storage

txn and bufferpool support transaction and durable-page orchestration around that path, but they do not redefine layer ownership. The root package stays thin and public-facing, storage owns durable metadata, value encoding, and page/index details behind narrow contracts, and boundary guardrails are part of the maintained engine baseline.

Long-Term Direction

RovaDB is intended to remain a real embedded relational engine with a deliberately narrow, correctness-first product boundary. The long-term ambition is to broaden capability over time while preserving its Go-first identity, readable implementation, strict semantics, and disciplined architecture.

Documentation

Current documentation in the repository includes:

  • README.md
  • docs/dev/CREATE_INDEX_design.md
  • docs/dev/known_gaps.md
  • docs/dev/RovaDB_SQL_Language_Spec.md
  • docs/dev/SCHEMA_LIFECYCLE_design.md
  • docs/dev/road_to_v1.md
  • docs/dev/workflows.md
  • examples/basic_usage/main.go

Blog

Contributing

Contributions are welcome, but they should align with RovaDB's established scope and design direction.

The project prioritizes:

  • clear issue definitions
  • straightforward build and test steps
  • readable code review
  • stable naming and layering
  • small, composable changes

A formal CONTRIBUTING.md can be added once the repository is ready for outside participation.

Name Origin

RovaDB takes its name from the “rova,” a historic fortified complex in Madagascar—built as a central, elevated stronghold. The idea reflects a database as a reliable, foundational place where data is securely held and organized.

Documentation

Overview

Package rovadb is the root API layer: it owns the public embedded API surface and contains no engine logic.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrNotImplemented marks API surface that exists before engine behavior does.
	ErrNotImplemented = errors.New("rovadb: not implemented")
	// ErrClosed reports use of a closed database handle.
	ErrClosed = errors.New("rovadb: closed")
	// ErrInvalidArgument reports invalid input provided to the API.
	ErrInvalidArgument = errors.New("rovadb: invalid argument")
	// ErrQueryRequiresSelect reports Query use with a non-SELECT statement.
	ErrQueryRequiresSelect = errors.New("rovadb: Query requires SELECT statement")
	// ErrExecDisallowsSelect reports Exec use with a SELECT statement.
	ErrExecDisallowsSelect = errors.New("rovadb: Exec disallows SELECT statement")
	// ErrScanMismatch reports that Scan destination count does not match the current row width.
	ErrScanMismatch = errors.New("rovadb: scan destination count mismatch")
	// ErrUnsupportedScanType reports unsupported or incompatible Scan destination/value types.
	ErrUnsupportedScanType = errors.New("rovadb: unsupported scan type")
	// ErrScanBeforeNext reports Scan without a current row selected by Next.
	ErrScanBeforeNext = errors.New("rovadb: Scan called before Next")
	// ErrRowsClosed reports Scan on a closed Rows value.
	ErrRowsClosed = errors.New("rovadb: rows closed")
	// ErrNoRows reports that QueryRow.Scan found no rows.
	ErrNoRows = errors.New("rovadb: no rows")
	// ErrMultipleRows reports that QueryRow.Scan found more than one row.
	ErrMultipleRows = errors.New("rovadb: multiple rows")
	// ErrTxNotActive reports use of a finished explicit transaction handle.
	ErrTxNotActive = errors.New("rovadb: transaction is not active")
)
View Source
var (
	ErrTxnAlreadyActive         = errors.New("rovadb: transaction already active")
	ErrTxnCommitWithoutActive   = errors.New("rovadb: commit requires active transaction")
	ErrTxnRollbackWithoutActive = errors.New("rovadb: rollback requires active transaction")
	ErrTxnInvariantViolation    = errors.New("rovadb: transaction invariant violation")
)

Functions

func Version

func Version() string

Version reports the current RovaDB product version.

Types

type ColumnInfo

type ColumnInfo struct {
	Name         string
	Type         string
	NotNull      bool
	HasDefault   bool
	DefaultValue any
}

ColumnInfo describes one column in the public catalog API.

type DB

type DB struct {
	// contains filtered or unexported fields
}

DB is the top-level handle for a RovaDB database. Mutating statements execute under an internal autocommit discipline.

func Open

func Open(path string) (*DB, error)

Open returns a database handle for the given path.

func OpenWithOptions

func OpenWithOptions(path string, opts OpenOptions) (*DB, error)

OpenWithOptions returns a database handle for the given path and validates any explicit open-time configuration that is available in this slice.

func (*DB) Begin

func (db *DB) Begin() (*Tx, error)

Begin starts an explicit transaction.

Explicit transaction execution remains in-memory for now. Existing DB-level autocommit behavior remains unchanged until later slices wire commit and rollback through durable closeout semantics.

func (*DB) CheckEngineConsistency

func (db *DB) CheckEngineConsistency() (EngineCheckResult, error)

CheckEngineConsistency runs a small read-only physical/control-plane check.

func (*DB) Close

func (db *DB) Close() error

Close releases database resources.

func (*DB) EngineReport

func (db *DB) EngineReport() (string, error)

EngineReport returns the formatted aggregate engine snapshot.

func (*DB) EngineSnapshot

func (db *DB) EngineSnapshot() (EngineSnapshot, error)

EngineSnapshot returns one deterministic aggregate diagnostic snapshot.

func (*DB) EngineStatus

func (db *DB) EngineStatus() (EngineStatus, error)

EngineStatus returns a stable in-memory status snapshot for diagnostics.

func (*DB) Exec

func (db *DB) Exec(query string, args ...any) (Result, error)

Exec executes a non-SELECT statement and returns a write result.

func (*DB) ExplainQueryPath

func (db *DB) ExplainQueryPath(sql string, args ...any) (QueryExecutionTrace, error)

ExplainQueryPath reports the high-level planned execution shape for a query.

func (*DB) GetTableSchema

func (db *DB) GetTableSchema(table string) (TableInfo, error)

GetTableSchema returns catalog metadata for one table in the open database.

func (*DB) ListTables

func (db *DB) ListTables() ([]TableInfo, error)

ListTables returns catalog metadata for all tables in the open database.

func (*DB) PageUsage

func (db *DB) PageUsage() (EnginePageUsage, error)

PageUsage returns a compact validated physical page breakdown.

func (*DB) Query

func (db *DB) Query(query string, args ...any) (*Rows, error)

Query executes a SELECT statement and returns a fully materialized row set.

func (*DB) QueryRow

func (db *DB) QueryRow(query string, args ...any) *Row

QueryRow executes Query and wraps the resulting row set for deferred handling.

func (*DB) SchemaDigest

func (db *DB) SchemaDigest() (string, error)

SchemaDigest returns a deterministic digest of the current logical schema.

func (*DB) SchemaDigestFromSystemCatalog

func (db *DB) SchemaDigestFromSystemCatalog() (string, error)

SchemaDigestFromSystemCatalog returns the logical schema digest from __sys_* rows.

func (*DB) SchemaInventory

func (db *DB) SchemaInventory() (EngineSchemaInventory, error)

SchemaInventory returns a compact deterministic inventory of user schema objects.

func (*DB) VerifySystemCatalogDigest

func (db *DB) VerifySystemCatalogDigest() error

VerifySystemCatalogDigest verifies that in-memory and SQL-visible schema digests match.

type DBError

type DBError = dberr.DBError

type EngineCheckResult

type EngineCheckResult struct {
	OK                   bool
	CheckedTableRoots    int
	CheckedTableHeaders  int
	CheckedIndexRoots    int
	CheckedSpaceMapPages int
	CheckedDataPages     int
	FreeListHead         uint32
}

EngineCheckResult summarizes a small read-only consistency check.

type EngineIndexInfo

type EngineIndexInfo struct {
	IndexID    uint32
	TableName  string
	IndexName  string
	RootPageID uint32
	IsUnique   bool
}

EngineIndexInfo is a compact logical index inventory entry.

type EnginePageUsage

type EnginePageUsage struct {
	TotalPages         int
	HeaderPages        int
	SpaceMapPages      int
	TablePages         int
	IndexLeafPages     int
	IndexInternalPages int
	FreePages          int
	DirectoryPages     int
}

EnginePageUsage summarizes physical page usage by validated page type.

type EngineSchemaInventory

type EngineSchemaInventory struct {
	Tables  []EngineTableInfo
	Indexes []EngineIndexInfo
}

EngineSchemaInventory is a compact logical object inventory.

type EngineSnapshot

type EngineSnapshot struct {
	Status    EngineStatus
	Check     EngineCheckResult
	PageUsage EnginePageUsage
	Inventory EngineSchemaInventory
}

EngineSnapshot aggregates the existing engine diagnostic helpers.

func (EngineSnapshot) String

func (s EngineSnapshot) String() string

String formats the snapshot into a compact deterministic text block.

type EngineStatus

type EngineStatus struct {
	DBFormatVersion         uint32
	WALVersion              uint32
	LastCheckpointLSN       uint64
	LastCheckpointPageCount uint32
	FreeListHead            uint32
	TableCount              int
	IndexCount              int
}

EngineStatus is a cheap diagnostic snapshot of engine control-plane state.

type EngineTableInfo

type EngineTableInfo struct {
	TableID                 uint32
	TableName               string
	RootPageID              uint32
	TableHeaderPageID       uint32
	FirstSpaceMapPageID     uint32
	OwnedSpaceMapPages      uint32
	EnumeratedSpaceMapPages uint32
	OwnedDataPages          uint32
	EnumeratedDataPages     uint32
	PhysicalMetaPresent     bool
	PhysicalMetaValid       bool
	PhysicalInventoryMatch  bool
	IndexCount              int
}

EngineTableInfo is a compact logical table inventory entry.

type ErrorKind

type ErrorKind = dberr.ErrorKind
const (
	ErrParse   ErrorKind = dberr.ErrParse
	ErrPlan    ErrorKind = dberr.ErrPlan
	ErrExec    ErrorKind = dberr.ErrExec
	ErrStorage ErrorKind = dberr.ErrStorage
)

type OpenOptions

type OpenOptions struct {
	DefaultTimezone string
}

OpenOptions configures database open behavior.

type QueryExecutionTrace

type QueryExecutionTrace struct {
	ScanType  string
	TableName string
	IndexName string
	UsesBTree bool
}

QueryExecutionTrace is a compact read-only summary of planned query shape.

type Result

type Result struct {
	// contains filtered or unexported fields
}

Result represents the outcome of a write operation.

func (Result) RowsAffected

func (r Result) RowsAffected() int

RowsAffected reports the number of rows changed by a write operation.

type Row

type Row struct {
	// contains filtered or unexported fields
}

Row is a thin QueryRow wrapper over Rows.

func (*Row) Scan

func (r *Row) Scan(dest ...any) error

Scan reads exactly one row from the wrapped Rows result.

type Rows

type Rows struct {
	// contains filtered or unexported fields
}

Rows represents a fully materialized query result.

func (*Rows) Close

func (r *Rows) Close() error

Close marks the row set closed. Rows are fully in memory, so this is lifecycle hygiene only.

func (*Rows) ColumnTypes

func (r *Rows) ColumnTypes() []string

ColumnTypes reports the projected result types in query order, when available, using canonical engine type names such as INT, TEXT, DATE, TIME, and TIMESTAMP.

func (*Rows) Columns

func (r *Rows) Columns() []string

Columns reports the projected column names in query order.

func (*Rows) Err

func (r *Rows) Err() error

Err reports any deferred query error associated with the row set.

func (*Rows) Next

func (r *Rows) Next() bool

Next advances to the next row in the fully materialized result set.

func (*Rows) Scan

func (r *Rows) Scan(dest ...any) error

Scan copies the current row into destination pointers using strict positional matching.

type TableInfo

type TableInfo struct {
	Name    string
	Columns []ColumnInfo
}

TableInfo describes one table in the public catalog API.

type Time

type Time struct {
	// contains filtered or unexported fields
}

Time is the public SQL TIME scan value. It has no date or timezone component and is stored as seconds since midnight.

func NewTime

func NewTime(hour, minute, second int) (Time, error)

NewTime builds a validated SQL TIME value from clock components.

func (Time) Hour

func (t Time) Hour() int

func (Time) Minute

func (t Time) Minute() int

func (Time) Second

func (t Time) Second() int

func (Time) String

func (t Time) String() string

type Tx

type Tx struct {
	// contains filtered or unexported fields
}

Tx is the public transaction handle reserved for explicit transaction support.

func (*Tx) Commit

func (tx *Tx) Commit() error

Commit finalizes an explicit transaction and installs its logical state.

func (*Tx) Exec

func (tx *Tx) Exec(query string, args ...any) (Result, error)

Exec executes a non-SELECT statement within the explicit transaction snapshot.

func (*Tx) Query

func (tx *Tx) Query(query string, args ...any) (*Rows, error)

Query executes a SELECT statement within the explicit transaction snapshot.

func (*Tx) QueryRow

func (tx *Tx) QueryRow(query string, args ...any) *Row

QueryRow executes Query within the explicit transaction snapshot and wraps the resulting row set for deferred handling.

func (*Tx) Rollback

func (tx *Tx) Rollback() error

Rollback abandons an explicit transaction and discards its logical state.

Directories

Path Synopsis
cmd
rovadb command
snapshot command
examples
basic_usage command
internal
bufferpool
Package bufferpool owns the in-memory committed/private page mediation layer used between runtime orchestration and durable storage access.
Package bufferpool owns the in-memory committed/private page mediation layer used between runtime orchestration and durable storage access.
executor
Package executor is the execution layer: it runs plans and coordinates row flow using storage via narrow interfaces only.
Package executor is the execution layer: it runs plans and coordinates row flow using storage via narrow interfaces only.
parser
Package parser is the parser layer: it owns SQL syntax only and has no execution or storage knowledge.
Package parser is the parser layer: it owns SQL syntax only and has no execution or storage knowledge.
planner
Package planner is the planner layer: it builds execution plans from parsed structures and has no storage or page awareness.
Package planner is the planner layer: it builds execution plans from parsed structures and has no storage or page awareness.
storage
Package storage is the storage layer: it owns pages, WAL, journals, and physical layout with no SQL or plan knowledge.
Package storage is the storage layer: it owns pages, WAL, journals, and physical layout with no SQL or plan knowledge.
txn
Package txn owns transaction state transitions and durability-oriented boundary bookkeeping.
Package txn owns transaction state transitions and durability-oriented boundary bookkeeping.

Jump to

Keyboard shortcuts

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