Help us shape the future of Go! Take the 2026 Go Developer Survey

extensions

package
v0.5.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 3, 2026 License: MIT Imports: 25 Imported by: 0

Documentation

Overview

Package extensions shares typed model ownership for framework model stores. It does not grant authentication or authorization; applications retain those decisions before invoking a model extension.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Digest

func Digest(parts ...string) string

Digest is the shared unambiguous hashing boundary for infrastructure scopes and operation identifiers. Inputs are JSON-escaped owned strings.

func LoadInParts

func LoadInParts[M, S any](ctx context.Context, parents []M, size int, limit error, load func(context.Context, []M) ([]S, error)) ([]S, error)

LoadInParts runs load over parents in parts of at most size, keeping their order. A part whose load reports limit, a store's row or byte bound, is halved and retried, so a batch bounded by retained bytes loads whenever each owner fits alone. Reads are side-effect free, so a retry repeats no effect.

func Module

func Module(name foundation.ProviderID, key foundation.Key[*Store], requires []foundation.ProviderID, construct func(foundation.Resolver) (*Store, error)) foundation.Module

Module owns its Store and requires providers owning its borrowed database. Feature managers using the store must in turn depend on this module.

func ORMIdentity

func ORMIdentity[M any, K comparable](owner Owner[M, K]) orm.ModelIdentity[M, K]

ORMIdentity returns the exact identity retained by a declaration-based owner. Example: extensions.ORMIdentity(owner).ReferenceOf(article).

Types

type Config

type Config struct {
	Schema    string
	Clock     clock.Clock
	MaxActive int
	Timeout   time.Duration
}

Config bounds the shared store. MaxActive admits that many concurrent operations; a burst beyond it queues in FIFO order for a short bounded wait before failing with fault.Overloaded, so latency spikes delay reads instead of rejecting them. Timeout bounds each admitted operation.

func DefaultConfig

func DefaultConfig() Config

DefaultConfig returns default schema, clock, capacity, and operation timeout settings.

func (Config) Validate

func (c Config) Validate() error

Validate checks the schema, clock, concurrency bound, and timeout.

type Declaration

type Declaration struct {
	// contains filtered or unexported fields
}

Declaration erases model types only at application assembly. Names and model namespaces, including declared storage models, must be unique; constructing a registry performs no database I/O.

func (Declaration) Describe

func (d Declaration) Describe() OwnerDescription

Describe returns the owner's persisted identity for inspection.

func (Declaration) Name

func (d Declaration) Name() OwnerName

Name identifies the declared owner for assembly diagnostics.

type Owner

type Owner[M any, K comparable] struct {
	// contains filtered or unexported fields
}

Owner binds one model and its concrete key to framework identity metadata. Reuse this exact declaration across attachments, metadata and translations.

func DefineORMOwner

func DefineORMOwner[M any, K comparable](name OwnerName, source orm.ModelIdentity[M, K], options OwnerOptions) Owner[M, K]

DefineORMOwner binds a declaration's identity to the existing extension stores. Pin StorageModel before renaming a table. Example: extensions.DefineORMOwner("articles",orm.IdentityOf(Articles.Table,Articles.Key()),extensions.OwnerOptions{StorageModel:"articles"}).

func (Owner[M, K]) ActiveSubjects

func (o Owner[M, K]) ActiveSubjects(ctx context.Context, executor database.Executor, registry *Registry, references []model.Reference[M, K]) (map[string]bool, []string, error)

ActiveSubjects performs one bounded primary-key query for owners visible under the declared soft-delete policy. It returns active opaque Subject.Key values and each reference's subject key in input order, as SubjectKey derives it.

func (Owner[M, K]) Check

func (o Owner[M, K]) Check(r *Registry) error

Check checks that this exact owner declaration is registered.

func (Owner[M, K]) Format

func (o Owner[M, K]) Format(s fmt.State, _ rune)

Format writes a fixed label without exposing owner details.

func (Owner[M, K]) Lock

func (o Owner[M, K]) Lock(ctx context.Context, tx *database.Tx, registry *Registry, reference model.Reference[M, K]) (Subject, error)

Lock validates the exact registry declaration then locks a currently active owner. The caller's transaction serializes extension writes against owner deletion and soft deletion. Existing model snapshots alone are insufficient.

func (Owner[M, K]) Name

func (o Owner[M, K]) Name() OwnerName

Name returns the owner name, or an empty name for an undefined owner.

func (Owner[M, K]) Parse

func (o Owner[M, K]) Parse(identity model.Identity) (model.Reference[M, K], error)

Parse restores a typed reference from a serialized identity. An identity attributed to the declared storage model is accepted as this owner's model: persisted rows written before a table rename keep their original attribution, while the key must still round trip through the current key codec.

func (Owner[M, K]) RecordedModels

func (o Owner[M, K]) RecordedModels() []string

