Documentation
¶
Overview ¶
Package den is an ODM for Go with two storage backends (SQLite and PostgreSQL). It exposes a single chainable QuerySet for filter-and-act operations and a small set of doc-in-hand top-level functions for persistence (Save, Delete, FindByID, Refresh).
This root package is the convenience surface: type aliases for every exported type plus thin wrapper functions for every exported function. The implementation lives in github.com/oliverandrich/den/engine, which is a public package — applications that need types or functions the root does not re-export (e.g. when building tooling) can import it directly. The aliases preserve type identity, so `den.QuerySet[T]` IS `engine.QuerySet[T]`.
Index ¶
- Constants
- Variables
- func AdvisoryLock(ctx context.Context, tx *Tx, key int64) error
- func Collections(db *DB) []string
- func Delete[T any](ctx context.Context, s Scope, document *T, opts ...CRUDOption) error
- func DeleteAll[T any](ctx context.Context, s Scope, docs []*T, opts ...CRUDOption) error
- func FetchAllLinks[T any](ctx context.Context, s Scope, doc *T) error
- func FetchLink[T any](ctx context.Context, s Scope, doc *T, fieldName string) error
- func FetchLinkField[T any](ctx context.Context, s Scope, link *Link[T]) error
- func FindByID[T any](ctx context.Context, s Scope, id string, opts ...CRUDOption) (*T, error)
- func FindByIDs[T any](ctx context.Context, s Scope, ids []string, opts ...CRUDOption) ([]*T, error)
- func GetChanges[T any](db *DB, doc *T) (map[string]FieldChange, error)
- func IsChanged[T any](db *DB, doc *T) (bool, error)
- func LiteralFTS5(term string) string
- func LockByID[T any](ctx context.Context, tx *Tx, id string, opts ...LockOption) (*T, error)
- func Marshal(v any) ([]byte, error)
- func NewID() string
- func PreserveServerFields[T any](db *DB, dst, src *T) error
- func Refresh[T any](ctx context.Context, s Scope, document *T, opts ...CRUDOption) error
- func RefreshAll[T any](ctx context.Context, s Scope, docs []*T, opts ...CRUDOption) error
- func Register(ctx context.Context, db *DB, types ...document.Document) error
- func RegisterBackend(scheme string, opener func(ctx context.Context, dsn string) (Backend, error))
- func Replace[T any](ctx context.Context, s Scope, fresh *T, opts ...CRUDOption) error
- func Revert[T any](db *DB, doc *T) error
- func RunInTransaction(ctx context.Context, db *DB, fn func(tx *Tx) error) error
- func Save[T any](ctx context.Context, s Scope, document *T, opts ...CRUDOption) error
- func SaveAll[T any](ctx context.Context, s Scope, docs []*T, opts ...CRUDOption) error
- type AfterDeleter
- type AfterInserter
- type AfterSaver
- type AfterSoftDeleter
- type AfterUpdater
- type AggregateOp
- type Backend
- type BeforeDeleter
- type BeforeInserter
- type BeforeSaver
- type BeforeSoftDeleter
- type BeforeUpdater
- type CRUDOption
- type CollectionMeta
- type DB
- type DanglingLinkError
- type DenSettable
- type DropStaleOption
- type DropStaleResult
- type FTSProvider
- type FTSSearcher
- type FieldChange
- type FieldMeta
- type GroupByAgg
- type GroupByBuilder
- type GroupByRow
- type GroupBySortEntry
- type IndexDefinition
- type Iterator
- type Link
- type LinkFieldMeta
- type LinkRule
- type LockMode
- type LockOption
- type Option
- type Query
- type QuerySet
- type ReadWriter
- type RecordedIndex
- type Scope
- type SeekableStorage
- type SetFields
- type Settings
- type SortDirection
- type SortEntry
- type StaleIndex
- type Storage
- type Transaction
- type Tx
- type Validator
Constants ¶
const ( // SortDirection Asc = engine.Asc Desc = engine.Desc // AggregateOp OpSum = engine.OpSum OpAvg = engine.OpAvg OpMin = engine.OpMin OpMax = engine.OpMax OpCount = engine.OpCount // LinkRule LinkIgnore = engine.LinkIgnore LinkWrite = engine.LinkWrite LinkDelete = engine.LinkDelete // LockMode LockDefault = engine.LockDefault LockSkipLocked = engine.LockSkipLocked LockNoWait = engine.LockNoWait // Reserved field name constants FieldID = engine.FieldID FieldCreatedAt = engine.FieldCreatedAt FieldUpdatedAt = engine.FieldUpdatedAt FieldRev = engine.FieldRev FieldDeletedAt = engine.FieldDeletedAt FieldDeletedBy = engine.FieldDeletedBy FieldDeleteReason = engine.FieldDeleteReason )
Variables ¶
var ( ErrNotFound = engine.ErrNotFound ErrMultipleMatches = engine.ErrMultipleMatches ErrDuplicate = engine.ErrDuplicate ErrRevisionConflict = engine.ErrRevisionConflict ErrNotRegistered = engine.ErrNotRegistered ErrValidation = engine.ErrValidation ErrTransactionFailed = engine.ErrTransactionFailed ErrNoSnapshot = engine.ErrNoSnapshot ErrMigrationFailed = engine.ErrMigrationFailed ErrLocked = engine.ErrLocked ErrDeadlock = engine.ErrDeadlock ErrSerialization = engine.ErrSerialization ErrFTSNotSupported = engine.ErrFTSNotSupported ErrLockRequiresTransaction = engine.ErrLockRequiresTransaction ErrIncompatiblePagination = engine.ErrIncompatiblePagination ErrUnsupportedScheme = engine.ErrUnsupportedScheme )
Error sentinels re-exported from den/engine so callers keep matching via `errors.Is(err, den.ErrNotFound)`.
Functions ¶
func AdvisoryLock ¶ added in v0.8.0
AdvisoryLock acquires a transaction-scoped advisory lock identified by key. PostgreSQL only; SQLite no-ops.
func Collections ¶
Collections returns the names of every registered collection.
func Delete ¶
Delete removes a document. Soft-deletes when the document embeds `document.SoftDelete`; pass HardDelete() to bypass.
func DeleteAll ¶ added in v0.12.0
DeleteAll deletes every doc in docs in a single transaction. Fail-fast.
func FetchAllLinks ¶
FetchAllLinks resolves the direct link fields on doc — single-level, the loaded targets' own links stay untouched.
func FetchLinkField ¶ added in v0.11.0
FetchLinkField resolves the link by typed pointer instead of a stringly-named field on the parent.
func FindByID ¶
FindByID retrieves a document by its ID. Returns ErrNotFound if no row matches. Explicit-by-ID lookups bypass the soft-delete filter — callers can check Value.IsDeleted() to react.
func FindByIDs ¶
FindByIDs retrieves multiple documents by their IDs in a single query. Missing IDs are silently skipped.
func GetChanges ¶
GetChanges returns a map of field names to their before/after values for all fields that changed since the document was loaded.
func IsChanged ¶
IsChanged reports whether the document has changed since it was loaded. Returns false if the document has no snapshot (never loaded or not Trackable).
func LiteralFTS5 ¶ added in v0.17.0
LiteralFTS5 builds a literal-terms FTS5 MATCH string from a raw term: whitespace-separated tokens become double-quoted literals ANDed together, neutralising FTS5 operators and punctuation. QuerySet.Search applies this automatically, so most callers never need it directly — reach for it only to compose a safe literal core with QuerySet.SearchRaw.
func LockByID ¶ added in v0.8.0
LockByID loads a document with a row-level lock held until the surrounding transaction commits or rolls back. Must be called inside a transaction; ErrLockRequiresTransaction otherwise.
func Marshal ¶ added in v0.17.0
Marshal is Den's output JSON marshaller: like json.Marshal, but any hydrated (Loaded) Link[T] anywhere in the value graph is emitted as its resolved object instead of the bare id. Unloaded links and all other fields marshal identically to the standard library — the default wire format (and Den's storage encoding) is unchanged. Hydrate the links you want expanded with QuerySet.WithFetchLinks, then Marshal for the response.
func NewID ¶ added in v0.4.0
func NewID() string
NewID generates a new ULID string. ULIDs are lexicographically sortable and timestamp-ordered. Use this for document IDs, worker IDs, or any unique identifier.
func PreserveServerFields ¶ added in v0.17.0
PreserveServerFields copies Den's server-owned fields (_id, _created_at, _updated_at, _rev, and the soft-delete audit fields) from src onto dst, leaving client-owned fields untouched. The building block behind Replace, for callers that load and persist the existing record themselves.
func Refresh ¶
Refresh re-reads a document from the database by its ID, overwriting all fields on the provided struct.
func RefreshAll ¶ added in v0.12.0
RefreshAll re-reads every doc in docs in a single transaction.
func Register ¶
Register registers one or more document types with the database. It must be called before any CRUD or query operation on the types. Types must embed document.Base to satisfy document.Document — the sealed marker enforces this at compile time.
func RegisterBackend ¶ added in v0.2.0
RegisterBackend registers a backend opener under the given URL scheme. Called from backend packages' init() functions; not typically called by application code.
func Replace ¶ added in v0.17.0
Replace performs a full-content replace (PUT semantics): fresh's client-owned fields overwrite the stored row — omitted fields reset to zero — while Den's server-owned identity, audit, and soft-delete fields are preserved from the existing record. Last-writer-wins (adopts the stored revision); does not resurrect soft-deleted documents. Returns ErrNotFound if no row matches fresh's ID, ErrValidation if it has none.
func Revert ¶ added in v0.8.0
Revert restores the document to its state at load time by decoding the stored snapshot back over its fields. Returns ErrNoSnapshot if the document was never loaded or does not embed `document.Tracked`.
func RunInTransaction ¶
RunInTransaction opens a write transaction on db, runs fn inside it, and commits on success. Any non-nil error from fn rolls back the transaction; the same error is returned to the caller.
Types ¶
type AfterDeleter ¶
type AfterDeleter = engine.AfterDeleter
type AfterInserter ¶
type AfterInserter = engine.AfterInserter
type AfterSaver ¶
type AfterSaver = engine.AfterSaver
type AfterSoftDeleter ¶ added in v0.11.0
type AfterSoftDeleter = engine.AfterSoftDeleter
type AfterUpdater ¶
type AfterUpdater = engine.AfterUpdater
type AggregateOp ¶
type AggregateOp = engine.AggregateOp
type BeforeDeleter ¶
type BeforeDeleter = engine.BeforeDeleter
type BeforeInserter ¶
type BeforeInserter = engine.BeforeInserter
type BeforeSaver ¶
type BeforeSaver = engine.BeforeSaver
type BeforeSoftDeleter ¶ added in v0.11.0
type BeforeSoftDeleter = engine.BeforeSoftDeleter
type BeforeUpdater ¶
type BeforeUpdater = engine.BeforeUpdater
type CRUDOption ¶
type CRUDOption = engine.CRUDOption
func HardDelete ¶
func HardDelete() CRUDOption
HardDelete permanently removes a soft-deleteable document instead of flipping its DeletedAt.
func IgnoreRevision ¶
func IgnoreRevision() CRUDOption
IgnoreRevision skips the optimistic-concurrency revision check on Save's update path. Use sparingly — race losers get silently overwritten.
func IncludeDeleted ¶ added in v0.11.0
func IncludeDeleted() CRUDOption
IncludeDeleted makes by-ID lookups (FindByID, FindByIDs) consider soft-deleted documents. Mirrors QuerySet.IncludeDeleted().
func SoftDeleteBy ¶ added in v0.11.0
func SoftDeleteBy(actor string) CRUDOption
SoftDeleteBy records an actor on the document's DeletedBy field on the soft-delete path. No-op on HardDelete() and on types that don't embed `document.SoftDelete`.
func SoftDeleteReason ¶ added in v0.11.0
func SoftDeleteReason(reason string) CRUDOption
SoftDeleteReason records a free-form reason on the document's DeleteReason field on the soft-delete path.
func WithLinkRule ¶
func WithLinkRule(rule LinkRule) CRUDOption
WithLinkRule sets the link cascading rule for Save / Delete and the QuerySet write terminals.
func WithoutFetchLinks ¶ added in v0.11.0
func WithoutFetchLinks() CRUDOption
WithoutFetchLinks suppresses link hydration on a doc-in-hand read, including fields tagged `den:"eager"`. Honored by FindByID, FindByIDs, and Refresh.
type CollectionMeta ¶
type CollectionMeta = engine.CollectionMeta
type DB ¶
func Open ¶
Open creates a new DB using the given backend directly. The context governs any registration work triggered by WithTypes (collection table creation, index provisioning); callers with long-running startup work can pass a timeout or cancellable context to abort it cleanly.
Use OpenURL for URL-based opening with automatic backend selection.
type DanglingLinkError ¶ added in v0.11.0
type DanglingLinkError = engine.DanglingLinkError
type DenSettable ¶
type DenSettable = engine.DenSettable
type DropStaleOption ¶ added in v0.8.0
type DropStaleOption = engine.DropStaleOption
type DropStaleResult ¶ added in v0.8.0
type DropStaleResult = engine.DropStaleResult
func DropStaleIndexes ¶ added in v0.8.0
func DropStaleIndexes(ctx context.Context, db *DB, opts ...DropStaleOption) (DropStaleResult, error)
DropStaleIndexes removes indexes that exist on the backend but are no longer declared by any registered type. Pass DryRun() to report what would change without touching the schema.
type FTSProvider ¶
type FTSProvider = engine.FTSProvider
type FTSSearcher ¶ added in v0.11.0
type FTSSearcher = engine.FTSSearcher
type FieldChange ¶
type FieldChange = engine.FieldChange
type GroupByAgg ¶ added in v0.7.0
type GroupByAgg = engine.GroupByAgg
type GroupByBuilder ¶
type GroupByBuilder[T any] = engine.GroupByBuilder[T]
type GroupByRow ¶ added in v0.7.0
type GroupByRow = engine.GroupByRow
type GroupBySortEntry ¶ added in v0.11.0
type GroupBySortEntry = engine.GroupBySortEntry
type IndexDefinition ¶
type IndexDefinition = engine.IndexDefinition
type LinkFieldMeta ¶ added in v0.17.0
type LinkFieldMeta = engine.LinkFieldMeta
func LinkFields ¶ added in v0.17.0
LinkFields enumerates the Link[T] / []Link[T] relation fields of the registered document type T (JSON name, target collection, single-vs-slice, eager). Returns ErrNotRegistered if T is not registered. Use it to validate or allowlist expandable relations without re-implementing reflection.
type LockOption ¶ added in v0.8.0
type LockOption = engine.LockOption
func NoWait ¶ added in v0.8.0
func NoWait() LockOption
NoWait makes LockByID return ErrLocked immediately when the row is already locked, instead of blocking. PostgreSQL only.
func SkipLocked ¶ added in v0.8.0
func SkipLocked() LockOption
SkipLocked makes LockByID return ErrNotFound when the row is already locked, instead of blocking. PostgreSQL only.
type Option ¶
func WithStorage ¶ added in v0.9.0
func WithStorage(s Storage) Option
WithStorage attaches an attachment Storage to the DB. Required when any registered type carries `document.Attachment` fields.
func WithTypes ¶ added in v0.8.0
WithTypes queues document types to be registered at the end of Open. Equivalent to calling Register(ctx, db, types...) after Open returns. Types must embed document.Base to satisfy document.Document — the sealed marker enforces this at compile time.
type QuerySet ¶
type ReadWriter ¶
type ReadWriter = engine.ReadWriter
type RecordedIndex ¶ added in v0.8.0
type RecordedIndex = engine.RecordedIndex
type SeekableStorage ¶ added in v0.11.2
type SeekableStorage = engine.SeekableStorage
type SortDirection ¶
type SortDirection = engine.SortDirection
type StaleIndex ¶ added in v0.8.0
type StaleIndex = engine.StaleIndex
type Transaction ¶
type Transaction = engine.Transaction
Directories
¶
| Path | Synopsis |
|---|---|
|
Package backend defines the contract every den storage engine implements: the Backend interface, plus the supporting types passed across it (Query, LockMode, AggregateOp, etc.).
|
Package backend defines the contract every den storage engine implements: the Backend interface, plus the supporting types passed across it (Query, LockMode, AggregateOp, etc.). |
|
postgres
Package postgres implements the Den backend for PostgreSQL via jackc/pgx/v5.
|
Package postgres implements the Den backend for PostgreSQL via jackc/pgx/v5. |
|
sqlite
Package sqlite implements the Den backend for SQLite via modernc.org/sqlite (pure Go, no CGO).
|
Package sqlite implements the Den backend for SQLite via modernc.org/sqlite (pure Go, no CGO). |
|
Package dentest provides test helpers for opening a Den database in a temporary directory (SQLite) or against a reachable PostgreSQL instance.
|
Package dentest provides test helpers for opening a Den database in a temporary directory (SQLite) or against a reachable PostgreSQL instance. |
|
Package engine is the den ODM implementation: DB and Tx, the chainable QuerySet, CRUD entry points, link hydration, lifecycle hooks, revision tracking, and soft-delete handling.
|
Package engine is the den ODM implementation: DB and Tx, the chainable QuerySet, CRUD entry points, link hydration, lifecycle hooks, revision tracking, and soft-delete handling. |
|
Package idgen produces ULID-format document IDs for Den.
|
Package idgen produces ULID-format document IDs for Den. |
|
internal
|
|
|
cmd/bench-report
command
Command bench-report reads `go test -bench` output on stdin and splices the benchmark results into README.md between the sentinel markers
|
Command bench-report reads `go test -bench` output on stdin and splices the benchmark results into README.md between the sentinel markers |
|
Package lock defines the option vocabulary for row-level and advisory locks used by engine.LockByID, engine.AdvisoryLock, and QuerySet.ForUpdate.
|
Package lock defines the option vocabulary for row-level and advisory locks used by engine.LockByID, engine.AdvisoryLock, and QuerySet.ForUpdate. |
|
Package maintenance defines the data shapes and option vocabulary for den's admin-side operations — notably engine.DropStaleIndexes, the post-schema-change cleanup that drops indexes Den previously created but no longer recognises.
|
Package maintenance defines the data shapes and option vocabulary for den's admin-side operations — notably engine.DropStaleIndexes, the post-schema-change cleanup that drops indexes Den previously created but no longer recognises. |
|
Package search defines the full-text-search contract that backends (and, where supported, their transactions) implement.
|
Package search defines the full-text-search contract that backends (and, where supported, their transactions) implement. |
|
Package storage defines the Storage interface that backs document.Attachment fields plus the registry OpenURL uses to construct a Storage from a URL-style DSN.
|
Package storage defines the Storage interface that backs document.Attachment fields plus the registry OpenURL uses to construct a Storage from a URL-style DSN. |
|
file
Package file provides a local-filesystem Storage backend for Den.
|
Package file provides a local-filesystem Storage backend for Den. |
|
Package validate exposes the struct-tag constraint helper used by Den.
|
Package validate exposes the struct-tag constraint helper used by Den. |