config

package
v0.11.1 Latest Latest
Warning

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

Go to latest
Published: Sep 18, 2026 License: MIT Imports: 6 Imported by: 0

Documentation

Overview

Package config loads and validates datavase's YAML configuration.

Parsing is deliberately split from file access: Parse works on any io.Reader so the whole validation surface can be tested without touching the filesystem.

Index

Constants

View Source
const (
	DefaultPort       = 3306
	DefaultTunnelPort = 22
	DefaultAutoLimit  = 1000
	DefaultFetchChunk = 500
	DefaultBufferMax  = 50000
)

Default values applied when the corresponding key is absent.

Variables

This section is empty.

Functions

func DefaultPath

func DefaultPath() (string, error)

DefaultPath returns the configuration file location, honouring XDG_CONFIG_HOME when it is set.

func Save added in v0.9.0

func Save(path string, c *Config) error

Save replaces the file at path with c.

The write goes to a temporary file beside it and is renamed into place: a crash or a full disk midway leaves the previous file intact rather than a truncated one that the next run cannot parse. Owner-only, because the file names hosts and accounts inside someone's network.

func Write added in v0.9.0

func Write(w io.Writer, c *Config) error

Write serialises c as YAML.

Types

type Config

type Config struct {
	DataSources []DataSource `yaml:"datasources"`
	Defaults    Defaults     `yaml:"defaults"`

	// Keymap is read and discarded. Earlier versions wrote it, and refusing
	// the whole file over a key that no longer does anything would lock out
	// exactly the people upgrading.
	Keymap map[string]any `yaml:"keymap,omitempty"`
	// contains filtered or unexported fields
}

Config is the root of the configuration file.

func Empty added in v0.9.0

func Empty() *Config

Empty is the configuration of a machine that has none: no datasources, the defaults in force.

func Load

func Load(path string) (*Config, error)

Load reads and validates the configuration file at path.

func Parse

func Parse(r io.Reader) (*Config, error)

Parse reads and validates YAML configuration from r.

Unknown keys are rejected rather than ignored: a typo such as "hots" would otherwise surface much later as a confusing "host is required".

func (*Config) Find

func (c *Config) Find(name string) (*DataSource, error)

Find returns the datasource with the given name.

func (*Config) Ignored added in v0.9.0

func (c *Config) Ignored() []string

Ignored names the top-level keys that were present and did nothing, so the caller can say so once rather than leave a setting silently dead.

func (*Config) Names

func (c *Config) Names() []string

Names lists the configured datasource names in file order.

type DataSource

type DataSource struct {
	Name     string  `yaml:"name"`
	Env      Env     `yaml:"env,omitempty"`
	Host     string  `yaml:"host"`
	Port     int     `yaml:"port"`
	User     string  `yaml:"user"`
	Database string  `yaml:"database,omitempty"`
	Tunnel   *Tunnel `yaml:"tunnel,omitempty"`

	// TLS is how much the connection must prove about the server. Empty means
	// DefaultTLSMode for this datasource's env.
	TLS TLSMode `yaml:"tls"`
	// TLSCA is a PEM file of roots to verify against instead of the system
	// store, for an instance behind a private certificate authority. It is
	// only meaningful under a mode that verifies, and is refused under any
	// other rather than read and ignored.
	TLSCA string `yaml:"tls_ca,omitempty"`

	// ReadOnly has the server refuse every write on this datasource. The
	// server rather than the tokenizer, which classifies statements for the
	// editor and was never meant to be a boundary: a write hidden in a stored
	// procedure or a multi-table syntax it does not know would walk past it.
	ReadOnly bool `yaml:"read_only,omitempty"`
}

DataSource is a single MySQL/MariaDB target. Passwords are never stored here; they live in the OS keychain keyed by Name.

type Defaults

type Defaults struct {
	AutoLimit  int `yaml:"auto_limit"`
	FetchChunk int `yaml:"fetch_chunk"`
	BufferMax  int `yaml:"buffer_max"`

	// Mouse says whether clicks mean anything.
	//
	// Mouse reporting disables the terminal's own text selection, which is a
	// regression for anyone who copies by dragging. Off costs only the ways
	// in: every click reaches an action also bound to a key.
	Mouse *bool `yaml:"mouse,omitempty"`

	// History says whether finished statements are written to the local
	// store. Absent means they are, which is what every configuration
	// written before this key existed meant.
	//
	// It is here rather than per datasource because the file holding them is
	// one file: turning it off for the datasource that matters would leave
	// the statements someone ran against it in the same store as the rest,
	// under a name that says they are not.
	History *bool `yaml:"history,omitempty"`
}

Defaults holds tunables shared by every datasource.

func (Defaults) KeepHistory added in v0.11.0

func (d Defaults) KeepHistory() bool

KeepHistory reports whether finished statements are remembered.

type Env

type Env string

Env is kept from earlier configurations for one reason: an absent "tls:" defaults by it, and dropping that would quietly let a production credential cross the wire in clear text. Nothing else reads it.

const (
	EnvProd  Env = "prod"
	EnvStage Env = "stage"
	EnvDev   Env = "dev"
)

type TLSMode added in v0.2.0

type TLSMode string

TLSMode says how much the connection has to prove about the server before a credential is sent over it. The names match MySQL's own ssl-mode so that what is configured here can be checked against the server.

const (
	// TLSDisabled sends everything in clear text.
	TLSDisabled TLSMode = "disabled"
	// TLSPreferred encrypts when the server offers it and silently does not
	// when it does not, which is why it is not enough for production.
	TLSPreferred TLSMode = "preferred"
	// TLSRequired encrypts or fails, but proves nothing about who answered.
	TLSRequired TLSMode = "required"
	// TLSVerifyCA additionally requires the certificate to chain to a trusted
	// root, without requiring the name on it to match the address dialled.
	TLSVerifyCA TLSMode = "verify-ca"
	// TLSVerifyIdentity additionally requires that name to match.
	TLSVerifyIdentity TLSMode = "verify-identity"
)

func DefaultTLSMode added in v0.2.0

func DefaultTLSMode(env Env) TLSMode

DefaultTLSMode is what an absent "tls:" means.

It follows env because production is where a credential crossing the wire in clear text costs the most, and it is also where the managed databases that refuse plain connections outright live, so "required" is both the safer default and usually the working one. Anywhere else the cost of being wrong is a connection that will not open on a developer's laptop, which is why those get "preferred".

type Tunnel

type Tunnel struct {
	Host     string `yaml:"host"`
	Port     int    `yaml:"port"`
	User     string `yaml:"user"`
	Identity string `yaml:"identity,omitempty"`
}

Tunnel describes an SSH bastion to reach a datasource through.

Jump to

Keyboard shortcuts

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