sqldb

package
v1.48.7-circular Latest Latest
Warning

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

Go to latest
Published: Jun 30, 2025 License: MPL-2.0 Imports: 44 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ErrUnsupported = errors.New("unsupported operation")

Functions

func IsUsed

func IsUsed(md *meta.Data) bool

IsUsed reports whether the application uses SQL databases at all.

func LoadAppliedVersions

func LoadAppliedVersions(ctx context.Context, conn *sql.Conn, schemaName, migrationsTable string) (map[uint64]bool, error)

func MultiReadCloser

func MultiReadCloser(r ...io.Reader) io.ReadCloser

MultiReadCloser is a helper wrapper which extends the io.MultiReader to also close the underlying closeable readers. It's used by the MetadataSource to append a statement to mark a migration as successful.

func NonSequentialMigrator

func NonSequentialMigrator(ctx context.Context, conn *sql.Conn, mdSource *MetadataSource) (database.Driver, source.Driver, error)

NonSequentialMigrator creates a new migrator that doesn't require migrations to be sequential. It does this by keeping track of applied migrations in a table and using that to determine the current version and which migrations need to be applied. It's effectively extending the logic of the go-migrate library to support non-sequential migrations and is semi-compatible since it's using the same underlying table.

func OneshotProxy

func OneshotProxy(appSlug, envSlug string, role RoleType) (port int, passwd string, err error)

OneshotProxy listens on a random port for a single connection, and proxies that connection to a remote db. It reports the one-time password and port to use. Once a connection has been established, it stops listening.

func RunMigration

func RunMigration(ctx context.Context, dbName string, allowNonSeq bool, conn *sql.Conn, mdSrc *MetadataSource) (err error)

func WaitForConn

func WaitForConn(ctx context.Context, uri string) error

WaitForConn waits for a successful connection to uri to be established.

Types

type Cluster

type Cluster struct {
	ID       ClusterID // cluster ID
	Memfs    bool      // use an in-memory filesystem?
	Password string    // randomly generated password for this cluster

	Roles EncoreRoles // set by Start

	// Ctx is canceled when the cluster is being torn down.
	Ctx context.Context
	// contains filtered or unexported fields
}

Cluster represents a running database Cluster.

func (*Cluster) GetDB

func (c *Cluster) GetDB(name string) (*DB, bool)

GetDB gets the database with the given name.

func (*Cluster) Info

func (c *Cluster) Info(ctx context.Context) (*ClusterInfo, error)

Info reports information about a cluster.

func (*Cluster) IsExternalDB

func (c *Cluster) IsExternalDB(name string) bool

func (*Cluster) Ready

func (c *Cluster) Ready() <-chan struct{}

Ready returns a channel that is closed when the cluster is up and running.

func (*Cluster) Recreate

func (c *Cluster) Recreate(ctx context.Context, appRoot string, databaseNames []string, md *meta.Data) error

Recreate recreates the databases for the given database names. If databaseNames is the nil slice it recreates all databases.

func (*Cluster) Setup

func (c *Cluster) Setup(ctx context.Context, appRoot string, md *meta.Data) error

Setup sets up the given databases.

func (*Cluster) SetupAndMigrate

func (c *Cluster) SetupAndMigrate(ctx context.Context, appRoot string, dbs []*meta.SQLDatabase) error

SetupAndMigrate creates and migrates the given databases.

func (*Cluster) Start

func (c *Cluster) Start(ctx context.Context, tracker *optracker.OpTracker) (*ClusterStatus, error)

Start creates the cluster if necessary and starts it. If the cluster is already running it does nothing.

func (*Cluster) Status

func (c *Cluster) Status(ctx context.Context) (*ClusterStatus, error)

Status reports the cluster's status.

func (*Cluster) Stop

func (c *Cluster) Stop()

type ClusterID

type ClusterID struct {
	NS   *namespace.Namespace
	Type ClusterType
}

ClusterID uniquely identifies a cluster.

func GetClusterID

func GetClusterID(app *apps.Instance, typ ClusterType, ns *namespace.Namespace) ClusterID

type ClusterInfo

type ClusterInfo struct {
	*ClusterStatus

	// Encore contains the roles to use to connect for an Encore app.
	// It is set if and only if the cluster is running.
	Encore EncoreRoles
}

ClusterInfo returns information about a cluster.

type ClusterManager

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

A ClusterManager manages running local sqldb clusters.

func NewClusterManager

func NewClusterManager(driver Driver, apps *apps.Manager, ns *namespace.Manager, secretMgr *secret.Manager) *ClusterManager

NewClusterManager creates a new ClusterManager.

func (*ClusterManager) CanDeleteNamespace

func (cm *ClusterManager) CanDeleteNamespace(ctx context.Context, app *apps.Instance, ns *namespace.Namespace) error

CanDeleteNamespace implements namespace.DeletionHandler.

