admin

package
v0.6.0 Latest Latest
Warning

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

Go to latest
Published: Sep 24, 2026 License: Apache-2.0 Imports: 12 Imported by: 0

Documentation

Overview

Package admin is the database admin service: schema state, verification, correction, seeding, named states, and diagnostics as operations over the sqlate library's functions, run once at startup and on demand from an administrative surface. The service owns the operations and their policy, such as which seed set applies at startup, and none of the content it administers: the migration sets, the seeder with its named sets, the pattern catalog, and the statements registry are the consumer's, passed in at construction.

Construction

New takes four collaborators:

  • the pool's lifecycle object
  • the sqlate session over the same pool
  • the migrator the consumer built over its migration sets
  • the pattern catalog every statement compiles against

Options carries the optional collaborators: a Seeder, a Registry, a logger, and the name of the seed set that applies at startup. A nil required collaborator, or a startup seed set without a seeder, is a wiring defect and panics, per the database package's wiring rule.

Migration sets

One service administers every migration set its migrator runs. The migrator runs one or more sets, each over its own history table, declared bottom-first: a set comes before the sets that build on it, as a library's shipped set comes beneath the consumer's own. A read or a whole-schema operation covers every set in declared order. A verb that targets one set takes its name; an empty or undeclared name is ErrUnknownSet, refused before any I/O. A migrator over one set is the same service with one entry in each report.

Startup

Service.Register declares the service on a lifecycle coordinator at Stage, after the pool at stage 0 and before the domains verify their statements at stage 2. Service.Start verifies every set's history; when migrations are pending, it logs them set by set, applies them under the migrator's lock, and verifies again. It then verifies the seeder's statements and applies the configured seed set when there is one: idempotent, so a deployment initializes its data at its first start and every later start leaves it as it is. A state the mechanism cannot correct — a dirty row, or a history a set does not carry — fails startup. An operator resolves it through the verbs. Service.Ready reports a clean, complete history in every set as of the last operation, so a readiness probe aggregating the service reflects it.

Operations

Every operation is a trigger over a library function:

  • Service.Verify, Service.Status, and Service.Up call the migrator's verb of the same name over every set; Status carries one SetStatus per set.
  • Service.Down, Service.Steps, and Service.Force call the verb of the same name on the set they name. The migrator's ordering holds: a set is not reverted while a set above it has applied migrations, nor applied while a set below it has pending ones.
  • The mutating verbs return the refreshed Status.
  • Service.States lists the seeder's declared names.
  • Service.Seed applies a named seed set, or the configured one, over the schema as it stands.
  • Service.Reset reverts every migration set, the last declared first, dropping each history table; applies every set again; and applies the named state's seed set. It is the one transition that brings a database to a named state from any other.
  • Service.Catalog and Service.Statements read the pattern catalog and the statements registry without I/O.
  • Service.Diagnose pings the pool, reads the server's version through the dialect's Versioner capability when it has one, and reports the pool's counters.

A seed operation without a seeder or a set is ErrSeedDisabled; an undeclared name is ErrUnknownState. Reset is destructive, in the class of Down and Force; the administrative surface decides who may call it and asks for confirmation. The HTTP half, a route group over these methods, is application code.

Dirty-set repair

A non-transactional migration that fails partway leaves its set's head dirty, and every run that writes refuses until the mark is cleared. Force is the repair: the operator fixes the failed migration's objects by hand, forces the named set to the version that is applied, then runs Up. Force touches no schema and checks no history first, since the set it repairs is the dirty one. When a revert is refused partway through, Service.Status reports where each set stands.

Index

Constants

View Source
const Stage = 1

Stage is the lifecycle stage the schema correction runs in: after the pool at stage 0, before the domains verify their statements at stage 2.

Variables

View Source
var (
	// ErrSeedDisabled reports a seed request the service cannot serve: no
	// seeder is wired, or the request names no set and the options
	// configure none.
	ErrSeedDisabled = errors.New("seeding is disabled")

	// ErrValidation classifies a rejected administrative request: a verb
	// argument outside its domain, refused before any I/O.
	ErrValidation = errors.New("validation failed")

	// ErrUnknownState reports a state name the seeder does not declare,
	// refused before any I/O.
	ErrUnknownState = errors.New("unknown state")

	// ErrUnknownSet reports a verb that names no migration set, or one the
	// migrator does not run, refused before any I/O.
	ErrUnknownSet = errors.New("unknown migration set")
)

Functions

This section is empty.

Types

type Catalog

type Catalog struct {
	Namespaces []string  `json:"namespaces"`
	Patterns   []Pattern `json:"patterns"`
}

Catalog is the pattern catalog as an operator reads it: every namespace the composition root registered and every pattern under them, in namespace then name order. It is build-time state; the read has no write.

type Diagnostics

type Diagnostics struct {
	Dialect       string        `json:"dialect"`
	Ping          time.Duration `json:"ping"`
	ServerVersion string        `json:"server_version,omitempty"`
	Pool          Pool          `json:"pool"`
	Namespaces    []string      `json:"namespaces"`
}

