orm

package module
v0.0.7 Latest Latest
Warning

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

Go to latest
Published: Feb 28, 2026 License: MIT Imports: 1 Imported by: 0

README

tinywasm/orm

Project Badges

Tiny ORM database adapter for WebAssembly.


What Problem This Library Solves

Modern applications often need to integrate a database before the final storage engine is known, or while keeping the project easily testable and portable across environments (backend, edge, or WebAssembly). Traditional ORMs and database libraries typically bind the application too early to a specific database driver, SQL dialect, or runtime environment.

tinywasm/orm solves this by providing a minimal, explicit, engine-agnostic ORM core that allows developers to add database capabilities to a project without committing to a specific database engine upfront.

Instead of coupling application logic directly to a database driver, the ORM separates responsibilities into clear layers:

ModelQueryCompilerPlanExecutor

This architecture allows the same application code to run with different storage engines such as SQL databases, embedded databases, or browser storage systems like IndexedDB, simply by swapping the compiler and executor.

This makes the library particularly useful for:

  • Projects where the database engine is undecided early in development.
  • Applications that must run in multiple environments (backend, WASM, edge).
  • Systems that prioritize testability and clean architecture.
  • Lightweight services that do not need a heavy ORM.

Key Advantages

  • Engine Agnostic: Application logic does not depend on a specific database engine. The storage backend can change without rewriting queries or business logic.
  • Excellent for Testing: A mock executor can be injected, allowing full testing of database logic without running a real database.
  • WASM Friendly: No reflection and no dependency on database/sql in the core. This keeps binaries small and compatible with WebAssembly environments.
  • Explicit and Predictable: The ORM avoids hidden behavior and runtime schema inspection. Queries are built explicitly and compiled deterministically.
  • Minimal and Lightweight: Designed to stay small, fast, and easy to reason about, especially compared to traditional ORMs.
  • Multi-Engine Architecture: The same ORM layer can support SQL databases, browser databases, or custom storage engines.
  • Streaming Query Results: Large result sets can be processed without allocating large slices in memory.

Trade-offs

This design intentionally avoids some features commonly found in traditional ORMs.

  • More Explicit Code: Models must define their schema manually, which adds some boilerplate but improves performance and clarity.
  • No Automatic Schema Discovery: The ORM does not inspect database schemas at runtime.
  • Less "Magic" Than Traditional ORMs: The library favors transparency and control over convenience abstractions.

When to Use This ORM

tinywasm/orm is a good fit when:

  • You want to keep your application independent from a specific database.
  • You need strong testability and clean dependency injection.
  • Your project targets WebAssembly or constrained environments.
  • You prefer explicit architecture over implicit ORM behavior.
  • You are building a framework, platform, or reusable system.

It may not be ideal if:

  • You want a fully automated ORM with migrations, schema discovery, and heavy automation.
  • You are tightly coupled to a single SQL engine and prefer driver-level APIs.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ErrEmptyTable = fmt.Err("name", "table", "empty")

ErrEmptyTable is returned when TableName() returns an empty string.

View Source
var ErrNoTxSupport = fmt.Err("transaction", "not", "supported")

ErrNoTxSupport is returned by DB.Tx() when the executor does not implement TxExecutor.

View Source
var ErrNotFound = fmt.Err("record", "not", "found")

ErrNotFound is returned when ReadOne() finds no matching row.

View Source
var ErrValidation = fmt.Err("error", "validation")

ErrValidation is returned when validate() finds a mismatch.

Functions

This section is empty.

Types

type Action

type Action int

Action represents the type of database operation.

const (
	ActionCreate Action = iota
	ActionReadOne
	ActionUpdate
	ActionDelete
	ActionReadAll
)

type Compiler added in v0.0.7

type Compiler interface {
	Compile(q Query, m Model) (Plan, error)
}

Compiler converts ORM queries into engine instructions.

type Condition

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

Condition represents a filter for a query. It is a sealed value type constructed via helper functions.

func Eq

func Eq(field string, value any) Condition

Eq creates a condition for checking equality.

func Gt

func Gt(field string, value any) Condition

Gt creates a condition for checking if a value is greater than another.

func Gte

func Gte(field string, value any) Condition

Gte creates a condition for checking if a value is greater than or equal to another.

