db

package
v1.20210103.1 Latest Latest
Warning

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

Go to latest
Published: Jan 3, 2021 License: MIT Imports: 22 Imported by: 11

Documentation

Overview

Package db provides a basic abstraction layer above normal database/sql.

It is not an ORM, and does not seek to replace writing actual sql.

It also includes some helpers to organize creating a connection to a database from a config file or object.

Index

Constants

View Source
const (
	// DefaultEngine is the default database engine.
	DefaultEngine = "pgx" // "postgres"

	// EnvVarDatabaseURL is an environment variable.
	EnvVarDatabaseURL = "DATABASE_URL"
	// EnvVarDBApplicationName is the environment variable used to set the
	// `application_name` configuration parameter in a `lib/pq` connection
	// string.
	//
	// See: https://www.postgresql.org/docs/12/runtime-config-logging.html#GUC-APPLICATION-NAME
	EnvVarDBApplicationName = "DB_APPLICATION_NAME"

	// DefaultHost is the default database hostname, typically used
	// when developing locally.
	DefaultHost = "localhost"
	// DefaultPort is the default postgres port.
	DefaultPort = "5432"
	// DefaultDatabase is the default database to connect to, we use
	// `postgres` to not pollute the template databases.
	DefaultDatabase = "postgres"

	// DefaultSchema is the default schema to connect to
	DefaultSchema = "public"

	// SSLModeDisable is an ssl mode.
	// Postgres Docs: "I don't care about security, and I don't want to pay the overhead of encryption."
	SSLModeDisable = "disable"
	// SSLModeAllow is an ssl mode.
	// Postgres Docs: "I don't care about security, but I will pay the overhead of encryption if the server insists on it."
	SSLModeAllow = "allow"
	// SSLModePrefer is an ssl mode.
	// Postgres Docs: "I don't care about encryption, but I wish to pay the overhead of encryption if the server supports it"
	SSLModePrefer = "prefer"
	// SSLModeRequire is an ssl mode.
	// Postgres Docs: "I want my data to be encrypted, and I accept the overhead. I trust that the network will make sure I always connect to the server I want."
	SSLModeRequire = "require"
	// SSLModeVerifyCA is an ssl mode.
	// Postgres Docs: "I want my data encrypted, and I accept the overhead. I want to be sure that I connect to a server that I trust."
	SSLModeVerifyCA = "verify-ca"
	// SSLModeVerifyFull is an ssl mode.
	// Postgres Docs: "I want my data encrypted, and I accept the overhead. I want to be sure that I connect to a server I trust, and that it's the one I specify."
	SSLModeVerifyFull = "verify-full"

	// DefaultConnectTimeout is the default connect timeout.
	DefaultConnectTimeout = 5 * time.Second

	// DefaultIdleConnections is the default number of idle connections.
	DefaultIdleConnections = 16
	// DefaultMaxConnections is the default maximum number of connections.
	DefaultMaxConnections = 32
	// DefaultMaxLifetime is the default maximum lifetime of driver connections.
	DefaultMaxLifetime = time.Duration(0)
	// DefaultBufferPoolSize is the default number of buffer pool entries to maintain.
	DefaultBufferPoolSize = 1024
)
View Source
const (
	// ErrDestinationNotStruct is an exception class.
	ErrDestinationNotStruct ex.Class = "db: destination object is not a struct"
	// ErrConfigUnset is an exception class.
	ErrConfigUnset ex.Class = "db: config is unset"
	// ErrUnsafeSSLMode is an error indicating unsafe ssl mode in production.
	ErrUnsafeSSLMode ex.Class = "db: unsafe ssl mode in prodlike environment"
	// ErrUsernameUnset is an error indicating there is no username set in a prodlike environment.
	ErrUsernameUnset ex.Class = "db: username is unset in prodlike environment"
	// ErrPasswordUnset is an error indicating there is no password set in a prodlike environment.
	ErrPasswordUnset ex.Class = "db: password is unset in prodlike environment"
	// ErrDurationConversion is the error returned when a duration cannot be
	// converted to multiple of some base (e.g. milliseconds or seconds)
	// without round off.
	ErrDurationConversion ex.Class = "db: cannot convert duration"
	// ErrConnectionAlreadyOpen is an error indicating the db connection was already opened.
	ErrConnectionAlreadyOpen ex.Class = "db: the connection is already opened"
	// ErrConnectionClosed is an error indicating the db connection hasn't been opened.
	ErrConnectionClosed ex.Class = "db: the connection is closed, or is being used before opened"
	// ErrPlanCacheUnset is an error indicating the statement cache is unset.
	ErrPlanCacheUnset ex.Class = "db: the plan cache is unset"
	// ErrPlanCacheKeyUnset is an error indicating the plan cache key is unset.
	ErrPlanCacheKeyUnset ex.Class = "db: the plan cache key is unset"
	// ErrCollectionNotSlice is an error returned by OutMany if the destination is not a slice.
	ErrCollectionNotSlice ex.Class = "db: outmany destination collection is not a slice"
	// ErrInvalidIDs is an error returned by Get if the ids aren't provided.
	ErrInvalidIDs ex.Class = "db: invalid `ids` parameter"
	// ErrNoPrimaryKey is an error returned by a number of operations that depend on a primary key.
	ErrNoPrimaryKey ex.Class = "db: no primary key on object"
	// ErrRowsNotColumnsProvider is returned by `PopulateByName` if you do not pass in `sql.Rows` as the scanner.
	ErrRowsNotColumnsProvider ex.Class = "db: rows is not a columns provider"
	// ErrTooManyRows is returned by Out if there is more than one row returned by the query
	ErrTooManyRows ex.Class = "db: too many rows returned to map to single object"
)
View Source
const (
	// ConnectionNilError is a common error
	ConnectionNilError = "connection is nil"
)
View Source
const (
	QueryFlag = "db.query"
)

