db

package
v1.0.0-b001 Latest Latest
Warning

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

Go to latest
Published: Apr 26, 2018 License: MIT Imports: 16 Imported by: 0

README

db

This is a very bare bones database interface for golang. It abstracts away a bunch of boilerplate so that the developer can concentrate on writing their app.

It does not abstract away actual sql, however.

Gotchas & General Notes

  • Stuct to database table / column mapping is done through field tags.
  • There are a bunch of helpers for common operations (Get, GetAll, Create, CreateMany, Update, Delete, etc.).
    • These will write sql for you, and generally simplify basic operations.
  • We leverage statement caching aggressively. What this means is that if a query or exec is assigned a label, we will save the returned query plan for later increasing throughput.
    • The pre-built (Get, GetAll, Create, CreateMany etc.) methods create query labels for you.
    • Your statements will not be cached if you don't set a query label.
    • You set the query label by: conn.Invoke().WithLabel("my_label").[Query(...)|Exec(...)]

Mapping Structs Using go-sdk/db

A sample database mapped type:

type MyTable struct {
	Id int `db:"id,auto,pk"`
	Name string
	Excluded `db:"-"`
}
// note; if we don't do this, the table name will be inferred from the type name.
func (mt MyTable) TableName() string {
	return "my_table"
}

Two important things: we define tags on struct members to tell the orm how to interact with the db. We also define a method that returns the table name for the struct as it is mapped in the db.

Tags are laid out in the following format db:"<column_name>,<options>,...", where after the column_name there can be multiple options. An example above is id,serial,pk, which translates to a column name id and options serial,pk respectively.

Options include:

  • auto : denotes a column that will be read back on Create (there can be many of these).
  • pk : deontes a column that consitutes a primary key. Will be used when creating SQL where clauses.
  • readonly : denotes a column that is only read, not written to the db.

Managing Connections and Aliases

The next step in running a database driven app is to tell the app how to connect to the db.

We can create a connection with a configuration:

conn, err := db.NewFromConfig(db.NewConfig().WithHost("localhost").WithDatabase("my_db").WithUser("postgres").WithPassword("super_secret_pw")).Open()

The above snipped creates a connection, and opens it (establishing the connection). We can then pass this connection around to other things like controllers.

The Default Connection

If we don't want to manage connection references ourselves and just want to have a simple .Default() accessible anywhere, we can use:

err := db.OpenDefault(db.NewFromConfig(db.NewConfig().WithHost("localhost").WithDatabase("my_db").WithUser("postgres").WithPassword("super_secret_pw")))

This will then let the connection be accessible from a central place db.Default().

The downside of this is if we need multiple connections to multiple databases we'll need to create another default singleton, and it's easier in that case just to manage the references ourselves.

ORM Actions: Create, Update, Delete, Get, GetAll

To create an object that has been mapped to a table, simply call:

obj := MyObj{...}
err := db.Default().Create(&obj) //note the reference! this is incase we have to write back a auto id.

Then we can get the object with:

var obj MyObj
err := db.Default().Get(&obj, "foo") // "foo" here is an imaginary primary key value.

To udpate an object:

var obj  MyObj
err := db.Default().Get(&obj, objID) //note, there can be multiple params (!!) if there are multiple pks
// .. handle the err
obj.Property = "new_value"
err = db.Default().Update(obj) //note we don't need a reference for this, as it's read only.

To delete an object:

var obj MyObj
err := db.Default().Get(&obj, objID) //note, there can be multiple params (!!) if there are multiple pks
// .. handle the err
err = db.Default().Delete(obj) //note we don't need a reference for this, as it's read only.

Complex queries; using raw sql

