metadata

package
v0.3.1 Latest Latest
Warning

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

Go to latest
Published: Oct 31, 2026 License: MIT Imports: 26 Imported by: 0

Documentation

Overview

Package metadata stores typed, model-owned values through explicit key declarations. It shares owner identity and transactions with model extensions.

Index

Constants

View Source
const (
	MigrationOrigin migrate.Origin  = "foundry.metadata"
	CreateMetadata  migrate.ID      = "000001_create_metadata"
	Introduced      migrate.Version = "v0.1.0"
)
View Source
const MaxBatchBytes = extensionvalue.MaxBatchBytes
View Source
const MaxKeysPerOwner = 256
View Source
const MaxValueBytes = extensionvalue.MaxBytes

Variables

This section is empty.

Functions

func Cleanup

func Cleanup[M any, K comparable](ctx context.Context, tx *database.Tx, m *Manager, owner extensions.Owner[M, K], reference model.Reference[M, K], operation lifecycle.Operation) error

Cleanup joins a generated Deleted/ForceDeleted observer's transaction. Soft deletion keeps values for restoration; ordinary reads remain unavailable. A still-existing owner is rejected, preventing accidental early cleanup. Bulk model deletes skip observers and require explicit maintenance afterward.

func CleanupIdentity

func CleanupIdentity(ctx context.Context, tx *database.Tx, m *Manager, owner extensions.OwnerName, identity model.Identity) error

CleanupIdentity is Cleanup for an owner known by its registered name and persisted identity, such as a durable cleanup job's request. It joins tx and rejects an owner that still exists.

func DeleteAll

func DeleteAll[M any, K comparable](ctx context.Context, m *Manager, owner extensions.Owner[M, K], reference model.Reference[M, K]) (int, error)

DeleteAll removes metadata for an active owner. Lifecycle cleanup uses Cleanup instead, after the owner's ordinary DELETE/ForceDelete SQL has succeeded.

func Matching

func Matching[M any, K comparable, V any](ctx context.Context, manager *Manager, key Key[M, K, V], input V) (orm.Predicate[M], error)

Matching materializes a bounded ORM owner predicate for an exact canonical JSON value and declared version. It uses the manager's existing matching limits, validation and cancellation. The declaration must have an ORM owner. No match produces a false predicate; the subsequent owner query retains its own fresh visibility and authorization. This is a snapshot of matching keys, not a live subquery. Example: predicate, err := metadata.Matching(ctx, manager, Preferences, input); then Owners.Query().Where(predicate).

func Migrations

func Migrations() []migrate.Definition

Migrations are explicit and use the common Store's schema. No automatic boot migration or owner-table inference occurs.

func PruneOrphans

func PruneOrphans(ctx context.Context, m *Manager, owner extensions.OwnerName, keys []string) (int, error)

PruneOrphans locks exact inspected row keys and rechecks current owners, including soft-deleted models. Existing and foreign rows remain untouched.

Types

type Batch

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

Batch is an immutable snapshot of one typed key for currently active owners. Decode returns fresh values. It is not an authorization or eligibility cache for later operations; each new read/write rechecks the actual owner.

func (Batch[M, K, V]) Format

func (Batch[M, K, V]) Format(s fmt.State, _ rune)

func (Batch[M, K, V]) Get

func (b Batch[M, K, V]) Get(ctx context.Context, owner model.Reference[M, K]) (value.Optional[V], error)

type Cursor

Cursor resumes a bounded scan for this feature and registered owner. It is not a capability or a stable snapshot across separate pages.

type Key

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

Key retains both the owner model/key and the value codec. Reuse the same declaration in assembly and calls; a matching string name cannot substitute an unrelated value type or schema. Increment Version for incompatible changes.

func Define

func Define[M any, K comparable, V any](owner extensions.Owner[M, K], name Name, version Version, schema contract.JSON[V]) Key[M, K, V]

func KeyOf

func KeyOf[M any, K comparable, V any](slot ValueHandle[M, K, V]) Key[M, K, V]

KeyOf returns the slot's existing key for explicit batch reads and matching. It preserves registration identity and the concrete value type; a zero handle returns an invalid zero key. Example: metadata.KeyOf(bound.SEO).Get(ctx,manager,reference).

func (Key[M, K, V]) Decode

func (k Key[M, K, V]) Decode(ctx context.Context, r Record[M]) (V, error)

func (Key[M, K, V]) Forget

func (k Key[M, K, V]) Forget(ctx context.Context, m *Manager, owner model.Reference[M, K]) (bool, error)

func (Key[M, K, V]) Format

func (Key[M, K, V]) Format(s fmt.State, _ rune)

