database

package
v1.13.0-rc.2 Latest Latest
Warning

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

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

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ErrSchemaOutOfDate = errors.New("database schema is out of date")

ErrSchemaOutOfDate is returned by Migrator.Check when the database has not been migrated to the version this binary expects.

Functions

func ConnectWithRetry

func ConnectWithRetry(
	ctx context.Context,
	connString string,
	applicationName string,
	timeout time.Duration,
) (*pgxpool.Pool, error)

ConnectWithRetry opens a pool as NewPool does, but keeps retrying while the database is unreachable or still starting, until it accepts a connection or timeout elapses. Components start before the database is ready more often than not, so those failures are expected rather than fatal. Anything else, such as a malformed connection string, a wrong password, or a database that does not exist, will not fix itself and fails immediately.

func NewPool

func NewPool(
	ctx context.Context,
	connString string,
	applicationName string,
) (*pgxpool.Pool, error)

NewPool opens a connection pool for the database at connString, which may be a URL or a key/value DSN, and confirms it can reach the database before returning. Every connection in the pool reports applicationName to the server so that its sessions can be told apart from other components' in pg_stat_activity and in lock-wait logs, and every operation issued through the pool records an OpenTelemetry span.

Types

type Config

type Config struct {
	// URL is a complete connection string, for example
	// postgres://user:password@host:5432/dbname?sslmode=require.
	URL string `envconfig:"DATABASE_URL"`
	// Host is the database server's host name, used when URL is empty.
	Host string `envconfig:"DATABASE_HOST"`
	// Port is the database server's port, used when URL is empty.
	Port int `envconfig:"DATABASE_PORT" default:"5432"`
	// Name is the database to connect to, used when URL is empty.
	Name string `envconfig:"DATABASE_NAME" default:"kargo"`
	// User is the user to connect as, used when URL is empty.
	User string `envconfig:"DATABASE_USER" default:"kargo"`
	// Password is the user's password, used when URL is empty.
	Password string `envconfig:"DATABASE_PASSWORD"`
	// SSLMode is the libpq sslmode to use, used when URL is empty.
	SSLMode string `envconfig:"DATABASE_SSL_MODE" default:"disable"`
	// ConnectTimeout bounds how long to keep retrying the first connection.
	// The database may still be starting when a component does, so being
	// unreachable or not ready is retried rather than treated as fatal until
	// this elapses. Errors that cannot clear on their own, such as a rejected
	// password, are not retried.
	ConnectTimeout time.Duration `envconfig:"DATABASE_CONNECT_TIMEOUT" default:"5m"`
	// MigrationLockTimeout bounds how long a migration run waits for another
	// run to release the lock on the schema before giving up. It must be
	// longer than the slowest migration, since that is exactly what a waiting
	// runner is waiting on.
	MigrationLockTimeout time.Duration `envconfig:"DATABASE_MIGRATION_LOCK_TIMEOUT" default:"1h"`
}

Config represents how a component reaches the database. Either URL is set, which is used verbatim, or the individual fields are, from which a connection string is composed with the password properly escaped. The Helm chart uses the individual fields for the bundled PostgreSQL, since it cannot escape a password it reads from a Secret, and URL for an external database whose Secret already holds a complete connection string.

func ConfigFromEnv

func ConfigFromEnv() Config

ConfigFromEnv returns a Config populated from environment variables.

func (Config) Configured

func (c Config) Configured() bool

Configured returns true when the Config names a database, by URL or by host. Components treat an unconfigured database as a feature switch: the functionality that needs it stays off rather than failing to start.

func (Config) ConnString

func (c Config) ConnString() (string, error)

ConnString returns the connection string described by the Config.

type DBTX

type DBTX interface {
	Exec(context.Context, string, ...interface{}) (pgconn.CommandTag, error)
	Query(context.Context, string, ...interface{}) (pgx.Rows, error)
	QueryRow(context.Context, string, ...interface{}) pgx.Row
}

type DeleteReplacedProjectParams

type DeleteReplacedProjectParams struct {
	Name string
	ID   string
}

type Migrator

type Migrator interface {
	// Up applies every pending migration in order and returns the versions
	// it applied. It holds a session-level advisory lock, keyed on the schema
	// being migrated, for the duration, so concurrent runners against the
	// same schema wait for one another instead of racing. It is safe to call
	// when nothing is pending.
	Up(ctx context.Context) ([]int64, error)
	// Version returns the version the database is at and the version this
	// binary's migrations reach.
	Version(ctx context.Context) (current int64, target int64, err error)
	// Check returns ErrSchemaOutOfDate if the database is behind the version
	// this binary expects. Components that read the database should call it at
	// startup and refuse to serve until it passes, so that new code never runs
	// against an old schema.
	Check(ctx context.Context) error
}

Migrator applies and inspects the database schema migrations embedded in this binary.

func NewMigrator

func NewMigrator(
	ctx context.Context,
	pool *pgxpool.Pool,
	migrations fs.FS,
	lockTimeout time.Duration,
) (Migrator, error)

NewMigrator returns a Migrator that applies the given migrations through the pool. Migrations run through pgx's database/sql adapter, so the pool's tracer sees them like any other query. lockTimeout bounds how long Up waits for a concurrent run to release the schema's lock; it must exceed the slowest migration, which is what a waiting run is waiting on.

type ProjectRow

type ProjectRow struct {
	ID        string
	Name      string
	CreatedAt time.Time
	SyncedAt  time.Time
}

type Queries

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

func New

func New(db DBTX) *Queries

func (*Queries) DeleteProjectByName

func (q *Queries) DeleteProjectByName(ctx context.Context, name string) error

func (*Queries) DeleteReplacedProject

func (q *Queries) DeleteReplacedProject(ctx context.Context, arg DeleteReplacedProjectParams) error

A Project is its namespace, and deleting it deletes everything in it. A Project deleted and recreated under the same name arrives with a new UID while its old row may still hold the name. Run this before UpsertProject to delete that row, so every row that references the old Project cascades away with it instead of carrying over to the new one.

func (*Queries) ListProjects

func (q *Queries) ListProjects(ctx context.Context) ([]ProjectRow, error)

func (*Queries) UpsertProject

func (q *Queries) UpsertProject(ctx context.Context, arg UpsertProjectParams) error

func (*Queries) WithTx

func (q *Queries) WithTx(tx pgx.Tx) *Queries

type UpsertProjectParams

type UpsertProjectParams struct {
	ID        string
	Name      string
	CreatedAt time.Time
}

Jump to

Keyboard shortcuts

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