To use sql directly, we need to use either an Exec (when we don't need to return results) or a Query (when we do want the results).

Query

There are a couple options / paths we can take to actually running a query, and it's important to understand when to use each path.

  • We need to run a query against the database without a transaction or a statement cache label:
db.Default().Query(<SQL Statement>, <Args...>).<Out(...)|OutMany(...)|Each(...)|First(...)|Scan(...)|Any()|None()>
  • We need to run a query against the database with statement cache label:
db.Default().Invoke().WithLabel("cached_statement").Query(<SQL Statement>, <Args...>).<Out(...)|OutMany(...)|Each(...)|First(...)|Scan(...)|Any()|None()>
  • We need to run a query against the database using a transaction, with a cache label:
db.Default().InTx(tx).WithLabel("cached_statement").Query(<SQL Statement>, <Args...>).<Out(...)|OutMany(...)|Each(...)|First(...)|Scan(...)|Any()|None()>

Note that after the Query(...) function itself, there can be various collectors. Each collector serves a different purpose:

  • Out(&obj): take the first result and automatically populate it against the object reference obj (must be passed by addr &)
  • OutMany(&objs): take all results and automatically populate them against the object array reference objs (must be passed by addr &)
  • Each(func(*sql.Rows) error): run the given handler for each result. This is useful if you need to read nested objects.
  • First(func(*sql.Rows) error): run the given handler for the first result. This is useful if you need to read a single complicated object.
  • Scan(<Args...>): read the first result into a given set of references. Useful for scalar return values.
  • Any, None: return if there are results present, or conversely no results present.

Exec

Executes have very similar preambles to queries:

  • We need to execute a sql statement:
db.Default().Exec(<SQL Statement>, <Args...>)

The only difference is the lack of a collector.

Common Patterns / Advanced Usage

Nested objects

Lets say you have to model the following:

type Parent struct {
	ID int `db:"id,pk,serial"`
	TimestampUTC time.Time `db:"timestamp_utc"`
	Children []Child `db:"-"` // not we don't actually map this to the db.
}

type Child struct {
	ID int `db:"id,pk,serial"`
	ParentID int `db:"parent_id"`
	Name string `db:"name"`
}

What would the best way be to read all the Parent objects out with a given query?

We would want to query the parent objects, and while we're doing so, create a way to modify the parents as we read all the children.

To do this we use a map as a lookup, and some careful handling of pointers.

func GetAllParents() (parents []Parent, err error) {
	parentLookup := map[int]*Parent{} // note the pointer! this is so we can modify it.

	if err = db.Default().Query("select * from parent").Each(func(r *sql.Rows) error {
		var parent Parent
		// populate by name is a helper to set an object from a given row result
		// it is used internally by `OutMany` on `Query`.
		if err := db.PopulateByName(&parent, r, db.Columns(parent)); err != nil {
			return err
		}
		parents = append(parents, parent)
		parentLookup[parent.ID] = &parent
		return nil
	}); err != nil {
		return 
	}

	// now we need to do a second query to get all the children.
	if err = db.Default().Query("select * from children").Each(func(r *sql.Rows) error {
		var child Child
		if err := db.PopulateByName(&child, r. db.Columns(child)); err != nil {
			return err
		}
		// here is the key part, we're looking up the parent to add the children.
		// because we're modifying references, the changes propagate to the original instances.
		if parent, hasParent := parentLookup[child.ParentID]; hasParent {
			parent.Children = append(parent.Children, child)
		}
		return nil
	}); err != nil {
		return 
	}
	return
}

Performance

Generally it's pretty good. There is a comparison test in spiffy_test.go if you want to see for yourself. It creates 5000 objects with 5 properties each, then reads them out using the orm or manual scanning.

The results were:

manual orm
17.11ms 38.08ms

This would be shabby in .net land, but for Go where we can't dynamically emit populate methods, and we're stuck doing in-order population or by name population, it's ok.

If you implement Populatable, performance improves dramatically.

manual orm (Populatable)
14.33ms 16.95ms

The strategy then is to impelement populate on your "hot read" objects, and let the orm figure out the other ones.

Documentation

Overview

Package db providers a basic abstraction layer above normal database/sql that makes it easier to interact with the database and organize database related code. It is not intended to replace actual sql (you write queries yourself).

Index

Constants

View Source
const (
	// EnvVarDatabaseURL is an environment variable.
	EnvVarDatabaseURL = "DATABASE_URL"

	// 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"

	// 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"

	// DefaultUseStatementCache is the default if we should enable the statement cache.
	DefaultUseStatementCache = true
	// 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 (
	//DBNilError is a common error
	DBNilError = "connection is nil"
)

Variables

This section is empty.

Functions

func ColumnNamesCSV

func ColumnNamesCSV(object DatabaseMapped) string

ColumnNamesCSV returns a csv of column names.

func IsPasswordUnset

func IsPasswordUnset(err error) bool

IsPasswordUnset returns if an error is an `ErrPasswordUnset`.

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 OpenDefault

func OpenDefault(conn *Connection) error

OpenDefault sets the default connection and opens it.

func OptionalTx

func OptionalTx(txs ...*sql.Tx) *sql.Tx

OptionalTx returns the first of a variadic set of txs. It is useful if you want to have a tx an optional parameter.

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 PopulateByName

func PopulateByName(object interface{}, row *sql.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 *sql.Rows, cols *ColumnCollection) 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 SetDefault

func SetDefault(conn *Connection)

SetDefault sets an alias created with `CreateDbAlias` as default. This lets you refer to it later via. `Default()`

spiffy.CreateDbAlias("main", spiffy.NewDbConnection("localhost", "test_db", "", ""))
spiffy.SetDefault("main")
execErr := spiffy.Default().Execute("select 'ok!')

This will then let you refer to the alias via. `Default()`

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 Tx

func Tx(txs ...*sql.Tx) *sql.Tx

Tx is an alias for OptionalTx

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 BufferPool

type BufferPool struct {
	sync.Pool
}

BufferPool is a sync.Pool of bytes.Buffer.

func NewBufferPool

func NewBufferPool(bufferSize int) *BufferPool

NewBufferPool returns a new BufferPool.

func (*BufferPool) Get

func (bp *BufferPool) Get() *bytes.Buffer

Get returns a pooled bytes.Buffer instance.

func (*BufferPool) Put

func (bp *BufferPool) Put(b *bytes.Buffer)

Put returns the pooled instance.

type Column

type Column struct {
	TableName    string
	FieldName    string
	FieldType    reflect.Type
	ColumnName   string
	Index        int
	IsPrimaryKey bool
	IsAuto       bool
	IsNullable   bool
	IsReadOnly   bool
	IsJSON       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 interface{}, value interface{}) error

SetValue sets the field on a database mapped 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 (*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) 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) 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) UpdateColumns

