QUARK ORM
Quark is v0.12 — late-alpha. Phase 6 (codegen + HA + sharding + benchmarks → v1.0) is open and actively delivering; the project is not yet v1.0 production-ready — see docs/ANALISIS_MADUREZ.md for the honest gap analysis. The core query builder, CRUD, schema-as-code migrations, multi-tenancy, caché, hooks/eventos/audit log, and observability are considered stable. Oracle is excluded from CI while a testcontainers image issue is open — Oracle-specific SQL is validated manually. Breaking changes are documented per version under docs/MIGRATION_vX.Y.Z.md with a migration path.
QUARK is a modern ORM for Go built around generics, immutable query builders, multi-dialect SQL, and production extension points. It keeps model code close to plain Go structs while still covering migrations, relations, batch operations, transactions, validation, caching, telemetry, and multi-tenancy.
// Query
users, err := quark.For[User](ctx, client).
Where("active", "=", true).
Preload("Posts").
OrderBy("created_at", "DESC").
Limit(20).
List()
// Batch upsert — dialect-specific SQL generated automatically
err = quark.For[Product](ctx, client).UpsertBatch(
feed,
[]string{"sku"},
[]string{"price", "stock"},
)
Why QUARK
| Capability | What it gives you |
|---|---|
| Type-safe API | quark.For[T] returns a *Query[T] — reads map directly back into model structs. |
| Compile-time column accessors | Opt-in: quark gen emits <Model>Columns so WhereP(UserColumns.Email.Eq(...)) catches column typos and wrong-typed values at build time. |
| Composable query builder | Typed expression AST, subqueries, CTEs, window functions, set operators (UNION/INTERSECT/EXCEPT), pessimistic locking (FOR UPDATE/SKIP LOCKED), optimistic locking (quark:"version"). |
| Immutable builders | Query methods clone builder state, making shared base queries safe to reuse across goroutines. |
| SQLGuard | Identifiers, operators, keywords, JSON paths, and JOIN-ON clauses are validated before SQL generation. |
| Six dialects | PostgreSQL, MySQL, MariaDB, SQLite, MSSQL, and Oracle with dialect-specific DDL, upserts (ON CONFLICT / ON DUPLICATE KEY / MERGE), and pagination. |
| Full batch suite | CreateBatch, UpsertBatch, UpdateBatch, DeleteBatch — dialect-dispatched and chunked automatically. |
| Schema-as-code migrations | Neutral introspection, pure-Go Diff, PlanMigration/ApplyPlan round-trip, transactional + resumable execution, distributed migration lock, orchestrated Backfill. |
| Multi-tenancy (4 strategies) | DatabasePerTenant, SchemaPerTenant, RowLevelSecurityClient (WHERE injection, all dialects), and RowLevelSecurityNative (PG-only, engine-enforced via set_config + CREATE POLICY with the quarktenant CLI). |
| Transactional hooks | Before*/After* (with After* firing post-commit under Client.Tx), BeforeFind/AfterFind, public Tx.OnCommit/Tx.OnRollback + quark.TxFromContext. |
| Event bus + audit log | Client.UseEventBus publishes created/updated/deleted synchronously post-commit; Client.EnableAuditLog writes quark_audit atomically with the CRUD transaction. |
| Dirty tracking | Tracked[T] snapshots at load; Save() emits UPDATE limited to changed fields — closes the "can't set false/0/""" trap. |
| Production caché | L2 store (memory / Redis) with stampede protection (singleflight + ±jitter + XFetch, ADR-0011), per-row + table tag invalidation. |
| Observability | OpenTelemetry traces and metrics (counter + duration/rows histograms), WithSpanRedaction (default-on), WithSlowQueryThreshold, WithDeadlockRetry. |
Why I built this
After running production services on GORM, three patterns kept causing incidents: every db.Find(&result) forced an interface{} cast the compiler couldn't verify; column names in WHERE clauses were plain strings with no guard against typos or injection in dynamic queries; N+1 queries appeared silently whenever a Preload was forgotten, only surfacing in slow-query logs hours later; and multi-tenant isolation meant copy-pasting WHERE tenant_id = ? everywhere, relying on discipline instead of enforcement. Quark is the ORM I wished existed: generics end the casts, SQLGuard validates every identifier at the API boundary, eager loading is explicit, and multi-tenancy is first-class — not an afterthought.
Documentation map
Guides
| Section | Contents |
|---|---|
| Installation | Requirements, drivers, optional packages, env vars |
| Getting Started | Connect, model, migrate, CRUD |
| Modeling | Tags, composite PKs, soft delete, validation, rich types (Nullable/JSON/Array), per-column timezones |
| Query Builder | Filters, scopes, joins, aggregates, streaming, CTEs, window functions, set operators, locking |
| Batch Operations | CreateBatch, UpsertBatch, UpdateBatch, DeleteBatch |
| Relations | has_many, belongs_to, many_to_many, polymorphic |
| Migrations | Migrate, Sync, schema diff (PlanMigration/ApplyPlan), Backfill, distributed lock |
| Transactions | Callback, manual, savepoints, isolation levels, WithDeadlockRetry |
| Lifecycle Hooks | Before/After Create/Update/Delete/Find, post-commit semantics, Tx.OnCommit/Tx.OnRollback |
| Operational Workflows | cmd/quark binary, migrations and tenant Go commands |
| Code Generation | Opt-in quark gen — typed scanners, INSERT binder, compile-time column accessors |
Advanced
| Section | Contents |
|---|---|
| Multi-Tenant | DatabasePerTenant, SchemaPerTenant, RowLevelSecurityClient |
| PostgreSQL Native RLS | RowLevelSecurityNative engine-enforced + quarktenant CLI |
| Event Bus | Client.UseEventBus, synchronous post-commit, at-least-once |
| Audit Log | Client.EnableAuditLog, atomic with CRUD transaction |
| Caching & Observability | L2 cache, stampede protection, OTel traces + metrics, slow-query log |
| Read Replicas | WithReplicas (experimental), Sticky(ctx) |
Reference
| Section | Contents |
|---|---|
| SQLGuard | Identifier validation, JSON path, JOIN-ON, AllowRawQueries |
| Comparison | Cell-by-cell vs GORM, sqlx, Ent |
| Configuration | Limits, WithDialect, WithCacheStore, middleware, observability options |
| Dialects | Dialect table, upsert mapping, custom dialects |
| Benchmarks | Reproducible database/sql baseline + GORM comparison |
| Architecture | Request lifecycle, SQLGuard, schema evolution |
| Roadmap | Implemented today vs Phase 6 in progress vs long-term |
| Release Notes | Per-version changelog |
Install
go get github.com/jcsvwinston/quark
import "github.com/jcsvwinston/quark"
See Installation for driver requirements, optional packages, and test environment variables.