Logger flags

Variables

This section is empty.

Functions

func ColumnNamesCSV

func ColumnNamesCSV(object DatabaseMapped) string

ColumnNamesCSV returns a csv of column names.

func Each added in v1.20201204.1

func Each(rows *sql.Rows, consumer RowsConsumer) (err error)

Each iterates over a given result set, calling the rows consumer.

func Error added in v0.3.2

func Error(err error, options ...ex.Option) error

Error returns a new exception by parsing (potentially) a driver error into relevant pieces.

func ExecRowsAffected added in v1.20201204.1

func ExecRowsAffected(i sql.Result, inputErr error) (int64, error)

ExecRowsAffected is a helper for use with .Exec() (sql.Result, error) that returns the rows affected.

func First added in v1.20201204.1

func First(rows *sql.Rows, consumer RowsConsumer) (found bool, err error)

First returns the first result of a result set to a consumer. If there are more than one row in the result, they are ignored.

func IgnoreExecResult added in v1.20201204.1

func IgnoreExecResult(_ sql.Result, err error) error

IgnoreExecResult is a helper for use with .Exec() (sql.Result, error) that ignores the result return.

func IsConfigUnset

func IsConfigUnset(err error) bool

IsConfigUnset returns if the error is an `ErrConfigUnset`.

func IsConnectionClosed

func IsConnectionClosed(err error) bool

IsConnectionClosed returns if the error is an `ErrConnectionClosed`.

func IsDurationConversion added in v1.20201204.1

func IsDurationConversion(err error) bool

IsDurationConversion returns if an error is an `ErrDurationConversion`.

func IsPasswordUnset

func IsPasswordUnset(err error) bool

IsPasswordUnset returns if an error is an `ErrPasswordUnset`.

func IsPlanCacheKeyUnset added in v1.20201204.1

func IsPlanCacheKeyUnset(err error) bool

IsPlanCacheKeyUnset returns if the error is an `ErrPlanCacheKeyUnset`.

func IsPlanCacheUnset added in v1.20201204.1

func IsPlanCacheUnset(err error) bool

IsPlanCacheUnset returns if the error is an `ErrConnectionClosed`.

func IsPopulatable added in v1.20201204.1

func IsPopulatable(object interface{}) bool

IsPopulatable returns if an object is populatable

func IsSkipQueryLogging added in v1.20201204.1

func IsSkipQueryLogging(ctx context.Context) bool

IsSkipQueryLogging returns if we should skip triggering logger listeners for a context.

func IsUnsafeSSLMode

func IsUnsafeSSLMode(err error) bool

IsUnsafeSSLMode returns if an error is an `ErrUnsafeSSLMode`.

func IsUsernameUnset

func IsUsernameUnset(err error) bool

IsUsernameUnset returns if an error is an `ErrUsernameUnset`.

func JSON added in v1.20201204.1

func JSON(obj interface{}) interface{}

JSON returns the json representation of a given object for inserts / updates.

func MakeWhereClause added in v1.20201204.1

func MakeWhereClause(pks *ColumnCollection, startAt int) string

MakeWhereClause returns the sql `where` clause for a column collection, starting at a given index (used in sql $1 parameterization).

func NewQueryEventFilter added in v1.20201204.1

func NewQueryEventFilter(filter func(context.Context, QueryEvent) (QueryEvent, bool)) logger.Filter

NewQueryEventFilter returns a new query event filter.

func NewQueryEventListener added in v1.20201204.1

func NewQueryEventListener(listener func(context.Context, QueryEvent)) logger.Listener

NewQueryEventListener returns a new listener for query events.

func Out added in v1.20201204.1

func Out(rows *sql.Rows, object interface{}) (found bool, err error)

Out reads a given rows set out into an object reference.

func OutMany added in v1.20201204.1

func OutMany(rows *sql.Rows, collection interface{}) (err error)

OutMany reads a given result set into a given collection.

func ParamTokens

func ParamTokens(startAt, count int) string

ParamTokens returns a csv token string in the form "$1,$2,$3...$N" if passed (1, N).

func ParamTokensCSV added in v1.20201204.1

func ParamTokensCSV(num int) string

ParamTokensCSV returns a csv token string in the form "$1,$2,$3...$N"

func ParseURL added in v1.20201204.1

func ParseURL(databaseURL string) (string, error)

ParseURL no longer needs to be used by clients of this library since supplying a URL as a connection string to sql.Open() is now supported:

sql.Open("postgres", "postgres://bob:secret@1.2.3.4:5432/mydb?sslmode=verify-full")

It remains exported here for backwards-compatibility.

ParseURL converts a url to a connection string for driver.Open. Example:

"postgres://bob:secret@1.2.3.4:5432/mydb?sslmode=verify-full"

converts to:

"user=bob password=secret host=1.2.3.4 port=5432 dbname=mydb sslmode=verify-full"

A minimal example:

"postgres://"

This will be blank, causing driver.Open to use all of the defaults

func PopulateByName

func PopulateByName(object interface{}, row Rows, cols *ColumnCollection) error

PopulateByName sets the values of an object from the values of a sql.Rows object using column names.

func PopulateInOrder

func PopulateInOrder(object DatabaseMapped, row Scanner, cols *ColumnCollection) (err error)

PopulateInOrder sets the values of an object in order from a sql.Rows object. Only use this method if you're certain of the column order. It is faster than populateByName. Optionally if your object implements Populatable this process will be skipped completely, which is even faster.