func (*ClusterManager) Create

func (cm *ClusterManager) Create(ctx context.Context, params *CreateParams) *Cluster

Create creates a database cluster but does not start it. If the cluster already exists it is returned. It does not perform any database migrations.

func (*ClusterManager) DeleteNamespace

func (cm *ClusterManager) DeleteNamespace(ctx context.Context, app *apps.Instance, ns *namespace.Namespace) error

DeleteNamespace implements namespace.DeletionHandler.

func (*ClusterManager) Get

func (cm *ClusterManager) Get(id ClusterID) (*Cluster, bool)

Get retrieves the cluster keyed by id.

func (*ClusterManager) LookupPassword

func (cm *ClusterManager) LookupPassword(password string) (*Cluster, bool)

LookupPassword looks up a cluster based on its password.

func (*ClusterManager) PreauthProxyConn

func (cm *ClusterManager) PreauthProxyConn(client net.Conn, id ClusterID) error

PreauthProxyConn is a pre-authenticated proxy conn directly specifically to the given cluster.

func (*ClusterManager) ProxyConn

func (cm *ClusterManager) ProxyConn(client net.Conn, waitForSetup bool) error

ProxyConn authenticates and proxies a conn to the appropriate database cluster and database. If waitForSetup is true, it will wait for initial setup to complete before proxying the connection.

func (*ClusterManager) Ready

func (cm *ClusterManager) Ready() error

Ready reports whether the cluster manager is ready and all requirements are met.

func (*ClusterManager) ServeProxy

func (cm *ClusterManager) ServeProxy(ln net.Listener) error

ServeProxy serves the database proxy using the given listener.

type ClusterStatus

type ClusterStatus struct {
	// Status is the status of the underlying container.
	Status Status

	// Config is how to connect to the cluster.
	// It is non-nil if Status == Running.
	Config *ConnConfig
}

ClusterStatus represents the status of a database cluster.

func (*ClusterStatus) ConnURI

func (s *ClusterStatus) ConnURI(database string, r Role) string

ConnURI reports the connection URI to connect to the given database in the cluster, authenticating with the given role.

type ClusterType

type ClusterType string
const (
	Run    ClusterType = "run"
	Shadow ClusterType = "shadow"
	Test   ClusterType = "test"
)

func (ClusterType) Memfs

func (ct ClusterType) Memfs() bool

type ConnConfig

type ConnConfig struct {
	// Host is the host address to connect to the database.
	// It is only set when Status == Running.
	Host string

	// Superuser is the role to use to connect as the superuser,
	// for creating and managing Encore databases.
	Superuser    Role
	RootDatabase string // root database to connect to
}

type CreateParams

type CreateParams struct {
	ClusterID ClusterID

	// Memfs, if true, configures the database container to use an
	// in-memory filesystem as opposed to persisting the database to disk.
	Memfs bool

	// Tracker allows tracking the progress of the operation.
	Tracker *optracker.OpTracker
}

CreateParams are the params to (*ClusterManager).Create.

type DB

type DB struct {
	EncoreName string
	Cluster    *Cluster

	// Ctx is canceled when the database is being torn down.
	Ctx context.Context
	// contains filtered or unexported fields
}

DB represents a single database instance within a cluster.

func (*DB) ApplicationCloudName

func (db *DB) ApplicationCloudName() string

ApplicationCloudName reports the "cloud name" of the application-facing database.

func (*DB) CloseConns

func (db *DB) CloseConns()

CloseConns closes all connections to this database through the dbproxy, and prevents future ones from being established.

func (*DB) ListAppliedMigrations

func (db *DB) ListAppliedMigrations(ctx context.Context) (map[uint64]bool, error)

func (*DB) Ready

func (db *DB) Ready() <-chan struct{}

Ready returns a channel that is closed when the database is up and running.

func (*DB) Setup

func (db *DB) Setup(ctx context.Context, appRoot string, dbMeta *meta.SQLDatabase, migrate, recreate bool) (err error)

Setup sets up the database, (re)creating it if necessary and running schema migrations.

func (*DB) TemplateCloudName

func (db *DB) TemplateCloudName() option.Option[string]

TemplateCloudName reports the "cloud name" of the template database, if any.

type Driver