func Like

func Like(field string, value any) Condition

Like creates a condition for checking if a value matches a pattern.

func Lt

func Lt(field string, value any) Condition

Lt creates a condition for checking if a value is less than another.

func Lte

func Lte(field string, value any) Condition

Lte creates a condition for checking if a value is less than or equal to another.

func Neq

func Neq(field string, value any) Condition

Neq creates a condition for checking inequality.

func Or

func Or(c Condition) Condition

Or creates a condition with OR logic.

func (Condition) Field

func (c Condition) Field() string

func (Condition) Logic

func (c Condition) Logic() string

func (Condition) Operator

func (c Condition) Operator() string

func (Condition) Value

func (c Condition) Value() any

type DB

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

DB represents a database connection. Consumers instantiate it via New().

func New

func New(exec Executor, compiler Compiler) *DB

New creates a new DB instance.

func (*DB) Create

func (db *DB) Create(m Model) error

Create inserts a new model into the database.

func (*DB) Delete

func (db *DB) Delete(m Model, conds ...Condition) error

Delete deletes a model from the database.

func (*DB) Query

func (db *DB) Query(m Model) *QB

Query creates a new QB instance.

func (*DB) Tx

func (db *DB) Tx(fn func(tx *DB) error) error

Tx executes a function within a transaction.

func (*DB) Update

func (db *DB) Update(m Model, conds ...Condition) error

Update updates a model in the database.

type Executor added in v0.0.7

type Executor interface {
	Exec(query string, args ...any) error
	QueryRow(query string, args ...any) Scanner
	Query(query string, args ...any) (Rows, error)
}

Executor represents the database connection abstraction. It must remain compatible with sql.DB, sql.Tx, mocks, and WASM drivers.

type Model

type Model interface {
	TableName() string
	Columns() []string
	Values() []any
	Pointers() []any
}

Model represents a database model. Consumers implement this interface.

type Order

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

Order represents a sort order for a query. It is a sealed value type constructed via QB.OrderBy().

func (Order) Column

func (o Order) Column() string

func (Order) Dir

func (o Order) Dir() string

type Plan added in v0.0.7

type Plan struct {
	Mode  Action
	Query string
	Args  []any
}

Plan describes how the Executor should run the operation.

type QB

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

QB represents a query builder. Consumers hold a *QB reference in variables for incremental building.

func (*QB) GroupBy

func (qb *QB) GroupBy(columns ...string) *QB

GroupBy adds a group by clause to the query.

func (*QB) Limit

func (qb *QB) Limit(limit int) *QB

Limit sets the limit for the query.

func (*QB) Offset

func (qb *QB) Offset(offset int) *QB

Offset sets the offset for the query.

func (*QB) OrderBy

func (qb *QB) OrderBy(column, dir string) *QB

OrderBy adds an order clause to the query.

func (*QB) ReadAll

func (qb *QB) ReadAll(new func() Model, onRow func(Model)) error

ReadAll executes the query and returns all results.

func (*QB) ReadOne

func (qb *QB) ReadOne() error

ReadOne executes the query and returns a single result.

func (*QB) Where

func (qb *QB) Where(conds ...Condition) *QB

Where adds conditions to the query.

type Query

type Query struct {
	Action     Action
	Table      string
	Columns    []string
	Values     []any
	Conditions []Condition
	OrderBy    []Order
	GroupBy    []string
	Limit      int
	Offset     int
}

Query represents a database query to be executed by an Executor. Planners read these fields to build Plans.

type Rows added in v0.0.7

type Rows interface {
	Next() bool
	Scan(dest ...any) error
	Close() error
	Err() error
}

Rows represents an iterator over query results.

type Scanner added in v0.0.7

type Scanner interface {
	Scan(dest ...any) error
}

Scanner represents a single row scanner.

type TxBoundExecutor added in v0.0.7

type TxBoundExecutor interface {
	Executor
	Commit() error
	Rollback() error
}

TxBoundExecutor represents an executor bound to a transaction.

type TxExecutor added in v0.0.7

type TxExecutor interface {
	Executor
	BeginTx() (TxBoundExecutor, error)
}

TxExecutor represents an executor that supports transactions.

Jump to

Keyboard shortcuts

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