func (cc *ColumnCollection) UpdateColumns() *ColumnCollection

UpdateColumns are non-readonly, non-serial columns.

func (*ColumnCollection) WriteColumns

func (cc *ColumnCollection) WriteColumns() *ColumnCollection

WriteColumns are non-serial, non-primary key, non-readonly columns.

type Config

type Config struct {
	// 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`.
	Schema string `json:"schema,omitempty" yaml:"schema,omitempty" env:"DB_SCHEMA"`
	// 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"`
	// SSLMode is the sslmode for the connection.
	SSLMode string `json:"sslMode,omitempty" yaml:"sslMode,omitempty" env:"DB_SSLMODE"`
	// UseStatementCache indicates if we should use the prepared statement cache.
	UseStatementCache *bool `json:"useStatementCache,omitempty" yaml:"useStatementCache,omitempty" env:"DB_USE_STATEMENT_CACHE"`
	// 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 NewConfig

func NewConfig() *Config

NewConfig creates a new config.

func NewConfigFromDSN

func NewConfigFromDSN(dsn string) (*Config, error)

NewConfigFromDSN creates a new config from a dsn.

func NewConfigFromEnv

func NewConfigFromEnv() *Config

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

  • DATABSE_URL = DSN //note that this has precedence over other vars (!!)
  • DB_HOST = Host
  • DB_PORT = Port
  • DB_NAME = Database
  • DB_SCHEMA = Schema
  • DB_USER = Username
  • DB_PASSWORD = Password
  • DB_SSLMODE = SSLMode

func (Config) CreateDSN

func (c Config) CreateDSN() string

CreateDSN creates a postgres connection string from the config.

func (Config) GetBufferPoolSize

func (c Config) GetBufferPoolSize(inherited ...int) int

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

func (Config) GetDSN

func (c Config) GetDSN(inherited ...string) string

GetDSN returns the postgres dsn (fully quallified url) for the config. If unset, it's generated from the host, port and database.

func (Config) GetDatabase

func (c Config) GetDatabase(inherited ...string) string

GetDatabase returns the connection database or a default.

func (Config) GetHost

func (c Config) GetHost(inherited ...string) string

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

func (Config) GetIdleConnections

func (c Config) GetIdleConnections(inherited ...int) int

GetIdleConnections returns the number of idle connections or a default.

func (Config) GetMaxConnections

func (c Config) GetMaxConnections(inherited ...int) int

GetMaxConnections returns the maximum number of connections or a default.

func (Config) GetMaxLifetime

func (c Config) GetMaxLifetime(inherited ...time.Duration) time.Duration

GetMaxLifetime returns the maximum lifetime of a driver connection.

func (Config) GetPassword

func (c Config) GetPassword(inherited ...string) string

GetPassword returns the connection password or a default.

func (Config) GetPort

func (c Config) GetPort(inherited ...string) string

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

func (Config) GetSSLMode

func (c Config) GetSSLMode(inherited ...string) string

GetSSLMode returns the connection ssl mode. It defaults to unset, which will then use the lib/pq defaults.

func (Config) GetSchema

func (c Config) GetSchema(inherited ...string) string

GetSchema returns the connection schema or a default.

func (Config) GetUseStatementCache

func (c Config) GetUseStatementCache(inherited ...bool) bool

GetUseStatementCache returns if we should enable the statement cache or a default.

func (Config) GetUsername

func (c Config) GetUsername(inherited ...string) string

GetUsername returns the connection username or a default.

func (Config) ValidateProduction

func (c Config) ValidateProduction() error

ValidateProduction validates production configuration for the config.

func (*Config) WithDSN

func (c *Config) WithDSN(dsn string) *Config

WithDSN sets the config dsn and returns a reference to the config.

func (*Config) WithDatabase

func (c *Config) WithDatabase(database string) *Config

WithDatabase sets the config database and returns a reference to the config.

func (*Config) WithHost

func (c *Config) WithHost(host string) *Config

WithHost sets the config host and returns a reference to the config.

func (*Config) WithPassword

func (c *Config) WithPassword(password string) *Config

WithPassword sets the config password and returns a reference to the config.

func (*Config) WithPort

func (c *Config) WithPort(port string) *Config

WithPort sets the config host and returns a reference to the config.

func (*Config) WithSSLMode

func (c *Config) WithSSLMode(sslMode string) *Config

WithSSLMode sets the config sslMode and returns a reference to the config.

func (*Config) WithSchema

func (c *Config) WithSchema(schema string) *Config

WithSchema sets the config schema and returns a reference to the config.

func (*Config) WithUsername

func (c *Config) WithUsername(username string) *Config

WithUsername sets the config username and returns a reference to the config.

type Connection

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

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

func Default

func Default() *Connection

Default returns a reference to the DbConnection set as default.

spiffy.Default().Exec("select 'ok!")

func New

func New() *Connection

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

func NewFromConfig

func NewFromConfig(cfg *Config) *Connection

NewFromConfig returns a new connection from a config.

func NewFromEnv

func NewFromEnv() *Connection

NewFromEnv creates a new db connection from environment variables.

func (*Connection) Begin

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

Begin starts a new transaction.

func (*Connection) Close

func (dbc *Connection) Close() error

Close implements a closer.

func (*Connection) Config

func (dbc *Connection) Config() *Config

Config returns the config.

func (*Connection) Connection

func (dbc *Connection) Connection() *sql.DB

Connection returns the underlying driver connection.

func (*Connection) Create

func (dbc *Connection) Create(object DatabaseMapped) error

Create writes an object to the database.

func (*Connection) CreateIfNotExists

func (dbc *Connection) CreateIfNotExists(object DatabaseMapped) error

CreateIfNotExists writes an object to the database if it does not already exist.

func (*Connection) CreateIfNotExistsInTx

func (dbc *Connection) CreateIfNotExistsInTx(object DatabaseMapped, tx *sql.Tx) (err error)

CreateIfNotExistsInTx writes an object to the database if it does not already exist within a transaction.

func (*Connection) CreateInTx

func (dbc *Connection) CreateInTx(object DatabaseMapped, tx *sql.Tx) (err error)

CreateInTx writes an object to the database within a transaction.

func (*Connection) CreateMany

func (dbc *Connection) CreateMany(objects interface{}) error

CreateMany writes many an objects to the database.

func (*Connection) CreateManyInTx

func (dbc *Connection) CreateManyInTx(objects interface{}, tx *sql.Tx) (err error)

CreateManyInTx writes many an objects to the database within a transaction.

func (*Connection) Delete

func (dbc *Connection) Delete(object DatabaseMapped) error

Delete deletes an object from the database.

func (*Connection) DeleteInTx

func (dbc *Connection) DeleteInTx(object DatabaseMapped, tx *sql.Tx) (err error)

DeleteInTx deletes an object from the database wrapped in a transaction.

func (*Connection) DisableStatementCache

func (dbc *Connection) DisableStatementCache()

DisableStatementCache opts to not use the statement cache.

func (*Connection) EnableStatementCache

func (dbc *Connection) EnableStatementCache()

EnableStatementCache opts to cache statements for the connection.

func (*Connection) Exec

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

Exec runs the statement without creating a QueryResult.

func (*Connection) ExecInTx

func (dbc *Connection) ExecInTx(statement string, tx *sql.Tx, args ...interface{}) (err error)

ExecInTx runs a statement within a transaction.

func (*Connection) ExecInTxWithCacheLabel

func (dbc *Connection) ExecInTxWithCacheLabel(statement, cacheLabel string, tx *sql.Tx, args ...interface{}) (err error)

ExecInTxWithCacheLabel runs a statement within a transaction.

func (*Connection) ExecWithCacheLabel

func (dbc *Connection) ExecWithCacheLabel(statement, cacheLabel string, args ...interface{}) error

ExecWithCacheLabel runs the statement without creating a QueryResult.

func (*Connection) Exists

func (dbc *Connection) Exists(object DatabaseMapped) (bool, error)

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

func (*Connection) ExistsInTx

func (dbc *Connection) ExistsInTx(object DatabaseMapped, tx *sql.Tx) (exists bool, err error)

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

func (*Connection) Get

func (dbc *Connection) Get(object DatabaseMapped, ids ...interface{}) error

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

func (*Connection) GetAll

func (dbc *Connection) GetAll(collection interface{}) error

GetAll returns all rows of an object mapped table.

func (*Connection) GetAllInTx

func (dbc *Connection) GetAllInTx(collection interface{}, tx *sql.Tx) error

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

func (*Connection) GetInTx

func (dbc *Connection) GetInTx(object DatabaseMapped, tx *sql.Tx, args ...interface{}) error

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

func (*Connection) InTx

func (dbc *Connection) InTx(txs ...*sql.Tx) *Invocation

InTx is an alias to Invoke.

func (*Connection) Invoke

func (dbc *Connection) Invoke(txs ...*sql.Tx) *Invocation

Invoke returns a new invocation.

func (*Connection) InvokeContext

func (dbc *Connection) InvokeContext(txs ...*sql.Tx) *InvocationContext

InvokeContext returns a new db context.

func (*Connection) Logger

func (dbc *Connection) Logger() *logger.Logger

Logger returns the diagnostics agent.

func (*Connection) Open

func (dbc *Connection) Open() (*Connection, error)

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

func (*Connection) Prepare

func (dbc *Connection) Prepare(statement string, tx *sql.Tx) (*sql.Stmt, error)

Prepare prepares a new statement for the connection.

func (*Connection) PrepareCached

func (dbc *Connection) PrepareCached(id, statement string, tx *sql.Tx) (*sql.Stmt, error)

PrepareCached prepares a potentially cached statement.

func (*Connection) Query

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

Query runs the selected statement and returns a Query.

func (*Connection) QueryInTx

func (dbc *Connection) QueryInTx(statement string, tx *sql.Tx, args ...interface{}) (result *Query)

QueryInTx runs the selected statement in a transaction and returns a Query.

func (*Connection) StatementCache

func (dbc *Connection) StatementCache() *StatementCache

StatementCache returns the statement cache.

func (*Connection) Truncate

func (dbc *Connection) Truncate(object DatabaseMapped) error

Truncate fully removes an tables rows in a single opertation.

func (*Connection) TruncateInTx

func (dbc *Connection) TruncateInTx(object DatabaseMapped, tx *sql.Tx) error

TruncateInTx applies a truncation in a transaction.

func (*Connection) Update

func (dbc *Connection) Update(object DatabaseMapped) error

Update updates an object.

func (*Connection) UpdateInTx

func (dbc *Connection) UpdateInTx(object DatabaseMapped, tx *sql.Tx) (err error)

UpdateInTx updates an object wrapped in a transaction.

func (*Connection) Upsert

func (dbc *Connection) Upsert(object DatabaseMapped) error

Upsert inserts the object if it doesn't exist already (as defined by its primary keys) or updates it.

func (*Connection) UpsertInTx

func (dbc *Connection) UpsertInTx(object DatabaseMapped, tx *sql.Tx) (err error)

UpsertInTx inserts the object if it doesn't exist already (as defined by its primary keys) or updates it wrapped in a transaction.

func (*Connection) WithConfig

func (dbc *Connection) WithConfig(cfg *Config) *Connection

WithConfig sets the config.

func (*Connection) WithLogger

func (dbc *Connection) WithLogger(log *logger.Logger) *Connection

WithLogger sets the connection's diagnostic agent.

func (*Connection) WithUseStatementCache

func (dbc *Connection) WithUseStatementCache(enabled bool) *Connection

WithUseStatementCache returns if we should use the statement cache.

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 Error

type Error string

Error is a common error type.

const (
	// ErrUnsafeSSLMode is an error indicating unsafe ssl mode in production.
	ErrUnsafeSSLMode Error = "db: unsafe ssl mode in prodlike environment"
	// ErrUsernameUnset is an error indicating there is no username set in a prodlike environment.
	ErrUsernameUnset Error = "db: username is unset in prodlike environment"
	// ErrPasswordUnset is an error indicating there is no password set in a prodlike environment.
	ErrPasswordUnset Error = "db: password is unset in prodlike environment"
)

func (Error) Error

func (e Error) Error() string

Error implements `error`

type Invocation

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

Invocation is a specific operation against a context.

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.

func (*Invocation) CreateMany

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

CreateMany writes many an objects to the database within a transaction.

func (*Invocation) Ctx

func (i *Invocation) Ctx() context.Context

Ctx returns the underlying context.

func (*Invocation) Delete

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

Delete deletes an object from the database wrapped in a transaction.

func (*Invocation) Exec

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

Exec executes a sql statement with a given set of arguments.

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) FireEvents

