Skip to content

tinywasm/orm

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

339 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

tinywasm/orm

Ultra-lightweight, strongly-typed ORM engineered for WebAssembly and backend environments.

Features

  • Declarative Source of Truth: Hand-written model.Definition literals as the source for code generation.
  • Zero Reflection: Interface-driven schema via github.com/tinywasm/model with generated code.
  • Isomorphic: Same generated code works in Go (backend) and WASM (frontend).
  • 0-alloc Codec: Symmetric, reflection-free serialization/deserialization methods generated for every model.
  • Query Builder: Reflection-free, type-safe query building.
  • Backend-Agnostic: orm.DB wraps a storage.Conn — no storage contract is defined here, so any backend implementing tinywasm/storage (Postgres, SQLite, in-memory, IndexedDB, ...) works unchanged.

Ecosystem

This repository is the ergonomic layer only — the equivalent of database/sql. It defines no storage contract of its own. Other parts of the ecosystem:

Component Repository Role
storage tinywasm/storage Storage port (Executor/Compiler/Query/Condition/Plan, mock, mem) — the equivalent of database/sql/driver. A backend implements storage.Conn; orm.New(conn) takes one.
ormc tinywasm/ormc Build-time code generator.
ddlc tinywasm/ddlc SQL Schema (DDL) exporter and utilities.
sqlmcp tinywasm/sqlmcp MCP tool provider for LLM interaction.

Installation

go get github.com/tinywasm/orm

To install the code generator:

go install github.com/tinywasm/ormc/cmd/ormc@latest

Declarative Workflow

In this ORM, you write the typed definition of your model, and ormc generates the concrete struct and the rest of the code. This ensures your schema is a compile-time checked symbol, eliminating errors from fragile string tags.

1. Define your models

Create a model.go or models.go file. Define your models as model.Definition variables ending in Model.

package user

import (
    "github.com/tinywasm/model"
)

var UserModel = model.Definition{
    Name: "user",
    Fields: model.Fields{
        {Name: "id",    Type: model.Int(),  DB: &model.FieldDB{PK: true, AutoInc: true}},
        {Name: "name",  Type: model.Text(), NotNull: true, Permitted: model.Permitted{Minimum: 2}},
        {Name: "email", Type: model.Text(), NotNull: true, DB: &model.FieldDB{Unique: true}},
        {Name: "bio",   Type: model.Text(), OmitEmpty: true},
        {Name: "addr",  Type: model.Struct(), Ref: &AddressModel},
    },
}

var AddressModel = model.Definition{
    Name: "address",
    Fields: model.Fields{
        {Name: "street", Type: model.Text()},
        {Name: "city",   Type: model.Text()},
    },
}

2. Generate

ormc

Generates model_orm.go next to each source file, containing the type User struct, type Address struct, and all interface implementations.

3. Use it

func GetUser(db *orm.DB, id int64) (*user.User, error) {
    return user.ReadOneUser(
        db.Query(&user.User{}).Where("id").Eq(id),
        &user.User{},
    )
}

Definition Reference

model.Field Options

Field Meaning
Name wire/DB column name (snake_case). Becomes PascalCase in the generated struct.
Type model.Kind (e.g. model.Text(), model.Int(), model.Struct()).
NotNull NOT NULL constraint in DB.
OmitEmpty Skips field if zero-value in codecs.
Exclude Field exists in generated struct but is skipped in Schema(), Pointers(), and codecs (e.g. for password_hash).
Widget Binding for UI rendering (see tinywasm/form/input).
DB Database-specific metadata (PK, Unique, AutoInc, RefColumn, OnDelete).
Ref Points to another *model.Definition. Used for composition or scalar Foreign Keys.
Permitted Validation rules (Minimum, Maximum, Letters, Numbers, etc.).

Relations

  1. Composition: When Type is model.Struct() or model.StructSlice(). The field becomes a nested struct or slice of structs part of the same row/JSON.
  2. Scalar Foreign Key: When Type is a scalar (e.g. model.Int()) and Ref is non-nil. Adds DDL metadata for FOREIGN KEY constraints.
{Name: "user_id", Type: model.Int(), Ref: &UserModel, DB: &model.FieldDB{RefColumn: "id", OnDelete: "CASCADE"}}

Schema Types Mapping

model.Kind Generated Go Type Codec Method
model.Text(), model.Raw() string String / Raw
model.Int() int64 Int
model.Float() float64 Float
model.Bool() bool Bool
model.Blob() []byte Bytes
model.IntSlice() []int Array
model.Struct() T (from Ref) Object
model.StructSlice() []*T (from Ref) Array

Generated Code

The ormc generator produces:

  • type T struct declaration.
  • Schema() []model.Field, Pointers() []any (parallel, zero-alloc).
  • EncodeFields(model.FieldWriter), DecodeFields(model.FieldReader) (symmetric codec).
  • IsNil() bool.
  • Validate(action byte) error (calling model.ValidateFields). Always generated.
  • ModelName() string.
  • ReadOneT(), ReadAllT(), TList type (for DB models).
  • SchemaExt() []ddlc.FieldExt (requires tinywasm/ddlc).

More Documentation

About

tiny orm data base adapter

Resources

License

Stars

1 star

Watchers

0 watching

Forks

Packages

 
 
 

Contributors

Languages