RecordedModels lists every model name persisted identities of this owner may carry: the current model, the storage model and declared previous models.

func (Owner[M, K]) Registration

func (o Owner[M, K]) Registration() Declaration

Registration returns the owner's registration callbacks, or an empty declaration for an undefined owner.

func (Owner[M, K]) Scope

func (o Owner[M, K]) Scope() string

Scope is the opaque persisted owner namespace. It depends only on the owner name and declared storage model, so a pinned storage model survives renames.

func (Owner[M, K]) StorageModel

func (o Owner[M, K]) StorageModel() string

StorageModel is the declared model name of the persisted owner scope. It equals the ORM identity's model name unless OwnerOptions pins a storage identity.

func (Owner[M, K]) Subject

func (o Owner[M, K]) Subject(reference model.Reference[M, K]) (Subject, error)

Subject converts a typed reference into an extension subject with a JSON identity snapshot.

func (Owner[M, K]) SubjectKey

func (o Owner[M, K]) SubjectKey(reference model.Reference[M, K]) (string, error)

SubjectKey returns the Subject.Key that Subject returns for reference, with the same validation but without snapshotting the identity. Reads use it to match owners with rows, which is all a subject key is for.

func (Owner[M, K]) Validate

func (o Owner[M, K]) Validate() error

Validate checks the owner name, model type, storage names, previous models, and identity source.

type OwnerDescription

type OwnerDescription struct {
	Name         OwnerName `json:"name"`
	Model        string    `json:"model"`
	StorageModel string    `json:"storage_model"`
}

OwnerDescription is an inspection snapshot of a registered owner identity.

type OwnerName

type OwnerName string

OwnerName identifies a model extension owner.

type OwnerOptions

type OwnerOptions struct {
	StorageModel   string
	PreviousModels []string
}

OwnerOptions declares the owner's persisted identity. StorageModel is the model name recorded in the owner scope, so every stored extension row, registration key and attachment object path depends on the declared owner identity rather than the current table name. Empty uses the declared table name, which is the historical, compatible scope. Declare the previous table name here before renaming an owner table; stored identities attributed to it are then accepted and decoded through the current key codec.

PreviousModels lists model names this owner's rows were recorded under before an undeclared rename. Only rows whose recorded scope and identity name one of these, the current model or the storage model are adopted by the explicit re-scope maintenance commands; rows of any other earlier model are reported, never moved.

type Registry

type Registry struct {
	// contains filtered or unexported fields
}

Registry holds validated model extension owner declarations.

func NewRegistry

func NewRegistry(owners ...Declaration) (*Registry, error)

NewRegistry validates and registers up to 256 owners, rejecting overlapping names or recorded models.

func (*Registry) AdoptSubject

func (r *Registry) AdoptSubject(owner OwnerName, identity model.Identity) (Subject, error)

AdoptSubject is the explicit re-scope maintenance boundary. It attributes a persisted identity recorded under one of the owner's declared models (see DeclaresModel) to its current model, decodes the key through the current codec and returns the subject in the owner's current scope. An identity of any other model is rejected. It performs no I/O and grants nothing.

func (*Registry) DeclaresModel

func (r *Registry) DeclaresModel(owner OwnerName, name string) bool

DeclaresModel reports whether name is the owner's current model, storage model or one of its declared OwnerOptions.PreviousModels.

func (*Registry) DeclaresScope

func (r *Registry) DeclaresScope(owner OwnerName, scope string) bool

DeclaresScope reports whether scope is the owner scope of one of the owner's declared models, the scopes its persisted rows may have been written under.

func (*Registry) Owners

func (r *Registry) Owners() []OwnerName

Owners returns a copy of the sorted owner names; a nil registry returns nil.

func (*Registry) RetainedSubjects

func (r *Registry) RetainedSubjects(ctx context.Context, executor database.Executor, owner OwnerName, identities []model.Identity) (map[string]bool, error)

RetainedSubjects is the explicit maintenance boundary. It includes soft- deleted owners, preventing them from being misclassified as orphans. Unknown owner declarations fail closed; maintenance never guesses a table name.

func (*Registry) Scope

func (r *Registry) Scope(owner OwnerName) (string, error)

Scope returns the registered owner's scope, rejecting unknown owners.

func (*Registry) Subject

func (r *Registry) Subject(owner OwnerName, identity model.Identity) (Subject, error)

Subject restores a registered owner's identity at an explicit heterogeneous maintenance boundary. Ordinary model APIs retain Owner[M,K].

func (*Registry) SubjectKey

func (r *Registry) SubjectKey(owner OwnerName, identity model.Identity) (string, error)

SubjectKey returns the Subject.Key that Subject returns for identity, with the same validation but without snapshotting the identity.

func (*Registry) Validate

func (r *Registry) Validate() error

Validate checks that the registry is initialized.

type SlotBinding