func (Key[M, K, V]) Get

func (k Key[M, K, V]) Get(ctx context.Context, m *Manager, owner model.Reference[M, K]) (value.Optional[V], error)

func (Key[M, K, V]) Load

func (k Key[M, K, V]) Load(ctx context.Context, m *Manager, owners []model.Reference[M, K]) (Batch[M, K, V], error)

func (Key[M, K, V]) Name

func (k Key[M, K, V]) Name() Name

func (Key[M, K, V]) Registration

func (k Key[M, K, V]) Registration() Registration

func (Key[M, K, V]) Set

func (k Key[M, K, V]) Set(ctx context.Context, m *Manager, owner model.Reference[M, K], input V) error

func (Key[M, K, V]) SetIn

func (k Key[M, K, V]) SetIn(ctx context.Context, tx *database.Tx, m *Manager, owner model.Reference[M, K], input V) error

SetIn joins a business transaction through the common savepoint/schema helper. A suppressed error cannot leave a partial metadata write in the outer Tx.

func (Key[M, K, V]) Validate

func (k Key[M, K, V]) Validate() error

func (Key[M, K, V]) Version

func (k Key[M, K, V]) Version() Version

type Manager

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

Manager borrows the common Store; it has no independent background work or shutdown. The store bounds and owns every metadata operation's actual lifetime.

func New

func New(store *extensions.Store, keys ...Registration) (*Manager, error)

func (*Manager) Validate

func (m *Manager) Validate() error

type Name

type Name string

type Orphan

type Orphan struct {
	Key  string `json:"key"`
	Name Name   `json:"name"`
}

type OrphanPage

type OrphanPage struct {
	Orphans []Orphan
	Scanned int
	Next    Cursor
}

func InspectOrphans

func InspectOrphans(ctx context.Context, m *Manager, owner extensions.OwnerName, cursor Cursor, limit int) (OrphanPage, error)

InspectOrphans never deletes. The limit bounds scanned rows, not matches, so sparse orphan sets cannot repeatedly starve later rows.

type Record

type Record[M any] struct {
	// contains filtered or unexported fields
}

Record preserves model ownership while supporting deliberate administrative inspection. Decode through its matching typed Key, or explicitly export the dynamic value. Records do not implicitly serialize private metadata.

func All

func All[M any, K comparable](ctx context.Context, m *Manager, owner extensions.Owner[M, K], reference model.Reference[M, K]) ([]Record[M], error)

All returns the bounded complete value set for one active owner. It includes unregistered persisted keys for explicit migration/administrative inspection.

func (Record[M]) CreatedAt

func (r Record[M]) CreatedAt() temporal.DateTime

func (Record[M]) DynamicValue

func (r Record[M]) DynamicValue() (json.RawMessage, error)

func (Record[M]) Format

func (Record[M]) Format(s fmt.State, _ rune)

func (Record[M]) MarshalJSON

func (Record[M]) MarshalJSON() ([]byte, error)

func (Record[M]) Name

func (r Record[M]) Name() Name

func (Record[M]) UpdatedAt

func (r Record[M]) UpdatedAt() temporal.DateTime

func (Record[M]) Version

func (r Record[M]) Version() Version

type Registration

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

type RescopePage

type RescopePage = extensionmaintenance.RescopePage

func InspectStale

func InspectStale(ctx context.Context, m *Manager, owner extensions.OwnerName, cursor Cursor, limit int) (RescopePage, error)

InspectStale lists, without writing, rows whose owner column names this registered owner but whose scope is not the owner's current scope. They are invisible to ordinary reads, typically after an owner table was renamed without declaring extensions.OwnerOptions.StorageModel; declare the old name in OwnerOptions.PreviousModels to adopt them. Conflicts, Missing subjects and Undeclared models are reported and left in place.

func Rescope

func Rescope(ctx context.Context, m *Manager, owner extensions.OwnerName, cursor Cursor, limit int) (RescopePage, error)

Rescope moves one bounded page of stale rows into the owner's current scope, preserving name, version, value and creation time. Each row is verified and locked first; a conflicting current-scope row is never overwritten.

type Spec

type Spec[V any] struct {
	Version Version
	JSON    contract.JSON[V]
}

Spec declares a metadata slot's stored version and JSON contract. A zero Version selects 1 and a zero JSON selects the contract generation inferred from the slot's value type (a generated DTO, scalar or json.RawMessage). Increment Version for incompatible changes: strict decoding rejects stored values with removed or renamed fields.

type StaleRow

type StaleRow = extensionmaintenance.Stale

StaleRow is one metadata row recorded under an earlier scope of its owner and its key in the owner's current scope. RescopePage lists rows inspected or moved; Conflicts are stale rows whose current-scope key already exists.