func ReflectSliceType added in v1.20201204.1

func ReflectSliceType(collection interface{}) reflect.Type

ReflectSliceType returns the inner type of a slice following pointers.

func ReflectType added in v1.20201204.1

func ReflectType(obj interface{}) reflect.Type

ReflectType retruns the reflect.Type for an object following pointers.

func ReflectValue added in v1.20201204.1

func ReflectValue(obj interface{}) reflect.Value

ReflectValue returns the reflect.Value for an object following pointers.

func Scan added in v1.20201204.1

func Scan(rows *sql.Rows, args ...interface{}) (found bool, err error)

Scan reads the first row from a resultset and scans it to a given set of args. If more than one row is returned it will return ErrTooManyRows.

func TableName

func TableName(obj DatabaseMapped) string

TableName returns the mapped table name for a given instance; it will sniff for the `TableName()` function on the type.

func TableNameByType

func TableNameByType(t reflect.Type) string

TableNameByType returns the table name for a given reflect.Type by instantiating it and calling o.TableName(). The type must implement DatabaseMapped or an exception will be returned.

func WithConnection added in v1.20201204.1

func WithConnection(ctx context.Context, conn *Connection) context.Context

WithConnection adds a given connection to the context.

func WithSkipQueryLogging added in v1.20201204.1

func WithSkipQueryLogging(ctx context.Context) context.Context

WithSkipQueryLogging sets the context to skip logger listener triggers.

func Zero added in v1.20201204.1

func Zero(object interface{}) error

Zero resets an object.

Types

type Annotations

type Annotations = map[string]string

Annotations is a loose type alias to map[string]string.

type Any

type Any = interface{}

Any is a loose type alias to interface{}

type Column

type Column struct {
	Parent       *Column
	TableName    string
	FieldName    string
	FieldType    reflect.Type
	ColumnName   string
	Index        int
	IsPrimaryKey bool
	IsUniqueKey  bool
	IsAuto       bool
	IsReadOnly   bool
	IsJSON       bool
	Inline       bool
}

Column represents a single field on a struct that is mapped to the database.

func NewColumnFromFieldTag

func NewColumnFromFieldTag(field reflect.StructField) *Column

