postgresql

package
v0.9.2 Latest Latest
Warning

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

Go to latest
Published: Jul 30, 2026 License: MIT Imports: 15 Imported by: 0

Documentation

Index

Constants

View Source
const AllSchemas = "*"

AllSchemas selects every non-system schema in the database

Variables

This section is empty.

Functions

func OpenDatabase added in v0.5.0

func OpenDatabase(connUrl string, databaseName string) (*sql.DB, error)

Types

type Database

type Database struct {
	Name               string `json:"name"`
	Owner              string `json:"owner"`
	Template           string `json:"template"`
	Encoding           string `json:"encoding"`
	Collation          string `json:"collation"`
	LcCtype            string `json:"lcCtype"`
	TablespaceName     string `json:"tablespaceName"`
	ConnectionLimit    int    `json:"connectionLimit"`
	IsTemplate         bool   `json:"isTemplate"`
	DisableConnections bool   `json:"disableConnections"`

	// Do not error if trying to create a database that already exists
	// Instead, read the existing and return
	UseExisting bool `json:"useExisting"`
}

func (Database) Key added in v0.7.0

func (d Database) Key() string

type Databases added in v0.5.0

type Databases struct {
	DbOpener DbOpener
}

func (*Databases) Create added in v0.5.0

func (d *Databases) Create(obj Database) (*Database, error)

func (*Databases) Drop added in v0.5.0

func (d *Databases) Drop(key string) (bool, error)

func (*Databases) Read added in v0.5.0

func (d *Databases) Read(key string) (*Database, error)

func (*Databases) Update added in v0.5.0

func (d *Databases) Update(key string, obj Database) (*Database, error)

type DbInfo

type DbInfo struct {
	DbVersion         semver.Version
	SupportedFeatures Features
	IsSuperuser       bool
	CurrentUser       string
}

func CalcDbConnectionInfo

func CalcDbConnectionInfo(db *sql.DB) (*DbInfo, error)

type DbOpener added in v0.5.6

type DbOpener interface {
	OpenDatabase(dbName string) (*sql.DB, error)
}

type DefaultGrant added in v0.5.0

type DefaultGrant struct {
	Id       string `json:"id"`
	Role     string `json:"role"`
	Target   string `json:"target"`
	Database string `json:"database"`
}

DefaultGrant defines a template of privileges that Role will be granted to Database This grants default privileges on schema objects created by Role in Database to Target

func (DefaultGrant) Key added in v0.5.0

func (g DefaultGrant) Key() DefaultGrantKey

func (*DefaultGrant) SetId added in v0.5.0

func (g *DefaultGrant) SetId()

type DefaultGrantKey added in v0.5.0

type DefaultGrantKey struct {
	Role     string
	Target   string
	Database string
}

type DefaultGrants added in v0.5.0

type DefaultGrants struct {
	DbOpener DbOpener
}

func (*DefaultGrants) Create added in v0.5.0

func (g *DefaultGrants) Create(grant DefaultGrant) (*DefaultGrant, error)

func (*DefaultGrants) Drop added in v0.5.0

func (g *DefaultGrants) Drop(key DefaultGrantKey) (bool, error)

func (*DefaultGrants) Read added in v0.5.0

func (*DefaultGrants) Update added in v0.5.0

func (g *DefaultGrants) Update(key DefaultGrantKey, grant DefaultGrant) (*DefaultGrant, error)

type FeatureName

type FeatureName uint
const (
	FeatureCreateRoleWith FeatureName = iota
	FeatureDBAllowConnections
	FeatureDBIsTemplate
	FeatureFallbackApplicationName
	FeatureRLS
	FeatureSchemaCreateIfNotExist
	FeatureReplication
	FeatureExtension
	FeaturePrivileges
	FeatureForceDropDatabase
	FeaturePid
	FeatureReplicationSlot
	FeaturePublication
	FeaturePublicationSchema
	FeatureRoleInheritOption
)

type Features

type Features map[FeatureName]bool

func CalcSupportedFeatures

func CalcSupportedFeatures(dbVersion semver.Version) Features

func (Features) IsSupported

func (f Features) IsSupported(name FeatureName) bool

type NoopRevoker added in v0.1.1

type NoopRevoker struct {
}

func (NoopRevoker) Revoke added in v0.1.1

func (t NoopRevoker) Revoke(db *sql.DB) error

type Publication added in v0.9.0

