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; the migration sets, the seeder with its named sets, the pattern catalog, and the statements registry are the consumer's, passed in at construction. A wiring defect panics, per the database package.
Construction ¶
New builds a Service over the pool, its sqlate session, the consumer's migrator, and its pattern catalog. Options carries the optional collaborators, the startup seed set, and the reset hook:
- Seeder is the consumer's seed mechanism over its named sets.
- Registry lists each domain's compiled statements as an Entry.
- Options.OnReset is the consumer's step in Service.Reset, between the apply and the seed.
Versioner is the optional dialect capability that supplies the statement reading the server's version.
Migration sets ¶
One service administers every set its migrator runs, 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. 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.
Startup ¶
The consumer defines the service as a node of its go-core graph. The Service is a lifecycle Starter and ReadinessChecker, so the Coordinator starts it in its layer and lists its readiness among its Checks under the node's name. Its node uses the pool's node, which places it in a layer above the pool, and a node that needs the corrected schema uses the service's node, or orders after it with Scope.After:
schema := g.Define("schema", func(s *graph.Scope) (*admin.Service, error) {
pool := s.Use(db)
session := sqlate.Wrap(pool.Conn(), dialect)
m, err := migrate.New(session, sets, migrate.Options{})
if err != nil {
return nil, err
}
return admin.New(pool, session, m, catalog, opts), nil
})
The Service is not a Stopper: it holds nothing the pool's shutdown does not release.
Service.Start applies pending migrations, verifies the seeder, and applies the configured seed set, idempotently at every start. A dirty set, or a history a set does not carry, fails startup, and a failed Start stops the process, so an operator repairs the schema through the verbs of another replica or starts a process against the corrected database. Service.Ready reports the schema alone, as the last operation that determined it found it; once Start has succeeded, a not-ready service re-verifies at most once per five seconds. A true Ready is not re-checked.
Operations ¶
The schema verbs run the migrator's function of their name, and the seed verbs the seeder's:
- Service.Verify checks every set's history and the seeder's statements.
- Service.Status reads the schema into a Status: one SetStatus per set, and one MigrationInfo per migration.
- Service.Up applies every set's pending migrations.
- Service.Down reverts, Service.Steps applies or reverts, and Service.Force sets the history version of the set each names.
- Service.States lists the seeder's named states.
- Service.Seed applies a state's seed set and returns the rows it Seeded.
- Service.Reset reverts and reapplies every set and seeds a named state, returning a Transition. It is the one transition to a named state from any other.
- Service.Catalog reads the pattern catalog into a Catalog of Pattern values.
- Service.Statements reads the registry into an Inventory of DomainStatements, each listing its StatementInfo values.
- Service.Diagnose reads the database's health into Diagnostics, including the Pool counters.
The mutating verbs return the refreshed Status. Reset, Down, and Force are destructive; the administrative surface, which is application code, decides who may call them.
Errors ¶
A request outside a verb's domain is refused before any I/O: ErrValidation, ErrUnknownSet, ErrUnknownState, or ErrSeedDisabled. An operation the schema's state refuses is ErrConflict, wrapping the migrate sentinel.
Dirty-set repair ¶
A non-transactional migration that fails partway leaves its set dirty, and every write refuses until Service.Force clears it. The operator fixes the failed migration's objects by hand, forces the set to the version that is applied, and runs Service.Up.
Index ¶
- Variables
- type Catalog
- type Diagnostics
- type DomainStatements
- type Entry
- type Inventory
- type MigrationInfo
- type Options
- type Pattern
- type Pool
- type Registry
- type Seeded
- type Seeder
- type Service
- func (s *Service) Catalog() Catalog
- func (s *Service) Diagnose(ctx context.Context) (Diagnostics, error)
- func (s *Service) Down(ctx context.Context, set string, n int) (Status, error)
- func (s *Service) Force(ctx context.Context, set string, version int) (Status, error)
- func (s *Service) Ready() bool
- func (s *Service) Reset(ctx context.Context, state string) (Transition, error)
- func (s *Service) Seed(ctx context.Context, state string) (Seeded, error)
- func (s *Service) Start(ctx context.Context) error
- func (s *Service) Statements() Inventory
- func (s *Service) States() []string
- func (s *Service) Status(ctx context.Context) (Status, error)
- func (s *Service) Steps(ctx context.Context, set string, n int) (Status, error)
- func (s *Service) Up(ctx context.Context) (Status, error)
- func (s *Service) Verify(ctx context.Context) error
- type SetStatus
- type StatementInfo
- type Status
- type Transition
- type Versioner
Constants ¶
This section is empty.
Variables ¶
var ( // ErrSeedDisabled reports a seed request with no seeder wired, or with // no set named or configured. ErrSeedDisabled = errors.New("seeding is disabled") // ErrValidation reports a verb argument outside its domain. ErrValidation = errors.New("validation failed") // ErrUnknownState reports a state name the seeder does not declare. ErrUnknownState = errors.New("unknown state") // ErrUnknownSet reports a set name the migrator does not run. ErrUnknownSet = errors.New("unknown migration set") // ErrConflict reports an operation the schema's state refuses: a dirty // or pending set, a history its set does not carry, a migration with no // down, or a set order the migrator forbids. The migrate sentinel stays // in the chain. ErrConflict = errors.New("schema conflict") )
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, in namespace then name order.
type Diagnostics ¶
type Diagnostics struct {
Dialect string `json:"dialect"`
Ping time.Duration `json:"ping"` // the ping's latency
ServerVersion string `json:"server_version,omitempty"` // empty without a Versioner
Pool Pool `json:"pool"`
Namespaces []string `json:"namespaces"` // the catalog's pattern namespaces
}
Diagnostics is one read of the database's health.
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, in the registry's order.
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 Start applies, and the state Seed and
// Reset use when a request names none. Empty applies none at startup; a
// name the seeder does not declare fails Start before it reads the
// schema.
Seed string
// Seeder is the consumer's seed mechanism; nil refuses Seed and Reset.
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
// OnReset runs once in each Reset, after every set is applied and
// before the state's seed set, with the state Reset resolved. It is the
// consumer's step for what the schema alone does not restore, such as
// state held outside the database. An error stops Reset before the
// seed, leaving the schema applied and unseeded. Start, Seed, and the
// schema verbs never call it. nil skips the step.
OnReset func(ctx context.Context, state string) error
}
Options holds the optional collaborators and the startup seed set.
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 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. Verify prepares its statements against the schema; States lists the declared names, sorted; Seed applies one set idempotently, even when replicas seed it concurrently, and counts what it inserted.
type Service ¶
type Service struct {
// contains filtered or unexported fields
}
Service is the database admin service.
func New ¶
func New(pool *database.DB, db *sqlate.DB, m *migrate.Migrator, c *query.Catalog, opts Options) *Service
New builds the service over the pool, its sqlate session, a migrator, and a catalog. A nil pool, db, migrator, or catalog panics, as does an Options.Seed without an Options.Seeder.
func (*Service) Diagnose ¶
func (s *Service) Diagnose(ctx context.Context) (Diagnostics, error)
Diagnose reads the database's health: a timed ping, the server's version when the dialect is a Versioner, and the pool's counters.
func (*Service) Force ¶
Force sets the named set's history to version, one of its migrations or 0 for none, and clears its dirty mark. It touches no schema and checks no history first, so it can create a broken state as well as clear a dirty one: a version the schema does not match leaves a clean history that misstates the schema.
func (*Service) Ready ¶
Ready reports the schema as the last operation that determined it found it: every set's history clean and current. Once Start has succeeded, a not-ready service re-verifies the schema itself, one probe at a time, at most once per five seconds, and bounded by the pool's conn_timeout. A true Ready is not re-checked.
func (*Service) Reset ¶ added in v0.5.0
Reset reverts every set, applies every set, runs Options.OnReset when one is set, and applies the named state's seed set, or the configured one when state is empty. The revert drops everything the consumer's sets hold, an outbox's unpublished rows included. The revert and the apply each hold the migrator's lock; the hook and the seed run outside it. A failure leaves the schema where its step stopped, and the error names the step: revert, apply, reset hook, or seed.
func (*Service) Seed ¶
Seed applies the named set, or the configured one when state is empty, over the schema as it stands.
func (*Service) Start ¶
Start refuses an undeclared Options.Seed, brings every set to its head (logging the pending migrations first), verifies the seeder's statements, and applies the configured seed set; the service is ready once all pass.
func (*Service) Statements ¶
Statements reads the statements registry: every domain's compiled inventory.
func (*Service) Steps ¶
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.
type SetStatus ¶ added in v0.6.0
type SetStatus struct {
Name string `json:"name"`
Table string `json:"table"` // the history table
Version int `json:"version"` // the applied head
Latest int `json:"latest"` // the set's last migration
Dirty bool `json:"dirty"`
Pending []int `json:"pending"`
Migrations []MigrationInfo `json:"migrations"`
}
SetStatus is one migration set's state.
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 ¶
Status is the schema's state: Ready when every set is clean and current, and each set's state in declared order.
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: the state, the schema's status, and the rows seeded.