NewColumnFromFieldTag reads the contents of a field tag, ex: `json:"foo" db:"bar,isprimarykey,isserial"

func (Column) GetValue

func (c Column) GetValue(object DatabaseMapped) interface{}

GetValue returns the value for a column on a given database mapped object.

func (Column) SetValue

func (c Column) SetValue(object, value interface{}) error

SetValue sets the field on a database mapped object to the instance of `value`.

func (Column) SetValueReflected added in v1.20201204.1

func (c Column) SetValueReflected(objectValue reflect.Value, value interface{}) error

SetValueReflected sets the field on a reflect value object to the instance of `value`.

type ColumnCollection

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

ColumnCollection represents the column metadata for a given struct.

func Columns

func Columns(object DatabaseMapped) *ColumnCollection

Columns returns the cached column metadata for an object.

func ColumnsFromType added in v1.20210103.1

func ColumnsFromType(identifier string, t reflect.Type) *ColumnCollection

ColumnsFromType reflects a reflect.Type into a column collection. The results of this are cached for speed.

func NewColumnCollection

func NewColumnCollection(columns ...Column) *ColumnCollection

NewColumnCollection returns a new empty column collection.

func NewColumnCollectionWithPrefix

func NewColumnCollectionWithPrefix(columnPrefix string, columns ...Column) *ColumnCollection

NewColumnCollectionWithPrefix makes a new column collection with a column prefix.

func (*ColumnCollection) Add

func (cc *ColumnCollection) Add(c Column)

Add adds a column.

func (*ColumnCollection) Autos

func (cc *ColumnCollection) Autos() *ColumnCollection

Autos are columns we have to return the id of.

func (*ColumnCollection) ColumnNames

func (cc *ColumnCollection) ColumnNames() []string

ColumnNames returns the string names for all the columns in the collection.

func (*ColumnCollection) ColumnNamesCSV

func (cc *ColumnCollection) ColumnNamesCSV() string

ColumnNamesCSV returns a csv of column names.

func (*ColumnCollection) ColumnNamesCSVFromAlias

func (cc *ColumnCollection) ColumnNamesCSVFromAlias(tableAlias string) string

ColumnNamesCSVFromAlias returns the string names for all the columns in the collection.

func (*ColumnCollection) ColumnNamesFromAlias

func (cc *ColumnCollection) ColumnNamesFromAlias(tableAlias string) []string

ColumnNamesFromAlias returns the string names for all the columns in the collection.

func (*ColumnCollection) ColumnValues

func (cc *ColumnCollection) ColumnValues(instance interface{}) []interface{}

ColumnValues returns the reflected value for all the columns on a given instance.

func (*ColumnCollection) Columns

func (cc *ColumnCollection) Columns() []Column

Columns returns the colummns

func (*ColumnCollection) ConcatWith

func (cc *ColumnCollection) ConcatWith(other *ColumnCollection) *ColumnCollection

ConcatWith merges a collection with another collection.

func (ColumnCollection) Copy

Copy creates a new column collection instance and carries over an existing column prefix.

func (ColumnCollection) CopyWithColumnPrefix

func (cc ColumnCollection) CopyWithColumnPrefix(prefix string) *ColumnCollection

CopyWithColumnPrefix applies a column prefix to column names and returns a new column collection.

func (*ColumnCollection) FirstOrDefault

func (cc *ColumnCollection) FirstOrDefault() *Column

FirstOrDefault returns the first column in the collection or `nil` if the collection is empty.

func (*ColumnCollection) HasColumn

func (cc *ColumnCollection) HasColumn(columnName string) bool

HasColumn returns if a column name is present in the collection.

func (*ColumnCollection) InsertColumns added in v1.20201204.1

func (cc *ColumnCollection) InsertColumns() *ColumnCollection

InsertColumns are non-auto, non-readonly columns.

func (*ColumnCollection) Len

func (cc *ColumnCollection) Len() int

Len returns the number of columns.

func (*ColumnCollection) Lookup

func (cc *ColumnCollection) Lookup() map[string]*Column

Lookup gets the column name lookup.

func (*ColumnCollection) NotAutos

func (cc *ColumnCollection) NotAutos() *ColumnCollection

NotAutos are columns we don't have to return the id of.

func (*ColumnCollection) NotPrimaryKeys

func (cc *ColumnCollection) NotPrimaryKeys() *ColumnCollection

NotPrimaryKeys are columns we can update.

func (*ColumnCollection) NotReadOnly

func (cc *ColumnCollection) NotReadOnly() *ColumnCollection

NotReadOnly are columns that we have to insert upon Create().

func (*ColumnCollection) NotUniqueKeys

func (cc *ColumnCollection) NotUniqueKeys() *ColumnCollection

NotUniqueKeys are columns we can update.

func (*ColumnCollection) NotZero added in v1.20210103.1

func (cc *ColumnCollection) NotZero(instance interface{}) *ColumnCollection

NotZero returns set fields on an instance that correspond to fields in the column collection.

func (*ColumnCollection) PrimaryKeys

func (cc *ColumnCollection) PrimaryKeys() *ColumnCollection

PrimaryKeys are columns we use as where predicates and can't update.

func (*ColumnCollection) ReadOnly

func (cc *ColumnCollection) ReadOnly() *ColumnCollection

ReadOnly are columns that we don't have to insert upon Create().

func (*ColumnCollection) Remove

func (cc *ColumnCollection) Remove(columnName string)

Remove removes a column (by column name) from the collection.

func (*ColumnCollection) String

func (cc *ColumnCollection) String() string

func (*ColumnCollection) UniqueKeys

func (cc *ColumnCollection) UniqueKeys() *ColumnCollection

UniqueKeys are columns we use as where predicates and can't update.

func (*ColumnCollection) UpdateColumns

func (cc *ColumnCollection) UpdateColumns() *ColumnCollection

UpdateColumns are non-primary key, non-readonly columns.

func (*ColumnCollection) Zero added in v1.20210103.1

func (cc *ColumnCollection) Zero(instance interface{}) *ColumnCollection

Zero returns unset fields on an instance that correspond to fields in the column collection.

type ColumnMetaCacheKeyProvider

type ColumnMetaCacheKeyProvider interface {
	ColumnMetaCacheKey() string
}

ColumnMetaCacheKeyProvider is a provider for a column meta key.

type ColumnsProvider

type ColumnsProvider interface {
	Columns() ([]string, error)
}

ColumnsProvider is a type that can return columns.

type Config

type Config struct {
	// Engine is the database engine.
	Engine string `json:"engine,omitempty" yaml:"engine,omitempty" env:"DB_ENGINE"`
	// DSN is a fully formed DSN (this skips DSN formation from all other variables outside `schema`).
	DSN string `json:"dsn,omitempty" yaml:"dsn,omitempty" env:"DATABASE_URL"`
	// Host is the server to connect to.
	Host string `json:"host,omitempty" yaml:"host,omitempty" env:"DB_HOST"`
	// Port is the port to connect to.
	Port string `json:"port,omitempty" yaml:"port,omitempty" env:"DB_PORT"`
	// DBName is the database name
	Database string `json:"database,omitempty" yaml:"database,omitempty" env:"DB_NAME"`
	// Schema is the application schema within the database, defaults to `public`. This schema is used to set the
	// Postgres "search_path" If you want to reference tables in other schemas, you'll need to specify those schemas
	// in your queries e.g. "SELECT * FROM schema_two.table_one..."
	// Using the public schema in a production application is considered bad practice as newly created roles will have
	// visibility into this data by default. We strongly recommend specifying this option and using a schema that is
	// owned by your service's role
	// We recommend against setting a multi-schema search_path, but if you really want to, you provide multiple comma-
	// separated schema names as the value for this config, or you can dbc.Invoke().Exec a SET statement on a newly
	// opened connection such as "SET search_path = 'schema_one,schema_two';" Again, we recommend against this practice
	// and encourage you to specify schema names beyond the first in your queries.
	Schema string `json:"schema,omitempty" yaml:"schema,omitempty" env:"DB_SCHEMA"`
	// ApplicationName is the name set by an application connection to a database
	// server, intended to be transmitted in the connection string. It can be
	// used to uniquely identify an application and will be included in the
	// `pg_stat_activity` view.
	//
	// See: https://www.postgresql.org/docs/12/runtime-config-logging.html#GUC-APPLICATION-NAME
	ApplicationName string `json:"applicationName,omitempty" yaml:"applicationName,omitempty" env:"DB_APPLICATION_NAME"`
	// Username is the username for the connection via password auth.
	Username string `json:"username,omitempty" yaml:"username,omitempty" env:"DB_USER"`
	// Password is the password for the connection via password auth.
	Password string `json:"password,omitempty" yaml:"password,omitempty" env:"DB_PASSWORD"`
	// ConnectTimeout determines the maximum wait for connection. The minimum
	// allowed timeout is 2 seconds, so anything below is treated the same
	// as unset. PostgreSQL will only accept second precision so this value will be
	// rounded to the nearest second before being set on a connection string.
	// Use `Validate()` to confirm that `ConnectTimeout` is exact to second
	// precision.
	//
	// See: https://www.postgresql.org/docs/10/libpq-connect.html#LIBPQ-CONNECT-CONNECT-TIMEOUT
	ConnectTimeout time.Duration `json:"connectTimeout" yaml:"connectTimeout" env:"DB_CONNECT_TIMEOUT"`
	// LockTimeout is the timeout to use when attempting to acquire a lock.
	// PostgreSQL will only accept millisecond precision so this value will be
	// rounded to the nearest millisecond before being set on a connection string.
	// Use `Validate()` to confirm that `LockTimeout` is exact to millisecond
	// precision.
	//
	// See: https://www.postgresql.org/docs/current/runtime-config-client.html#GUC-LOCK-TIMEOUT
	LockTimeout time.Duration `json:"lockTimeout" yaml:"lockTimeout" env:"DB_LOCK_TIMEOUT"`
	// StatementTimeout is the timeout to use when invoking a SQL statement.
	// PostgreSQL will only accept millisecond precision so this value will be
	// rounded to the nearest millisecond before being set on a connection string.
	// Use `Validate()` to confirm that `StatementTimeout` is exact to millisecond
	// precision.
	//
	// See: https://www.postgresql.org/docs/current/runtime-config-client.html#GUC-STATEMENT-TIMEOUT
	StatementTimeout time.Duration `json:"statementTimeout" yaml:"statementTimeout" env:"DB_STATEMENT_TIMEOUT"`
	// SSLMode is the sslmode for the connection.
	SSLMode string `json:"sslMode,omitempty" yaml:"sslMode,omitempty" env:"DB_SSLMODE"`
	// IdleConnections is the number of idle connections.
	IdleConnections int `json:"idleConnections,omitempty" yaml:"idleConnections,omitempty" env:"DB_IDLE_CONNECTIONS"`
	// MaxConnections is the maximum number of connections.
	MaxConnections int `json:"maxConnections,omitempty" yaml:"maxConnections,omitempty" env:"DB_MAX_CONNECTIONS"`
	// MaxLifetime is the maximum time a connection can be open.
	MaxLifetime time.Duration `json:"maxLifetime,omitempty" yaml:"maxLifetime,omitempty" env:"DB_MAX_LIFETIME"`
	// BufferPoolSize is the number of query composition buffers to maintain.
	BufferPoolSize int `json:"bufferPoolSize,omitempty" yaml:"bufferPoolSize,omitempty" env:"DB_BUFFER_POOL_SIZE"`
}

Config is a set of connection config options.

func MustNewConfigFromEnv

func MustNewConfigFromEnv() Config

MustNewConfigFromEnv returns a new config from the environment, it will panic if there is an error.

func NewConfigFromDSN

func NewConfigFromDSN(dsn string) (config Config, err error)

NewConfigFromDSN creates a new config from a DSN. Errors can be produced by parsing the DSN.

func NewConfigFromEnv

func NewConfigFromEnv() (config Config, err error)

NewConfigFromEnv returns a new config from the environment. The environment variable mappings are as follows:

  • DB_ENGINE = Engine
  • DATABASE_URL = DSN //note that this has precedence over other vars (!!)
  • DB_HOST = Host
  • DB_PORT = Port
  • DB_NAME = Database
  • DB_SCHEMA = Schema
  • DB_APPLICATION_NAME = ApplicationName
  • DB_USER = Username
  • DB_PASSWORD = Password
  • DB_CONNECT_TIMEOUT = ConnectTimeout
  • DB_LOCK_TIMEOUT = LockTimeout
  • DB_STATEMENT_TIMEOUT = StatementTimeout
  • DB_SSLMODE = SSLMode
  • DB_IDLE_CONNECTIONS = IdleConnections
  • DB_MAX_CONNECTIONS = MaxConnections
  • DB_MAX_LIFETIME = MaxLifetime
  • DB_BUFFER_POOL_SIZE = BufferPoolSize

func (Config) BufferPoolSizeOrDefault added in v1.20201204.1

func (c Config) BufferPoolSizeOrDefault() int

BufferPoolSizeOrDefault returns the number of query buffers to maintain or a default.

func (Config) CreateDSN

func (c Config) CreateDSN() string

CreateDSN creates a postgres connection string from the config.

func (Config) CreateLoggingDSN added in v1.20201204.1

func (c Config) CreateLoggingDSN() string

CreateLoggingDSN creates a postgres connection string from the config suitable for logging. It will not include the password.

func (Config) DatabaseOrDefault added in v1.20201204.1

func (c Config) DatabaseOrDefault() string

DatabaseOrDefault returns the connection database or a default.

func (Config) EngineOrDefault added in v1.20201204.1

func (c Config) EngineOrDefault() string

EngineOrDefault returns the database engine.

func (Config) HostOrDefault added in v1.20201204.1

func (c Config) HostOrDefault() string

HostOrDefault returns the postgres host for the connection or a default.

func (Config) IdleConnectionsOrDefault added in v1.20201204.1

func (c Config) IdleConnectionsOrDefault() int

IdleConnectionsOrDefault returns the number of idle connections or a default.

func (Config) IsZero added in v1.20201204.1

func (c Config) IsZero() bool

IsZero returns if the config is unset.

func (Config) MaxConnectionsOrDefault added in v1.20201204.1

func (c Config) MaxConnectionsOrDefault() int

MaxConnectionsOrDefault returns the maximum number of connections or a default.

func (Config) MaxLifetimeOrDefault added in v1.20201204.1

func (c Config) MaxLifetimeOrDefault() time.Duration

MaxLifetimeOrDefault returns the maximum lifetime of a driver connection.

func (Config) MustReparse added in v1.20201204.1

func (c Config) MustReparse() Config

MustReparse creates a DSN and reparses it, in case some values need to be coalesced, and panics if there is an error.

func (Config) PortOrDefault added in v1.20201204.1

func (c Config) PortOrDefault() string

PortOrDefault returns the port for a connection if it is not the standard postgres port.

func (Config) Reparse added in v1.20201204.1

func (c Config) Reparse() (Config, error)

Reparse creates a DSN and reparses it, in case some values need to be coalesced.

func (*Config) Resolve

func (c *Config) Resolve(ctx context.Context) error

Resolve applies any external data sources to the config.

func (Config) SchemaOrDefault added in v1.20201204.1

func (c Config) SchemaOrDefault() string

SchemaOrDefault returns the schema on the search_path or the default ("public"). It's considered bad practice to use the public schema in production

func (Config) Validate added in v1.20201204.1

func (c Config) Validate() error

Validate validates that user-provided values are valid, e.g. that timeouts can be exactly rounded into a multiple of a given base value.

func (Config) ValidateProduction

func (c Config) ValidateProduction() error

ValidateProduction validates production configuration for the config.

type Connection

type Connection struct {
	Connection           *sql.DB
	BufferPool           *bufferutil.Pool
	Config               Config
	Log                  logger.Log
	Tracer               Tracer
	StatementInterceptor StatementInterceptor
}

Connection is the basic wrapper for connection parameters and saves a reference to the created sql.Connection.

func GetConnection added in v1.20201204.1

func GetConnection(ctx context.Context) *Connection

GetConnection adds a given connection to the context.

func MustNew added in v1.20201204.1

func MustNew(options ...Option) *Connection

MustNew returns a new connection and panics on error.

func New

func New(options ...Option) (*Connection, error)

New returns a new Connection. It will use very bare bones defaults for the config.

func Open added in v1.20201204.1

func Open(conn *Connection, err error) (*Connection, error)

Open opens a connection, testing an error and returning it if not nil, and if nil, opening the connection. It's designed ot be used in conjunction with a constructor, i.e.

conn, err := db.Open(db.NewFromConfig(cfg))

func (*Connection) Begin

func (dbc *Connection) Begin(opts ...func(*sql.TxOptions)) (*sql.Tx, error)

Begin starts a new transaction.

func (*Connection) BeginContext

func (dbc *Connection) BeginContext(ctx context.Context, opts ...func(*sql.TxOptions)) (*sql.Tx, error)

BeginContext starts a new transaction in a givent context.

func (*Connection) Close

func (dbc *Connection) Close() error

Close implements a closer.

func (*Connection) Exec

func (dbc *Connection) Exec(statement string, args ...interface{}) (sql.Result, error)

Exec is a helper stub for .Invoke(...).Exec(...).

func (*Connection) ExecContext

func (dbc *Connection) ExecContext(ctx context.Context, statement string, args ...interface{}) (sql.Result, error)

ExecContext is a helper stub for .Invoke(OptContext(ctx)).Exec(...).

func (*Connection) Invoke

func (dbc *Connection) Invoke(options ...InvocationOption) *Invocation

Invoke returns a new invocation.

func (*Connection) Open

func (dbc *Connection) Open() error

Open returns a connection object, either a cached connection object or creating a new one in the process.

func (*Connection) PrepareContext

func (dbc *Connection) PrepareContext(ctx context.Context, statement string, tx *sql.Tx) (stmt *sql.Stmt, err error)

PrepareContext prepares a statement within a given context. If a tx is provided, the tx is the target for the prepare. This will trigger tracing on prepare.

func (*Connection) Query

func (dbc *Connection) Query(statement string, args ...interface{}) *Query

Query is a helper stub for .Invoke(...).Query(...).

func (*Connection) QueryContext

func (dbc *Connection) QueryContext(ctx context.Context, statement string, args ...interface{}) *Query

QueryContext is a helper stub for .Invoke(OptContext(ctx)).Query(...).

type DB added in v1.20201204.1

type DB interface {
	ExecContext(context.Context, string, ...interface{}) (sql.Result, error)
	QueryContext(context.Context, string, ...interface{}) (*sql.Rows, error)
	QueryRowContext(context.Context, string, ...interface{}) *sql.Row
}

DB is a handler for queries.

type DatabaseMapped

type DatabaseMapped interface{}

DatabaseMapped is the interface that any objects passed into database mapped methods like Create, Update, Delete, Get, GetAll etc.

type Invocation

type Invocation struct {
	DB DB

	/* invocation state */
	Label string

	/* context */
	Context context.Context
	Cancel  func()

	/* dependencies */
	Config     Config
	Log        logger.Triggerable
	BufferPool *bufferutil.Pool

	/* logging hooks */
	StatementInterceptor StatementInterceptor
	Tracer               Tracer
	StartTime            time.Time
	TraceFinisher        TraceFinisher
}

Invocation is a specific operation against a context.

func (*Invocation) All added in v1.20201204.1

func (i *Invocation) All(collection interface{}) (err error)

All returns all rows of an object mapped table wrapped in a transaction.

func (*Invocation) Create

func (i *Invocation) Create(object DatabaseMapped) (err error)

Create writes an object to the database within a transaction.

func (*Invocation) CreateIfNotExists

func (i *Invocation) CreateIfNotExists(object DatabaseMapped) (err error)

CreateIfNotExists writes an object to the database if it does not already exist within a transaction. This will _ignore_ auto columns, as they will always invalidate the assertion that there already exists a row with a given primary key set.

func (*Invocation) CreateMany

func (i *Invocation) CreateMany(objects interface{}) (err error)

CreateMany writes many objects to the database in a single insert.

func (*Invocation) Delete

func (i *Invocation) Delete(object DatabaseMapped) (deleted bool, err error)

Delete deletes an object from the database wrapped in a transaction. Returns whether or not any rows have been deleted and potentially an error. If ErrTooManyRows is returned, it's important to note that due to https://github.com/golang/go/issues/7898, the Delete HAS BEEN APPLIED on the current transaction. Its on the developer using Delete to ensure their tags are correct and/or ensure theit Tx rolls back on this error.

func (*Invocation) Exec

func (i *Invocation) Exec(statement string, args ...interface{}) (res sql.Result, err error)

Exec executes a sql statement with a given set of arguments and returns the rows affected.

func (*Invocation) Exists

func (i *Invocation) Exists(object DatabaseMapped) (exists bool, err error)

Exists returns a bool if a given object exists (utilizing the primary key columns if they exist) wrapped in a transaction.

func (*Invocation) Get

func (i *Invocation) Get(object DatabaseMapped, ids ...interface{}) (found bool, err error)

Get returns a given object based on a group of primary key ids within a transaction.

func (*Invocation) Query

func (i *Invocation) Query(statement string, args ...interface{}) *Query

Query returns a new query object for a given sql query and arguments.

func (*Invocation) Update

func (i *Invocation) Update(object DatabaseMapped) (updated bool, err error)

Update updates an object wrapped in a transaction. Returns whether or not any rows have been updated and potentially an error. If ErrTooManyRows is returned, it's important to note that due to https://github.com/golang/go/issues/7898, the Update HAS BEEN APPLIED. Its on the developer using UPDATE to ensure his tags are correct and/or execute it in a transaction and roll back on this error

func (*Invocation) Upsert

func (i *Invocation) Upsert(object DatabaseMapped) (err error)

Upsert inserts the object if it doesn't exist already (as defined by its primary keys) or updates it atomically. It returns `found` as true if the effect was an upsert, i.e. the pk was found.

type InvocationOption added in v1.20201204.1

type InvocationOption func(*Invocation)

InvocationOption is an option for invocations.

func OptCancel added in v1.20201204.1

func OptCancel(cancel context.CancelFunc) InvocationOption

OptCancel sets the context cancel func..

func OptContext added in v1.20201204.1

func OptContext(ctx context.Context) InvocationOption

OptContext sets a context on an invocation.

func OptDB added in v1.20201204.1

func OptDB(db DB) InvocationOption

OptDB is an invocation option that sets the underlying invocation db.

func OptInvocationLog added in v1.20201204.1

func OptInvocationLog(log logger.Log) InvocationOption

OptInvocationLog sets the invocation logger.

func OptInvocationStatementInterceptor added in v1.20201204.1

func OptInvocationStatementInterceptor(interceptor StatementInterceptor) InvocationOption

OptInvocationStatementInterceptor sets the invocation statement interceptor.

func OptLabel added in v1.20201204.1

func OptLabel(label string) InvocationOption

OptLabel sets the Label on the invocation.

func OptTimeout added in v1.20201204.1

func OptTimeout(d time.Duration) InvocationOption

OptTimeout sets a command timeout for the invocation.

func OptTx added in v1.20201204.1

func OptTx(tx *sql.Tx) InvocationOption

OptTx is an invocation option that sets the invocation transaction.

type Labels

type Labels = map[string]string

Labels is a loose type alias to map[string]string.

type Option added in v1.20201204.1

type Option func(c *Connection) error

Option is an option for database connections.

func OptConfig added in v1.20201204.1

func OptConfig(cfg Config) Option

OptConfig sets the config on a connection.

func OptConfigFromEnv added in v1.20201204.1

func OptConfigFromEnv() Option

OptConfigFromEnv sets the config on a connection from the environment.

func OptConnection added in v1.20201204.1

func OptConnection(conn *sql.DB) Option

OptConnection sets the underlying driver connection.

func OptDatabase added in v1.20201204.1

func OptDatabase(database string) Option

OptDatabase sets the connection database.

func OptEngine added in v1.20201204.1

func OptEngine(engine string) Option

OptEngine sets the connection engine. You must have this engine registered with database/sql.

func OptHost added in v1.20201204.1

func OptHost(host string) Option

OptHost sets the connection host.

func OptLog added in v1.20201204.1

func OptLog(log logger.Log) Option

OptLog sets the tracer on the connection.

func OptPassword added in v1.20201204.1

func OptPassword(password string) Option

OptPassword sets the connection ssl mode.

func OptPort added in v1.20201204.1

func OptPort(port string) Option

OptPort sets the connection port.

func OptSSLMode added in v1.20201204.1

func OptSSLMode(mode string) Option

OptSSLMode sets the connection ssl mode.

func OptSchema added in v1.20201204.1

func OptSchema(schema string) Option

OptSchema sets the connection schema path.

func OptStatementInterceptor added in v1.20201204.1

func OptStatementInterceptor(interceptor StatementInterceptor) Option

OptStatementInterceptor sets the statement interceptor on the connection.

func OptTracer added in v1.20201204.1

func OptTracer(tracer Tracer) Option

OptTracer sets the tracer on the connection.

func OptUsername added in v1.20201204.1

func OptUsername(username string) Option

OptUsername sets the connection ssl mode.

type Populatable

type Populatable interface {
	Populate(rows Scanner) error
}

Populatable is an interface that you can implement if your object is read often and is performance critical.

func AsPopulatable added in v1.20201204.1

func AsPopulatable(object interface{}) Populatable

AsPopulatable casts an object as populatable.

type Query

type Query struct {
	Invocation *Invocation
	Statement  string
	Args       []interface{}
}

Query is the intermediate result of a query.

func (*Query) Any

func (q *Query) Any() (found bool, err error)

Any returns if there are any results for the query.

func (*Query) Do added in v1.20201204.1

func (q *Query) Do() (rows *sql.Rows, err error)

Do runs a given query, yielding the raw results.

func (*Query) Each

func (q *Query) Each(consumer RowsConsumer) (err error)

Each executes the consumer for each result of the query (one to many).

func (*Query) First

func (q *Query) First(consumer RowsConsumer) (found bool, err error)

First executes the consumer for the first result of a query. It returns `ErrTooManyRows` if more than one result is returned.

func (*Query) None

func (q *Query) None() (notFound bool, err error)

None returns if there are no results for the query.

func (*Query) Out

func (q *Query) Out(object interface{}) (found bool, err error)

Out writes the query result to a single object via. reflection mapping. If there is more than one result, the first result is mapped to to object, and ErrTooManyRows is returned. Out() will apply column values for any colums in the row result to the object, potentially zeroing existing values out.

func (*Query) OutMany

func (q *Query) OutMany(collection interface{}) (err error)

OutMany writes the query results to a slice of objects.

func (*Query) Scan

func (q *Query) Scan(args ...interface{}) (found bool, err error)

Scan writes the results to a given set of local variables. It returns if the query produced a row, and returns `ErrTooManyRows` if there are multiple row results.

type QueryEvent added in v1.20201204.1

type QueryEvent struct {
	Database string
	Engine   string
	Username string
	Label    string
	Body     string
	Elapsed  time.Duration
	Err      error
}

QueryEvent represents a database query.

func NewQueryEvent added in v1.20201204.1

func NewQueryEvent(body string, elapsed time.Duration, options ...QueryEventOption) QueryEvent

NewQueryEvent creates a new query event.

func (QueryEvent) Decompose added in v1.20201204.1

func (e QueryEvent) Decompose() map[string]interface{}

Decompose implements JSONWritable.

func (QueryEvent) GetFlag added in v1.20201204.1

func (e QueryEvent) GetFlag() string

GetFlag implements Event.

func (QueryEvent) WriteText added in v1.20201204.1

func (e QueryEvent) WriteText(tf logger.TextFormatter, wr io.Writer)

WriteText writes the event text to the output.

type QueryEventOption added in v1.20201204.1

type QueryEventOption func(*QueryEvent)

QueryEventOption mutates a query event.

func OptQueryEventBody added in v1.20201204.1

func OptQueryEventBody(value string) QueryEventOption

OptQueryEventBody sets a field on the query event.

func OptQueryEventDatabase added in v1.20201204.1

func OptQueryEventDatabase(value string) QueryEventOption

OptQueryEventDatabase sets a field on the query event.

func OptQueryEventElapsed added in v1.20201204.1

func OptQueryEventElapsed(value time.Duration) QueryEventOption

OptQueryEventElapsed sets a field on the query event.

func OptQueryEventEngine added in v1.20201204.1

func OptQueryEventEngine(value string) QueryEventOption

OptQueryEventEngine sets a field on the query event.

func OptQueryEventErr added in v1.20201204.1

func OptQueryEventErr(value error) QueryEventOption

OptQueryEventErr sets a field on the query event.

func OptQueryEventLabel added in v1.20201204.1

func OptQueryEventLabel(label string) QueryEventOption

OptQueryEventLabel sets a field on the query event.

func OptQueryEventUsername added in v1.20201204.1

func OptQueryEventUsername(value string) QueryEventOption

OptQueryEventUsername sets a field on the query event.

type Rows

type Rows interface {
	Scanner
	ColumnsProvider
}

Rows provides the relevant fields to populate by name.

type RowsConsumer

type RowsConsumer func(r Rows) error

RowsConsumer is the function signature that is called from within Each().

type Scanner

type Scanner interface {
	Scan(...interface{}) error
}

Scanner is a type that can scan into variadic values.

type StatementInterceptor added in v0.3.1

type StatementInterceptor func(statementID, statement string) string

StatementInterceptor is an interceptor for statements.

type TableNameProvider

type TableNameProvider interface {
	TableName() string
}

TableNameProvider is a type that implements the TableName() function. The only required method is TableName() string that returns the name of the table in the database this type is mapped to.

type MyDatabaseMappedObject {
	Mycolumn `db:"my_column"`
}
func (_ MyDatabaseMappedObject) TableName() string {
	return "my_database_mapped_object"
}

If you require different table names based on alias, create another type.

type TraceFinisher

type TraceFinisher interface {
	FinishPrepare(context.Context, error)
	FinishQuery(context.Context, sql.Result, error)
}

TraceFinisher is a type that can finish traces.

type Tracer

type Tracer interface {
	Prepare(context.Context, Config, string) TraceFinisher
	Query(context.Context, Config, string, string) TraceFinisher
}

Tracer is a type that can implement traces. If any of the methods return a nil finisher, they will be skipped.

type Values

type Values = map[string]interface{}

Values is a loose type alias to map[string]interface{}.

Directories

Path Synopsis
Package migration provides helpers for writing rerunnable database migrations.
Package migration provides helpers for writing rerunnable database migrations.

Jump to

Keyboard shortcuts

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