type Publication struct {
	Name     string `json:"name"`
	Database string `json:"database"`

	AllTables bool               `json:"allTables"`
	Schemas   []string           `json:"schemas"`
	Tables    []PublicationTable `json:"tables"`

	// Do not error if trying to create a publication that already exists
	// Instead, reconcile the existing publication's membership and return
	UseExisting bool `json:"useExisting"`
}

Publication defines a postgres publication -- the set of tables that a logical replication consumer receives

A publication selects its tables in one of three ways:

  • AllTables: `FOR ALL TABLES` -- every table in every schema, including tables created later
  • Schemas: `FOR TABLES IN SCHEMA <schema>` -- every table in the schema, including tables created later (postgres 15+)
  • Tables: `FOR TABLE <schema>.<table>` -- only the listed tables

Schemas and Tables can be combined; AllTables cannot be combined with either.

func (Publication) Key added in v0.9.0

func (p Publication) Key() PublicationKey

type PublicationKey added in v0.9.0

type PublicationKey struct {
	Database string
	Name     string
}

type PublicationTable added in v0.9.0

type PublicationTable struct {
	Schema string `json:"schema"`
	Name   string `json:"name"`
}

func (PublicationTable) String added in v0.9.0

func (t PublicationTable) String() string

type Publications added in v0.9.0

type Publications struct {
	DbOpener DbOpener
}

func (*Publications) Create added in v0.9.0

func (p *Publications) Create(obj Publication) (*Publication, error)

func (*Publications) Drop added in v0.9.0

func (p *Publications) Drop(key PublicationKey) (bool, error)

func (*Publications) Read added in v0.9.0

func (p *Publications) Read(key PublicationKey) (*Publication, error)

func (*Publications) Update added in v0.9.0

func (p *Publications) Update(key PublicationKey, obj Publication) (*Publication, error)

Update reconciles the publication's membership using `ALTER PUBLICATION ... ADD|DROP` The publication is never dropped and recreated: recreating invalidates any active subscription

type ReplicationSlot added in v0.9.0

type ReplicationSlot struct {
	Name     string `json:"name"`
	Database string `json:"database"`
	// Plugin is the logical decoding output plugin, defaults to `pgoutput`
	Plugin string `json:"plugin"`

	// Active reports whether a consumer is currently streaming from this slot (read-only)
	Active bool `json:"active"`

	// Do not error if trying to create a slot that already exists
	// Instead, read the existing and return
	UseExisting bool `json:"useExisting"`
}

ReplicationSlot defines a logical replication slot that a consumer (e.g. Datastream) reads changes from

A slot is bound to a single database and retains WAL until its consumer has acknowledged it. An orphaned slot retains WAL forever, which eventually fills the instance disk -- Drop really drops the slot.

func (ReplicationSlot) Key added in v0.9.0

type ReplicationSlotKey added in v0.9.0

type ReplicationSlotKey struct {
	Database string
	Name     string
}

type ReplicationSlots added in v0.9.0

type ReplicationSlots struct {
	DbOpener DbOpener
}

func (*ReplicationSlots) Create added in v0.9.0

func (*ReplicationSlots) Drop added in v0.9.0

Drop really drops the slot Unlike the other resources in this api, leaving a logical replication slot behind is not harmless: the slot pins WAL indefinitely and will eventually fill the instance's disk

func (*ReplicationSlots) Read added in v0.9.0

func (*ReplicationSlots) Update added in v0.9.0

Update cannot alter a slot -- postgres offers no way to change a slot's plugin or database It exists to ensure the slot is present and to report its current state

type Revoker added in v0.1.1

type Revoker interface {
	Revoke(db *sql.DB) error
}

func GrantRoleMembership added in v0.1.1

func GrantRoleMembership(db *sql.DB, role string, info *DbInfo) (Revoker, error)

GrantRoleMembership grants role membership of the target 'role' to the current user This is used to perform commands if user is not a superuser For instance, when using AWS RDS, user is not given superuser It returns a nil Revoker if the grant is not needed because the user already has the role's privileges.

func GrantRoleMemberships added in v0.9.1

func GrantRoleMemberships(db *sql.DB, roles []string, info *DbInfo) (Revoker, error)

GrantRoleMemberships acquires the privileges of every role in 'roles' at once

This takes the advisory lock once for the whole batch. Granting the roles one at a time would deadlock: each grant locks the same key (the current user), and the lock is held until its membership is revoked.

Membership errors are returned alongside a Revoker for whatever was acquired: the caller usually only cares about them if the statement it is about to run fails.