Diagnostics is one read of the database's health:

  • the dialect
  • the ping latency
  • the server's version, when the dialect supplies the statement
  • the pool's counters
  • the pattern namespaces the catalog registered

type DomainStatements

type DomainStatements struct {
	Name       string          `json:"name"`
	Statements []StatementInfo `json:"statements"`
}

DomainStatements is one domain's compiled inventory.

type Entry

type Entry struct {
	Name       string
	Statements *query.Statements
}

Entry is one domain's compiled statements, registered under its name.

type Inventory

type Inventory struct {
	Domains []DomainStatements `json:"domains"`
}

Inventory is the statements registry as an operator reads it: every domain that registered its compiled statements, in the registry's order, each statement as the library holds it. Build-time state; no write.

type MigrationInfo

type MigrationInfo struct {
	Version       int    `json:"version"`
	Name          string `json:"name"`
	Transactional bool   `json:"transactional"`
	Applied       bool   `json:"applied"`
}

MigrationInfo describes one migration of a set.

type Options

type Options struct {
	// Seed names the state whose set applies at every startup, once the
	// schema is current, and on a seed request that names no set: the way
	// a deployment initializes its data. Empty applies none at startup. A
	// name without a Seeder is a wiring defect; a name the seeder does not
	// declare is a configuration defect that fails startup.
	Seed string

	// Seeder is the consumer's seed mechanism. nil means the consumer has
	// no sets: Start verifies no seed statements, and Seed and Reset
	// refuse.
	Seeder Seeder

	// Registry is the consumer's statements registry. nil means Statements
	// reports no domains.
	Registry Registry

	// Logger receives the startup narrative. nil is silent.
	Logger *slog.Logger
}

Options holds the collaborators and switches the composition root chooses.

type Pattern

type Pattern struct {
	Namespace string   `json:"namespace"`
	Name      string   `json:"name"`
	Tier      string   `json:"tier"`
	Native    string   `json:"native,omitempty"`
	Slots     []string `json:"slots"`
	Text      string   `json:"text"`
}

Pattern is one catalog entry: its namespace and name, its tier and native note, the slots its body declares, and the body itself, as the library composes or splices it.

type Pool

type Pool struct {
	Open         int           `json:"open"`
	InUse        int           `json:"in_use"`
	Idle         int           `json:"idle"`
	MaxOpen      int           `json:"max_open"`
	WaitCount    int64         `json:"wait_count"`
	WaitDuration time.Duration `json:"wait_duration"`
}

Pool is the connection pool's counters.

type Registry

type Registry interface {
	Registry() []Entry
}

Registry lists the statements every domain registered, in the order the inventory reports them.

type Seeded

type Seeded map[string]int

Seeded counts the rows a seed run inserted, by the consumer's own names.

type Seeder

type Seeder interface {
	Verify(ctx context.Context) error
	States() []string
	Seed(ctx context.Context, state string) (Seeded, error)
}

Seeder is the consumer's seed mechanism over its named sets. A set is the data a deployment or a scenario starts from, declared by the consumer under a state name. Verify prepares the seeder's statements against the schema; States lists the declared names, sorted, without I/O; Seed applies one set idempotently and counts what it inserted.

type Service

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

Service is the database admin service. Every operation is a trigger over the migrator, the session, the seeder, or the catalog; Start runs the same functions the on-demand verbs do. Ready reports a clean, complete schema and follows every operation.

func New

func New(pool *database.DB, db *sqlate.DB, m *migrate.Migrator, c *query.Catalog, opts Options) *Service

New builds the service over its four collaborators:

  • pool, the lifecycle object it administers
  • db, the sqlate session over the same pool
  • m, the migrator the consumer built over its migration sets
  • c, the catalog every statement compiles against

A nil pool, db, m, or c panics, as does an opts.Seed name without opts.Seeder: each is a wiring defect at the composition root.

func (*Service) Catalog

func (s *Service) Catalog() Catalog

Catalog reads the pattern catalog: every namespace and every pattern, so an operator sees a pattern's text, tier, and slots as the library holds them. No I/O.

func (*Service) Diagnose

func (s *Service) Diagnose(ctx context.Context) (Diagnostics, error)

Diagnose reads the database's health: the dialect, a timed ping through the pool's lifecycle object, the server's version when the dialect supplies the statement, and the pool's counters.

func (*Service) Down

func (s *Service) Down(ctx context.Context, set string, n int) (Status, error)

Down reverts the named set's n most recent migrations; n must be positive. A set above it with applied migrations refuses the revert.

func (*Service) Force

func (s *Service) Force(ctx context.Context, set string, version int) (Status, error)

Force sets the named set's history to version, clearing its dirty state; 0 empties it. It never touches the schema and checks no set's history first: it repairs a dirty set once the operator has fixed the failed migration's objects by hand, and Up follows it. It can just as well manufacture a dirty state, since a forced-down history re-applies files against objects that still exist.