func (i *Invocation) FireEvents() bool

FireEvents returns if events are enabled.

func (*Invocation) Get

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

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

func (*Invocation) GetAll

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

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

func (*Invocation) Label

func (i *Invocation) Label() string

Label returns the statement / plan cache label for the context.

func (*Invocation) Prepare

func (i *Invocation) Prepare(statement string) (*sql.Stmt, error)

Prepare returns a cached or newly prepared statment plan for a given sql statement.

func (*Invocation) Query

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

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

func (*Invocation) Truncate

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

Truncate completely empties a table in a single command.

func (*Invocation) Tx

func (i *Invocation) Tx() *sql.Tx

Tx returns the underlying transaction.

func (*Invocation) Update

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

Update updates an object wrapped in a transaction.

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 wrapped in a transaction.

func (*Invocation) Validate

func (i *Invocation) Validate() error

Validate validates the invocation is ready

func (*Invocation) WithCtx

func (i *Invocation) WithCtx(ctx context.Context) *Invocation

WithCtx sets the ctx and returns a reference to the invocation.

func (*Invocation) WithFireEvents

func (i *Invocation) WithFireEvents(flag bool) *Invocation

WithFireEvents sets the fire events property and returns an invocation.

func (*Invocation) WithLabel

func (i *Invocation) WithLabel(label string) *Invocation