type Role

type Role struct {
	Name     string `json:"name"`
	Password string `json:"password"`
	// Do not error if trying to create a role that already exists
	// Instead, read the existing, set the password, and return
	UseExisting bool `json:"useExisting"`
	// SkipPasswordUpdate informs Create to skip updating the role's password if the role already exists
	SkipPasswordUpdate bool `json:"-"`

	MemberOf   []string       `json:"memberOf"`
	Attributes RoleAttributes `json:"attributes"`
}

func (Role) Key added in v0.7.0

func (r Role) Key() string

type RoleAttributes added in v0.6.0

type RoleAttributes struct {
	CreateDb   bool `json:"createDb"`
	CreateRole bool `json:"createRole"`
	// Replication allows the role to initiate streaming replication and to create/drop replication slots
	// This is required for logical replication consumers (e.g. Datastream)
	Replication bool `json:"replication"`
}

type RoleMember added in v0.5.0

type RoleMember struct {
	// Member receives all the permissions for Target
	Member string `json:"member"`

	// Target is the role that gains an additional Member
	Target string `json:"target"`

	// WithAdminOption permits Member to grant it to others
	WithAdminOption bool `json:"withAdminOption"`

	// Do not error if trying to create a role membership that already exists
	// Instead, return the existing
	UseExisting bool `json:"useExisting"`
}

RoleMember adds Member to the Target role

func (RoleMember) Key added in v0.7.0

func (r RoleMember) Key() RoleMemberKey

type RoleMemberKey added in v0.5.0

type RoleMemberKey struct {
	Member string
	Target string
}

type RoleMembers added in v0.5.0

type RoleMembers struct {
	DbOpener DbOpener
}

func (*RoleMembers) Create added in v0.5.0

func (r *RoleMembers) Create(membership RoleMember) (*RoleMember, error)

func (*RoleMembers) Drop added in v0.5.0

func (r *RoleMembers) Drop(key RoleMemberKey) (bool, error)

func (*RoleMembers) Read added in v0.5.0

func (r *RoleMembers) Read(key RoleMemberKey) (*RoleMember, error)

func (*RoleMembers) Update added in v0.5.0

func (r *RoleMembers) Update(key RoleMemberKey, membership RoleMember) (*RoleMember, error)

type Roles added in v0.5.0

type Roles struct {
	DbOpener DbOpener
}

func (*Roles) Create added in v0.5.0

func (r *Roles) Create(role Role) (*Role, error)

func (*Roles) Drop added in v0.5.0

func (r *Roles) Drop(key string) (bool, error)

func (*Roles) Read added in v0.5.0

func (r *Roles) Read(key string) (*Role, error)

func (*Roles) Update added in v0.5.0

func (r *Roles) Update(key string, role Role) (*Role, error)

type SchemaPrivilege added in v0.5.0

type SchemaPrivilege struct {
	Role     string `json:"role"`
	Database string `json:"database"`
}

SchemaPrivilege grants to Role on Database

CREATE|USAGE on public schema
CREATE|CONNECT|TEMPORARY on database

func (SchemaPrivilege) Key added in v0.5.0

type SchemaPrivilegeKey added in v0.5.0

type SchemaPrivilegeKey struct {
	Role     string
	Database string
}

type SchemaPrivileges added in v0.5.0

type SchemaPrivileges struct {
	DbOpener DbOpener
}

func (*SchemaPrivileges) Create added in v0.5.0

func (*SchemaPrivileges) Drop added in v0.5.0

func (*SchemaPrivileges) Read added in v0.5.0

func (*SchemaPrivileges) Update added in v0.5.0

type Settings added in v0.9.0

type Settings struct {
	Version     string `json:"version"`
	CurrentUser string `json:"currentUser"`
	IsSuperuser bool   `json:"isSuperuser"`

	// WalLevel is `logical` when logical replication is available
	// On cloud sql, this is controlled by the `cloudsql.logical_decoding` database flag (requires an instance restart)
	WalLevel string `json:"walLevel"`

	MaxReplicationSlots  int `json:"maxReplicationSlots"`
	MaxWalSenders        int `json:"maxWalSenders"`
	UsedReplicationSlots int `json:"usedReplicationSlots"`
}

Settings reports the server configuration that callers need to know before they attempt logical replication

This is exposed over the api (`GET /settings`) so that infrastructure modules can detect a misconfigured instance up front instead of failing later with an opaque error from postgres or from a replication consumer.

func ReadSettings added in v0.9.0