func (*Service) Ready

func (s *Service) Ready() bool

Ready reports whether every set's history is its clean head, as of the last operation.

func (*Service) Register

func (s *Service) Register(lc *lifecycle.Coordinator)

Register declares the schema stage on lc: Start corrects the schema and Ready gates readiness on it.

func (*Service) Reset added in v0.5.0

func (s *Service) Reset(ctx context.Context, state string) (Transition, error)

Reset brings the database to the named state: every migration set is reverted, the last declared first, with its history table dropped; every set is applied again in declared order; and the state's seed set is applied, each through the same function the verbs and Start run. The revert and the apply each hold the migrator's lock; the seed runs outside it, as Seed does. The request is refused before any I/O the way Seed refuses; a failure at any step leaves the schema where that step stopped, and the status is still read so Ready reflects it.

func (*Service) Seed

func (s *Service) Seed(ctx context.Context, state string) (Seeded, error)

Seed applies the named set idempotently over the schema as it stands, or the configured set when state is empty. Without a seeder, or with no set named or configured, the request is refused with ErrSeedDisabled; a name the seeder does not declare is refused with ErrUnknownState; both before any I/O.

func (*Service) Start

func (s *Service) Start(ctx context.Context) error

Start brings every set to its head: pending migrations are logged set by set, then applied under the migrator's lock; a clean, complete history passes. A state the mechanism cannot correct — a dirty row, or a history a set does not carry — fails startup. An operator resolves it through the verbs (force the named set, then up) on a process started against a corrected database, or from another replica. The seeder's statements are then verified against the schema, and the configured seed set, when there is one, is applied.

func (*Service) Statements

func (s *Service) Statements() Inventory

Statements reads the statements registry: every domain's compiled inventory, the counterpart of Catalog for authored files. No I/O; no registry reports no domains.

func (*Service) States added in v0.5.0

func (s *Service) States() []string

States lists the state names the seeder declares, sorted; no seeder declares none. No I/O.

func (*Service) Status

func (s *Service) Status(ctx context.Context) (Status, error)

Status reads every set's state, in declared order, and refreshes Ready from it: ready when no set is dirty or pending. A history that cannot be read, or that carries a row its set does not, is an error, and Ready is cleared: the service cannot claim a clean schema it cannot account for.

func (*Service) Steps

func (s *Service) Steps(ctx context.Context, set string, n int) (Status, error)

Steps applies the named set's next n pending migrations when n is positive, or reverts its last -n applied ones when it is negative; zero is rejected. A set below it with pending migrations refuses an apply, and a set above it with applied ones refuses a revert.

func (*Service) Up

func (s *Service) Up(ctx context.Context) (Status, error)

Up applies every pending migration of every set, in declared order, and returns the resulting state.

func (*Service) Verify

func (s *Service) Verify(ctx context.Context) error

Verify checks that every set's history is its clean head and, when it is, that the seeder's statements prepare against the schema; the error names the set or statement that is wrong. Ready follows the result.

type SetStatus added in v0.6.0

type SetStatus struct {
	Name       string          `json:"name"`
	Table      string          `json:"table"`
	Version    int             `json:"version"`
	Latest     int             `json:"latest"`
	Dirty      bool            `json:"dirty"`
	Pending    []int           `json:"pending"`
	Migrations []MigrationInfo `json:"migrations"`
}

SetStatus is one migration set's state:

  • its name and the history table it is recorded in
  • the applied head, the set's latest version, and whether the head is dirty
  • the versions still pending
  • every migration of the set, with whether it is applied

type StatementInfo

type StatementInfo struct {
	Name                string   `json:"name"`
	Tier                string   `json:"tier"`
	Native              string   `json:"native,omitempty"`
	TransactionRequired bool     `json:"transaction_required"`
	Params              []string `json:"params"`
	Key                 string   `json:"key,omitempty"`
	Fields              []string `json:"fields,omitempty"`
	Text                string   `json:"text"`
}

StatementInfo is one compiled statement: its declarations, its parameters in position order, and the text the engine receives.

type Status

type Status struct {
	Ready bool        `json:"ready"`
	Sets  []SetStatus `json:"sets"`
}

Status is the schema's state against every migration set the migrator runs: whether the service reports ready (every set's history clean and complete), and each set's own state in declared order, the set the others build on first.

type Transition added in v0.5.0

type Transition struct {
	State  string `json:"state"`
	Schema Status `json:"schema"`
	Seeded Seeded `json:"seeded"`
}

Transition is the result of a reset to a named state: the state, the schema's status after the set was applied, and the rows the state's set inserted.

type Versioner

type Versioner interface {
	ServerVersion() string
}

Versioner is the optional dialect capability that supplies the statement reading the server's version: one row, one text column. Diagnose asserts it off the session's dialect and omits the version when it is absent.

Jump to

Keyboard shortcuts

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