WithLabel instructs the query generator to get or create a cached prepared statement.

type InvocationContext

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

InvocationContext represents an invocation context. It rolls both the underlying connection and an optional tx into one struct. The motivation here is so that if you have datamanager functions they can be used across databases, and don't assume internally which db they talk to.

func NewInvocationContext

func NewInvocationContext(conn *Connection) *InvocationContext

NewInvocationContext returns a new invocation context.

func (*InvocationContext) Commit

func (ic *InvocationContext) Commit() error

Commit calls `Commit()` on the underlying transaction.

func (*InvocationContext) Connection

func (ic *InvocationContext) Connection() *Connection

Connection returns the underlying connection for the context.

func (*InvocationContext) Ctx

func (ic *InvocationContext) Ctx() context.Context

Ctx returns the context on the invocation context.

func (*InvocationContext) FireEvents

func (ic *InvocationContext) FireEvents() bool

FireEvents returns if events are enabled.

func (*InvocationContext) InTx

func (ic *InvocationContext) InTx(txs ...*sql.Tx) *InvocationContext

InTx isolates a context to a transaction.

func (*InvocationContext) Invoke

func (ic *InvocationContext) Invoke() *Invocation

Invoke starts a new invocation.

func (*InvocationContext) Rollback

func (ic *InvocationContext) Rollback() error