func ReadSettings(db *sql.DB) (*Settings, error)

func (Settings) LogicalReplicationEnabled added in v0.9.0

func (s Settings) LogicalReplicationEnabled() bool

LogicalReplicationEnabled reports whether the server can support logical replication slots

type SettingsReader added in v0.9.0

type SettingsReader struct {
	DbOpener DbOpener
}

func (*SettingsReader) Read added in v0.9.0

func (r *SettingsReader) Read() (*Settings, error)

type Store added in v0.5.0

type Store struct {
	Databases        *Databases
	Roles            *Roles
	RoleMembers      *RoleMembers
	DefaultGrants    *DefaultGrants
	SchemaPrivileges *SchemaPrivileges
	TablePrivileges  *TablePrivileges
	Publications     *Publications
	ReplicationSlots *ReplicationSlots
	Settings         *SettingsReader

	sync.Mutex
	// contains filtered or unexported fields
}

func NewStore added in v0.5.0

func NewStore(connUrl string) *Store

func (*Store) Close added in v0.5.6

func (s *Store) Close()

func (*Store) ConnectionUrl added in v0.6.0

func (s *Store) ConnectionUrl() string

func (*Store) OpenDatabase added in v0.5.6

func (s *Store) OpenDatabase(dbName string) (*sql.DB, error)

type TablePrivilege added in v0.9.0

type TablePrivilege struct {
	Id       string `json:"id"`
	Database string `json:"database"`
	// Schema is the schema to grant on, or `*` for every non-system schema in the database
	Schema string `json:"schema"`
	Role   string `json:"role"`

	// Privileges defaults to `["SELECT"]`
	Privileges []string `json:"privileges"`

	// IncludeFuture also grants the privileges on tables created later, via ALTER DEFAULT PRIVILEGES
	IncludeFuture bool `json:"includeFuture"`
	// FutureFromRoles lists the roles whose future tables are covered by IncludeFuture
	// Default privileges only apply to objects created by a specific role, so covering an application's future tables
	// requires naming the role that creates them -- an empty list only covers tables created by the admin user itself
	FutureFromRoles []string `json:"futureFromRoles"`
	// FutureFromTableOwners adds every role that currently owns a table in the schema to FutureFromRoles
	FutureFromTableOwners bool `json:"futureFromTableOwners"`

	// GrantConnect also grants CONNECT on the database
	GrantConnect bool `json:"grantConnect"`
}

TablePrivilege grants table-level access on a schema to Role

GRANT USAGE ON SCHEMA <schema> TO <role>
GRANT <privileges> ON ALL TABLES IN SCHEMA <schema> TO <role>
ALTER DEFAULT PRIVILEGES [FOR ROLE ...] IN SCHEMA <schema> GRANT <privileges> ON TABLES TO <role>

Unlike SchemaPrivilege -- which grants full access so an application can own and modify its schema -- this grants a specific (typically read-only) set of privileges, e.g. for a replication consumer.

func (TablePrivilege) Key added in v0.9.0

func (*TablePrivilege) SetId added in v0.9.0

func (p *TablePrivilege) SetId()

type TablePrivilegeKey added in v0.9.0

type TablePrivilegeKey struct {
	Database string
	Schema   string
	Role     string
}

type TablePrivileges added in v0.9.0

type TablePrivileges struct {
	DbOpener DbOpener
}

func (*TablePrivileges) Create added in v0.9.0

func (*TablePrivileges) Drop added in v0.9.0

func (t *TablePrivileges) Drop(key TablePrivilegeKey) (bool, error)

func (*TablePrivileges) Read added in v0.9.0

func (*TablePrivileges) Update added in v0.9.0

type TempGrant

type TempGrant struct {
	Tx          *sql.Tx
	Role        string
	CurrentUser string
}

func (TempGrant) Revoke

func (t TempGrant) Revoke(db *sql.DB) error

Revoke revokes the role *role* from the user *member*. It returns false if the revoke is not needed because the user is not a member of this role.

type TempGrants added in v0.9.1

type TempGrants struct {
	Tx          *sql.Tx
	Roles       []string
	CurrentUser string
}

TempGrants releases a batch of temporary memberships acquired under a single advisory lock

func (TempGrants) Revoke added in v0.9.1

func (t TempGrants) Revoke(db *sql.DB) error

Revoke releases every membership in the batch, continuing past a failure so that one stuck role does not leave the rest of them granted

Jump to

Keyboard shortcuts

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