Documentation
¶
Overview ¶
Package dbdir is the local-only binding a migrations folder remembers: which managed database it targets, on which instance and organization.
WHY THIS IS NOT A COMMITTED ronja.json. The workflow folder's manifest is committed on purpose — it describes the workflow itself, and a colleague who clones the repo should get it. A migrations folder has no such content to share: the .sql files ARE the shareable part, and all that is left is one id pointing at one organization's database, which is exactly the thing that differs per person.
It would also collide. wfdir.FindRoot walks up from the working directory looking for a ronja.json, and wfdir.LoadManifest refuses one whose kind is not "workflow". A committed ronja.json with kind "database" at a repository root would therefore break every `ronja wf` command run anywhere beneath it, and a workflow manifest sitting above a migrations/ folder would break `db migrate`. Sharing that file needs the manifest layer split properly, which is worth doing when there is something worth sharing — and is not worth coupling to this.
So: .ronja/database.json, git-ignored like the workflow baseline beside it, holding nothing that cannot be re-derived by passing --database once.
Index ¶
Constants ¶
const DirName = ".ronja"
DirName is the local-only state directory, shared with the workflow commands.
const FileName = "database.json"
FileName is the binding file inside it.
const MigrationsDir = "migrations"
MigrationsDir is the folder `db migrate` reads .sql files from.
Variables ¶
This section is empty.
Functions ¶
func ReadMigrations ¶
ReadMigrations loads migrations/*.sql from dir, in filename order.
The name of a migration is its filename STEM — 0001_leads.sql is the migration "0001_leads" — so the file you can see in a diff is the thing the ledger records, with no separate manifest to fall out of step with it.
Order is lexical by filename, which is why the conventional zero-padded prefix matters: 10_x.sql sorts before 9_x.sql, and a set applied in the wrong order fails at the database rather than quietly doing the wrong thing. That is a footgun worth naming rather than hiding behind a natural sort, because the ledger records what ran and re-ordering after the fact is drift.
The SQL is read VERBATIM — no trimming, no newline normalisation. The server's ledger hash covers exactly these bytes, so a client that tidied them would make the same file hash differently from the way it was applied, and every applied migration would report as drifted forever after.
Types ¶
type Binding ¶
type Binding struct {
Instances []Instance `json:"instances"`
}
Binding is .ronja/database.json.
Keyed by (instance, organization) through wfdir.InstanceKey — the SAME reason it is keyed that way for workflows applies verbatim here: a managed database id belongs to exactly one organization, and a person in two organizations on one instance would otherwise have the second overwrite the first's binding and then send one organization's id under the other's token.
func Load ¶
Load reads the binding file. A missing file is an EMPTY binding, not an error: a folder that has never been pushed is a normal state, and --database is always accepted.
func (*Binding) DatabaseFor ¶
func (b *Binding) DatabaseFor(want wfdir.InstanceKey) (string, error)
DatabaseFor returns the database id bound for want, or "" if none is.
The ErrAmbiguousInstance case is passed through rather than guessed at: a folder bound to two organizations on one instance, consulted while signed out, has no right answer, and picking one would send a migration set at whichever database won a coin flip.