Architecture
QUARK is organized around a small set of primitives:
Clientowns the database handle, dialect, middleware, observers, cache, and migration helpers.Query[T]is the immutable typed builder for model operations.Dialectisolates database-specific SQL details.- Middleware and hooks extend the execution path.
TenantRouterinjects tenant-aware behavior.
Core principles
| Principle | Implementation |
|---|---|
| Type safety | For[T] returns a query bound to a concrete model type. |
| Immutability | Query methods clone builder state before returning the next query. |
| Database independence | Dialects own placeholders, quoting, upserts, and DDL. |
| Guarded SQL | SQLGuard validates identifiers, operators, and keywords. |
| Modular execution | Middleware, hooks, observers, and cache stores are injected through the client. |
Request lifecycle
quark.For[T]parses model metadata and initializes a typed builder.- Builder methods add query state by returning cloned builders.
- An endpoint such as
List,Create,Update, orDeleteexecutes. - Write operations run validation.
- Middleware and lifecycle hooks wrap the operation.
- SQL is generated through the dialect and SQLGuard.
database/sqlexecutes the statement.- Rows are mapped into typed models.
- Preloads resolve associations with secondary queries.
- Observers and telemetry receive query events.
Native routines and events
QUARK separates routine execution from normal model queries.
users, err := quark.NewRoutine[User](
ctx,
client,
"get_active_users",
100,
).List()
For stored procedures with output parameters, use Call.
var processed int
err := quark.Call(
ctx,
client,
"process_billing",
"2026-05",
sql.Out{Dest: &processed},
)
Database-native events are exposed through notification helpers such as
quark.Notify.
Schema evolution
Schema operations are routed through dialect methods for add, drop, alter, rename column, and rename table behavior. Dialects also report whether transactional DDL is supported.