Rollback calls `Rollback()` on the underlying transaction.

func (*InvocationContext) Tx

func (ic *InvocationContext) Tx() *sql.Tx

Tx returns the transction for the context.

func (*InvocationContext) WithConnection

func (ic *InvocationContext) WithConnection(conn *Connection) *InvocationContext

WithConnection sets the connection for the context.

func (*InvocationContext) WithCtx

WithCtx sets the db context.

func (*InvocationContext) WithFireEvents

func (ic *InvocationContext) WithFireEvents(flag bool) *InvocationContext

WithFireEvents sets the `FireEvents` property.

type Labels

type Labels = map[string]string

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

type Populatable

type Populatable interface {
	Populate(rows *sql.Rows) error
}

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

type Query

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

Query is the intermediate result of a query.

func (*Query) Any

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

Any returns if there are any results for the query.

func (*Query) CachedAs

func (q *Query) CachedAs(cacheLabel string) *Query

CachedAs sets the statement cache label for the query.

func (*Query) Close

func (q *Query) Close() error

Close closes and releases any resources retained by the QueryResult.

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) Execute

func (q *Query) Execute() (stmt *sql.Stmt, rows *sql.Rows, err error)

Execute runs a given query, yielding the raw results.

func (*Query) First

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

First executes the consumer for the first result of a query.

func (*Query) None

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

None returns if there are no results for the query.

func (*Query) Out

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

Out writes the query result to a single object via. reflection mapping.

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{}) (err error)

Scan writes the results to a given set of local variables.

type RowsConsumer

type RowsConsumer func(r *sql.Rows) error

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

type StatementCache

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

StatementCache is a cache of prepared statements.

func (*StatementCache) Clear

func (sc *StatementCache) Clear() error

Clear deletes all cached statements.

func (*StatementCache) Close

func (sc *StatementCache) Close() error

Close implements io.Closer.

func (*StatementCache) HasStatement

func (sc *StatementCache) HasStatement(statementID string) bool

HasStatement returns if the cache contains a statement.

func (*StatementCache) InvalidateStatement

func (sc *StatementCache) InvalidateStatement(statementID string)

InvalidateStatement removes a statement from the cache.

func (*StatementCache) Prepare

func (sc *StatementCache) Prepare(id, statementProvider string) (*sql.Stmt, error)

Prepare returns a cached expression for a statement, or creates and caches a new one.

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 Values

type Values = map[string]interface{}

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

Directories

Path Synopsis
_example command

Jump to

Keyboard shortcuts

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