type Undeclared

type Undeclared = extensionmaintenance.Undeclared

Undeclared lists stored names that no current registration declares.

func InspectUndeclared

func InspectUndeclared(ctx context.Context, m *Manager, owner extensions.OwnerName) (Undeclared, error)

InspectUndeclared lists stored key names in owner's current scope that no key registered with m declares, for example after renaming a slot field without pinning its stored name. It reads names only and modifies nothing.

type Value

type Value[V any] struct {
	// contains filtered or unexported fields
}

Value is a model slot holding one typed metadata value. The zero value is not loaded; a loaded slot distinguishes an absent key from a stored value. Reading a slot performs no I/O. Maps and slices inside a decoded value keep ordinary Go value-copy semantics.

func (Value[V]) Format

func (Value[V]) Format(s fmt.State, _ rune)

func (Value[V]) Get

func (v Value[V]) Get() (value.Optional[V], bool)

Get returns the optional stored value and whether the slot was loaded.

func (Value[V]) IsLoaded

func (v Value[V]) IsLoaded() bool

IsLoaded reports whether the slot was filled by a loader.

func (Value[V]) MarshalJSON

func (Value[V]) MarshalJSON() ([]byte, error)

type ValueHandle

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

ValueHandle retains typed slot capabilities behind shared callback state. Example: slot.From(manager).Relation(Fields.Slot).

func ValueOf

func ValueOf[M any, K comparable, V any](owner extensions.Owner[M, K], name Name, spec Spec[V], inferred contract.JSON[V], binding extensions.SlotBinding[M, K, Value[V]]) ValueHandle[M, K, V]

ValueOf declares a thin metadata handle retaining the concrete input and JSON contract. Example: metadata.ValueOf(owner,"seo",spec,contract.StringJSON[string](),binding).

func (ValueHandle[M, K, V]) Describe

func (s ValueHandle[M, K, V]) Describe() extensions.SlotDescription

Describe returns an owned inspection snapshot. Example: slot.Describe().

func (ValueHandle[M, K, V]) Forget

func (s ValueHandle[M, K, V]) Forget(ctx context.Context, owner M) (bool, error)

Forget removes the stored value and reports whether it existed. Example: slot.Forget(ctx,article).

func (ValueHandle[M, K, V]) ForgetIn

func (s ValueHandle[M, K, V]) ForgetIn(ctx context.Context, tx *database.Tx, owner M) (bool, error)

ForgetIn removes the stored value in the caller transaction. Example: slot.ForgetIn(ctx,tx,article).

func (ValueHandle[M, K, V]) Format

func (ValueHandle[M, K, V]) Format(s fmt.State, _ rune)

Format omits retained runtime state. Example: fmt.Sprintf("%+v",slot).

func (ValueHandle[M, K, V]) From

func (s ValueHandle[M, K, V]) From(m *Manager) ValueHandle[M, K, V]

From returns a copy borrowing this family's manager; nil leaves it unbound. Example: slot.From(manager).

func (ValueHandle[M, K, V]) Name

func (s ValueHandle[M, K, V]) Name() Name

Name returns the stored name. Example: slot.Name().

func (ValueHandle[M, K, V]) Registration

func (s ValueHandle[M, K, V]) Registration() Registration

Registration returns the existing manager registration. Example: slot.Registration().

func (ValueHandle[M, K, V]) Relation

func (s ValueHandle[M, K, V]) Relation(slot orm.Slot[M, Value[V]]) orm.ExtensionRelation[M]

Relation binds the loader to its concrete ORM field; mismatched fields fail validation. Example: Articles.Query().With(slot.Relation(Articles.SEO)).

func (ValueHandle[M, K, V]) Save

func (s ValueHandle[M, K, V]) Save(ctx context.Context, owner M, input V) error

Save replaces the typed value in the manager transaction. Example: slot.Save(ctx,article,input).

func (ValueHandle[M, K, V]) SaveIn

func (s ValueHandle[M, K, V]) SaveIn(ctx context.Context, tx *database.Tx, owner M, input V) error

SaveIn replaces the typed value in the caller transaction. Example: slot.SaveIn(ctx,tx,article,input).

func (ValueHandle[M, K, V]) Validate

func (s ValueHandle[M, K, V]) Validate() error

Validate checks the declaration and slot binding. Example: slot.Validate().

type Version

type Version uint32

Directories

Path Synopsis
Package command provides metadata maintenance commands, borrowing already assembled services.
Package command provides metadata maintenance commands, borrowing already assembled services.

Jump to

Keyboard shortcuts

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