An Entity Framework-inspired ORM / Data Mapper for Go, built on top of go-foundation.
Type-safe queries • Zero code generation • Dual SQL/NoSQL backends • Code-First Migrations
dsl.Register(User{})
ctx := wh.New(provider.Default())
var u User
ctx.Set(&u).Find(42)
u.Age = 35
ctx.Save() // → UPDATE "users" SET "age" = ? WHERE "id" = ?- Global CLI Tool - Entity Framework-like CLI, runs via build flag or standalone binary
- Auto-Discovery — Automatically finds models with
dbtags in your project - Pointer-tracking DSL — compile-time type-safe queries, no code generation
- Change Tracker — Unit of Work with partial UPDATE (only changed columns)
- SQL + NoSQL — pluggable providers for PostgreSQL, SQLite, MySQL, MongoDB, Slipstream (Bitcask), MemDoc (in-memory)
- Cross-Engine Sync — migrate data between different engines (e.g. MSSQL to Postgres) with identity/sequence handling
- Engine-Specific Naming — automatic mapping between conventions (PascalCase for MSSQL, snake_case for others)
- Code-First Migrations — EF Core-style differ, runner, CLI, scaffold, multi-dialect DDL
- Vector Search - pgvector nearest-neighbor on PostgreSQL (L2 / cosine / inner-product distance). PostgreSQL only; see Limitations
- Resilience — retry with backoff, circuit breaker, aggregated MultiError
- Lifecycle Hooks —
BeforeSave(),AfterInsert()auto-discovered via reflection - DI-ready — first-class
go-foundation/pkg/diintegration
type User struct {
ID int `db:"primary_key;auto_increment"`
Name string `db:"column:name"`
Age int `db:"column:age"`
}export WORMHOLE_DSN="./myapp.db"
export WORMHOLE_DRIVER="sqlite" # or postgres, mysql, sqlserverIf your project imports go-wormhole as a library, use the -tags wormhole_cli build flag
to run wormhole commands directly from your project, no extra setup needed:
go run -tags wormhole_cli . migrations add CreateUser
go run -tags wormhole_cli . database update
go run -tags wormhole_cli . migrations listOr install the standalone CLI:
go install github.com/fabricatorsltd/go-wormhole/cmd/wormhole@latest
wormhole migrations add CreateUser
wormhole database update| Chapter | Topic |
|---|---|
| 01 — Getting Started | Install, define entities, first query in 3 steps |
| 02 — Pointer-Tracking DSL | How it works, all operators, type safety |
| 03 — Change Tracker | Unit of Work, snapshots, partial updates, hooks |
| 04 — Code-First Migrations | Differ, runner, CLI, scaffold, dialects |
| 05 — Providers | SQL provider, Slipstream, multi-backend setup |
| 06 — Resilience | Retry, circuit breaker, MultiError |
| 07 — Architecture | Internals, data flows, design decisions |
| 08 — Relationships | 1:1, 1:N, N:M declarations, eager loading with Include |
| 09 — Global CLI Tool | Entity Framework-like CLI experience |
| 10 - Concurrency & Lifetime | DbContext per request, what to share, thread-safety |
Runnable programs in examples/ cover CRUD, querying, advanced query
shapes (DISTINCT, subqueries, set operations, CASE), and modeling (composite keys,
computed columns, JSON value objects, single-table hierarchy). Each runs on an
in-memory database with no setup: go run ./examples/crud.
- Vector search is PostgreSQL-only. Nearest-neighbor search uses the pgvector extension and is verified end-to-end against pgvector 0.6 on PostgreSQL 16. A vector query on any other provider returns an error rather than running.
- MongoDB
$vectorSearchis not implemented. Atlas vector search is powered bymongot, an Atlas-only component that cannot be installed onto a self-hosted MongoDB, so the native Mongo vector path was deferred and ships untested in this release. It is gated off (vector queries on Mongo return an error), so it fails closed rather than returning wrong results. Building and verifying it needs an Atlas (cloud) or Atlas CLI local deployment.
| Entity Framework | go-wormhole |
|---|---|
dotnet ef migrations add |
wormhole migrations add |
dotnet ef database update |
wormhole database update |
dotnet ef migrations list |
wormhole migrations list |
dotnet ef migrations script |
wormhole migrations script |
dotnet ef dbcontext scaffold |
wormhole dbcontext scaffold |
# PostgreSQL
export WORMHOLE_DRIVER=postgres
export WORMHOLE_DSN="host=localhost user=postgres dbname=myapp sslmode=disable"
# MySQL
export WORMHOLE_DRIVER=mysql
export WORMHOLE_DSN="user:password@tcp(localhost:3306)/myapp?parseTime=true"
# SQL Server
export WORMHOLE_DRIVER=sqlserver
export WORMHOLE_DSN="server=localhost;user id=sa;database=myapp"
# SQLite (default)
export WORMHOLE_DRIVER=sqlite
export WORMHOLE_DSN=./myapp.dbBuilding with -tags wormhole_cli activates the CLI inside DbContext.New() via a
build-tag-gated method. Execution is intercepted and the wormhole CLI runs before your
main() logic continues. No files are generated in your project and no code changes
are needed.
MIT