type SlotBinding[M any, K comparable, S any] struct {
	Field     string
	Reference func(M) model.Reference[M, K]
	Get       func(M) S
	Set       func(M, S) M
}

SlotBinding connects one generated model struct field to an extension declaration. Generation supplies it from the model's slot fields; Field names the Go field, which identifies the slot in eager loading and diagnostics. Reference derives the owner identity from a model value without I/O. Get and Set read and replace the slot on a model copy.

func BindSlot

func BindSlot[M any, K comparable, S any](key orm.Key[M, K], slot orm.Slot[M, S]) SlotBinding[M, K, S]

BindSlot connects a validated declaration offset and primary key to an extension. Example: extensions.BindSlot(Articles.Key(),Articles.Title).

func (SlotBinding[M, K, S]) Validate

func (b SlotBinding[M, K, S]) Validate() error

Validate checks the generated binding without calling its functions.

type SlotDescription

type SlotDescription struct {
	Field    string   `json:"field"`
	Kind     string   `json:"kind"`
	Name     string   `json:"name"`
	Storage  string   `json:"storage"`
	MaxBytes int64    `json:"max_bytes,omitempty"`
	Require  string   `json:"require,omitempty"`
	Disk     string   `json:"disk,omitempty"`
	MaxFiles int      `json:"max_files,omitempty"`
	Accepted []string `json:"accepted,omitempty"`
	Variants []string `json:"variants,omitempty"`
	Version  uint32   `json:"version,omitempty"`
}

SlotDescription is an owned, secret-free inspection snapshot of one model extension slot: its Go field, kind, stored name and declared policy bounds. Kinds are "text", "one", "many" and "value". Unused bounds are omitted.

type Store

type Store struct {
	// contains filtered or unexported fields
}

Store owns only operation admission. The database and immutable owner registry are borrowed. Constructing a store does not connect, migrate or seed data.

func New

func New(db *database.DB, registry *Registry, config Config) (*Store, error)

New validates dependencies and configuration and creates an extension store borrowing the database.

func (*Store) Clock

func (s *Store) Clock() clock.Clock

Clock is the store's configured time source. Feature caches use it for expiry so tests and applications share one injected clock.

func (*Store) Close

func (s *Store) Close(ctx context.Context) error

Close closes operation admission and waits for tracked work using the supplied context.

func (*Store) Database

func (s *Store) Database() *database.DB

Database returns the underlying database, or nil for a nil store.

func (*Store) Done

func (s *Store) Done() <-chan struct{}

Done returns the operation group's completion channel.

func (*Store) Format

func (*Store) Format(state fmt.State, _ rune)

Format writes a fixed label without exposing store data.

func (*Store) Join

func (s *Store) Join(ctx context.Context, tx *database.Tx, fn func(context.Context, *database.Tx) error) error

Join contains infrastructure writes in a savepoint of this store's exact borrowed pool. It restores the caller's search_path and never commits the outer transaction. Lifecycle adapters use this for atomic owner cleanup.

func (*Store) Now

func (s *Store) Now() (temporal.DateTime, error)

Now returns validated application time in UTC at microsecond precision.

func (*Store) Read

func (s *Store) Read(ctx context.Context, fn func(context.Context, *database.Tx) error) error

Read holds one read-only repeatable snapshot across owner checks and batched extension reads. It never adds row locks or invokes model presentation hooks.

func (*Store) ReadFor

func (s *Store) ReadFor(ctx context.Context, executor database.Executor, fn func(context.Context, *database.Tx) error) error

ReadFor reads inside the caller's transaction when executor is a transaction of this store's exact pool, so slot loads see that transaction's own uncommitted writes; the savepoint restores its search path. Any other executor, including custom wrappers, reads from Read's own snapshot.

func (*Store) Registry

func (s *Store) Registry() *Registry

Registry returns the owner registry, or nil for a nil store.

func (*Store) Schema

func (s *Store) Schema() string

Schema returns the configured schema, or an empty string for a nil store.

func (*Store) Validate

func (s *Store) Validate() error

Validate checks that the store and owner registry are initialized.

func (*Store) Write

func (s *Store) Write(ctx context.Context, fn func(context.Context, *database.Tx) error) error

Write opens a normal transaction. Extension writers must Lock their owner before modifying rows. Unknown commit outcomes must be reconciled, not undone by deleting external objects.

type Subject

type Subject struct {
	Scope, Key string
	Identity   value.JSON[model.Identity]
}

Subject is frozen infrastructure metadata, not owner authority. It contains the full typed identity at an explicit JSON storage boundary and an opaque equality key shared by every model extension.

func (Subject) Format

func (Subject) Format(s fmt.State, _ rune)

Format writes a fixed label without exposing the subject.

Directories

Path Synopsis
Package slots binds generated model extension slots to the translation, attachment and metadata managers.
Package slots binds generated model extension slots to the translation, attachment and metadata managers.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL