Documentation
¶
Overview ¶
Package dbschema describes a migration set a rig module carries with it.
rig owns a dozen tables — the identities, the tokens, the file rows, the notifications — and their DDL has to reach a project's database somehow. There are two readings of how. A project can vendor the set, in which case the files land in its own migrations directory and its own history records them; or it can leave each module to apply its own, in which case every set is applied and recorded separately. Both readings need the same facts about a set: where the files are, what order they go in, which tables each one creates, and where it writes down how far it got. That is what this package is, and it is all it is.
It lives in runtime because runtime is the one module every generated application already imports, so a set declared in these terms costs nobody a dependency they did not already have. It deliberately holds no migration engine: applying a set is rig/migrate's job, and a module that carries schema should not thereby carry goose.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Migration ¶
type Migration struct {
// Number is the filename's numeric prefix within this set.
Number int
// Name is the migration's identity, stable across vendoring.
Name string
// Tables are the tables this migration creates.
//
// Written down rather than parsed out of the SQL, so that adding a table to
// the foundation is a decision somebody makes here as well: which side of
// that line a table falls on decides whether rig generates code for it, and
// a heuristic would quietly move one.
//
// Empty for a migration that only alters what an earlier one created, which is
// what most upgrades are. A table belongs to the migration that creates it and
// to no other, so a later ALTER adds nothing here — the column it adds arrives
// through introspection like any other.
Tables []string
}
A Migration is one file in a Set.
Number and Name are separate facts because vendoring renumbers. A set copied into a project's migrations directory is renumbered into that project's sequence, so the number identifies a migration inside its own set and nowhere else. The name identifies it everywhere, which is why a vendored file carries it: `00009_rig_tenancy.sql` is recognisable as this set's `tenancy` however it was numbered on the way in.
type Set ¶
type Set struct {
// Module is the module that owns the set, for a message that has to say
// which one a database is behind.
Module string
// FS holds the files, and Dir names the directory inside it.
FS fs.FS
Dir string
// Table is where this set records how far it has been applied. It is not the
// project's own bookkeeping table and must never be.
Table string
// Migrations are the set's entries, in the order they apply.
Migrations []Migration
}
A Set is one module's migrations: append-only, numbered from one, and recorded in a bookkeeping table of its own.
The private table is what lets the modules be released independently. Two modules sharing one would share one numbering sequence, and two of them adding a migration in the same release would collide on a version number — which goose refuses outright rather than resolves. So the separation is not tidiness. It is the reason three separately tagged modules never have to agree about a number.
func (Set) Read ¶
Read returns a migration's SQL.
The error is a programming mistake rather than a condition to handle: the manifest and the embedded files ship together, so a name in one and not the other is a set that should have failed Set.Validate.
func (Set) Validate ¶
Validate reports a set whose manifest and files disagree.
A set ships both halves in one package, so a name in one and not the other is a mistake that belongs in the owning module's test run rather than in somebody's database. It is also where append-only stops being a convention: numbers start at one, ascend, and never repeat, so an entry inserted between two shipped ones fails here instead of renumbering a migration that has already been applied.
Every module carrying a set is expected to call this in a test of its own. It is not called at run time — a set is a compile-time constant in all but name, and checking it on every start would be paying for a mistake that cannot survive a test run.