type Driver interface {
	// CreateCluster creates (if necessary) and starts (if necessary) a new cluster using the driver,
	// and returns its status.
	// err is nil if and only if the cluster could not be started.
	CreateCluster(ctx context.Context, p *CreateParams, log zerolog.Logger) (*ClusterStatus, error)

	// CanDestroyCluster reports whether the cluster could be destroyed, if desired.
	// If a Driver doesn't support destroying the cluster it reports ErrUnsupported.
	CanDestroyCluster(ctx context.Context, id ClusterID) error

	// DestroyCluster destroys a cluster with the given id.
	// If a Driver doesn't support destroying the cluster it reports ErrUnsupported.
	DestroyCluster(ctx context.Context, id ClusterID) error

	// DestroyNamespaceData destroys the data associated with a namespace.
	// If a Driver doesn't support destroying data it reports ErrUnsupported.
	DestroyNamespaceData(ctx context.Context, ns *namespace.Namespace) error

	// ClusterStatus reports the current status of a cluster.
	ClusterStatus(ctx context.Context, id ClusterID) (*ClusterStatus, error)

	// CheckRequirements checks whether all the requirements are met
	// to use the driver.
	CheckRequirements(ctx context.Context) error

	// Meta reports driver metadata.
	Meta() DriverMeta
}

A Driver abstracts away how a cluster is actually operated.

type DriverMeta

type DriverMeta struct {
	// ClusterIsolation reports whether clusters are isolated by the driver.
	// If false, database names will be prefixed with the cluster id.
	ClusterIsolation bool
}

type EncoreRoles

type EncoreRoles []Role

EncoreRoles describes the credentials to use when connecting to the cluster as an Encore user.

func (EncoreRoles) Admin

func (roles EncoreRoles) Admin() (Role, bool)

func (EncoreRoles) First

func (roles EncoreRoles) First(typs ...RoleType) (Role, bool)

func (EncoreRoles) Read

func (roles EncoreRoles) Read() (Role, bool)

func (EncoreRoles) Superuser

func (roles EncoreRoles) Superuser() (Role, bool)

func (EncoreRoles) Write

func (roles EncoreRoles) Write() (Role, bool)

type MetadataSource

type MetadataSource struct {
	MigrationReader
	// contains filtered or unexported fields
}

MetadataSource is a source.Driver implementation that keeps a list of migrations retrieved from the Encore metadata. It relies on a MigrationReader to read the migration files.

func NewMetadataSource

func NewMetadataSource(reader MigrationReader, migrations []*meta.DBMigration) *MetadataSource

NewMetadataSource creates a new MetadataSource instance.

func (*MetadataSource) Close

func (src *MetadataSource) Close() error

func (*MetadataSource) First

func (src *MetadataSource) First() (version uint, err error)

func (*MetadataSource) Next

func (src *MetadataSource) Next(version uint) (nextVersion uint, err error)

func (*MetadataSource) Open

func (src *MetadataSource) Open(url string) (source.Driver, error)

func (*MetadataSource) Prev

func (src *MetadataSource) Prev(version uint) (prevVersion uint, err error)

func (*MetadataSource) ReadDown

func (src *MetadataSource) ReadDown(version uint) (r io.ReadCloser, identifier string, err error)

func (*MetadataSource) ReadUp

func (src *MetadataSource) ReadUp(version uint) (r io.ReadCloser, identifier string, err error)

type MigrationReader

type MigrationReader interface {
	Read(*meta.DBMigration) (r io.ReadCloser, err error)
}

MigrationReader is an interface for reading migration files. It has two main implementations: OsMigrationReader and ZipFSMigrationReader.

type OsMigrationReader

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

func NewOsMigrationReader

func NewOsMigrationReader(path string) *OsMigrationReader

The OsMigrationReader reads migrations from the local filesystem.

func (*OsMigrationReader) Read

func (src *OsMigrationReader) Read(m *meta.DBMigration) (r io.ReadCloser, err error)

type Role

type Role struct {
	Type     RoleType
	Username string
	Password string
}

type RoleType

type RoleType string
const (
	RoleSuperuser RoleType = "superuser"
	RoleAdmin     RoleType = "admin"
	RoleWrite     RoleType = "write"
	RoleRead      RoleType = "read"
)

func (RoleType) String

func (r RoleType) String() string

type Status

type Status string

Status represents the status of a container.

const (
	// Running indicates the cluster is running.
	Running Status = "running"
	// Stopped indicates the container exists but is not running.
	Stopped Status = "stopped"
	// NotFound indicates the container does not exist.
	NotFound Status = "notfound"
)

type WebsocketLogicalConn

type WebsocketLogicalConn struct {
	*websocket.Conn
	// contains filtered or unexported fields
}

func (*WebsocketLogicalConn) Cancel

func (c *WebsocketLogicalConn) Cancel(req *pgproxy.CancelData) error

func (*WebsocketLogicalConn) Read

func (c *WebsocketLogicalConn) Read(p []byte) (int, error)

func (*WebsocketLogicalConn) SetDeadline

func (c *WebsocketLogicalConn) SetDeadline(t time.Time) error

func (*WebsocketLogicalConn) Write

func (c *WebsocketLogicalConn) Write(p []byte) (int, error)

Directories

Path Synopsis
Package external implements a cluster driver for an external cluster.
Package external implements a cluster driver for an external cluster.

Jump to

Keyboard shortcuts

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