dbw

package module
v0.1.2 Latest Latest
Warning

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

Go to latest
Published: Feb 12, 2024 License: MPL-2.0 Imports: 29 Imported by: 7

README

dbw package

Go Reference Go Report Card Go Coverage

dbw is a database wrapper that supports connecting and using any database with a GORM driver.

dbw is intended to completely encapsulate an application's access to its database with the exception of migrations. dbw is intentionally not an ORM and it removes typical ORM abstractions like "advanced query building", associations and migrations.

Of course you can use dbw for complicated queries, it's just that dbw doesn't try to reinvent SQL by providing some sort of pattern for building them with functions. Of course, dbw also provides lookup/search functions when you simply need to read resources from the database.

dbw strives to make CRUD for database resources fairly trivial for common use cases. It also supports an WithOnConflict(...) option for its RW.Create(...) function for complex scenarios. dbw also allows you to opt out of its CRUD functions and use exec, query and scan rows directly. You may want to carefully weigh when it's appropriate to use exec and query directly, since it's likely that each time you use them you're leaking a bit of your database layer schema into your application's domain.

Documentation

Overview

Package dbw is a database wrapper that supports connecting and using any database with a gorm driver. It's intent is to completely encapsulate an application's access to it's database with the exception of migrations.

dbw is intentionally not an ORM and it removes typical ORM abstractions like "advanced query building", associations and migrations.

This is not to say you can't easily use dbw for complicated queries, it's just that dbw doesn't try to reinvent sql by providing some sort of pattern for building them with functions. Of course, dbw also provides lookup/search functions when you simply need to read resources from the database.

dbw strives to make CRUD for database resources fairly trivial. Even supporting "on conflict" for its create function. dbw also allows you to opt out of its CRUD functions and use exec, query and scan rows directly. You may want to carefully weigh when it's appropriate to use exec and query directly, since it's likely that each time you use them you're leaking a bit of your database schema into your application's domain.

For more information see README.md

Index

Constants

View Source
const (

	// DefaultLimit is the default for search results when no limit is specified
	// via the WithLimit(...) option
	DefaultLimit = 10000
)

Variables

View Source
var (
	// ErrUnknown is an unknown/undefined error
	ErrUnknown = errors.New("unknown")

	// ErrInvalidParameter is an invalid parameter error
	ErrInvalidParameter = errors.New("invalid parameter")

	// ErrInternal is an internal error
	ErrInternal = errors.New("internal error")

	// ErrRecordNotFound is a not found record error
	ErrRecordNotFound = errors.New("record not found")

	// ErrMaxRetries is a max retries error
	ErrMaxRetries = errors.New("too many retries")

	// ErrInvalidFieldMask is an invalid field mask error
	ErrInvalidFieldMask = errors.New("invalid field mask")
)

Functions

func BuildUpdatePaths

func BuildUpdatePaths(fieldValues map[string]interface{}, fieldMask []string, allowZeroFields []string) (masks []string, nulls []string)

BuildUpdatePaths takes a map of field names to field values, field masks, fields allowed to be zero value, and returns both a list of field names to update and a list of field names that should be set to null.

func Clear

func Clear(i interface{}, fields []string, depth int) error

Clear sets fields in the value pointed to by i to their zero value. Clear descends i to depth clearing fields at each level. i must be a pointer to a struct. Cycles in i are not detected.

A depth of 2 will change i and i's children. A depth of 1 will change i but no children of i. A depth of 0 will return with no changes to i.

func InitNonCreatableFields

func InitNonCreatableFields(fields []string)

InitNonCreatableFields sets the fields which are not setable using via RW.Create(...)

func InitNonUpdatableFields

func InitNonUpdatableFields(fields []string)

InitNonUpdatableFields sets the fields which are not updatable using via RW.Update(...)

func Intersection

func Intersection(av, bv []string) ([]string, map[string]string, map[string]string, error)

Intersection is a case-insensitive search for intersecting values. Returns []string of the Intersection with values in lowercase, and map[string]string of the original av and bv, with the key set to uppercase and value set to the original

func NewId

func NewId(prefix string, opt ...Option) (string, error)

NewId creates a new random base62 ID with the provided prefix with an underscore delimiter

func NonCreatableFields

func NonCreatableFields() []string

NonCreatableFields returns the current set of fields which are not setable using via RW.Create(...)

func NonUpdatableFields

func NonUpdatableFields() []string

NonUpdatableFields returns the current set of fields which are not updatable using via RW.Update(...)

func TestCreateTables

func TestCreateTables(t *testing.T, conn *DB)

TestCreateTables will create the test tables for the dbw pkg

func UpdateFields

func UpdateFields(i interface{}, fieldMaskPaths []string, setToNullPaths []string) (map[string]interface{}, error)

UpdateFields will create a map[string]interface of the update values to be sent to the db. The map keys will be the field names for the fields to be updated. The caller provided fieldMaskPaths and setToNullPaths must not intersect. fieldMaskPaths and setToNullPaths cannot both be zero len.

Types

type Backoff

type Backoff interface {
	Duration(attemptNumber uint) time.Duration
}

Backoff defines an interface for providing a back off for retrying transactions. See DoTx(...)

type Column

type Column struct {
	// Name of the column
	Name string
	// Table name of the column
	Table string
}

Column represents a table Column

type ColumnValue

type ColumnValue struct {
	// Column name
	Column string
	// Value is the column's value
	Value interface{}
}

ColumnValue defines a column and it's assigned value for a database operation. See: SetColumnValues(...)

func SetColumnValues

func SetColumnValues(columnValues map[string]interface{}) []ColumnValue

SetColumnValues defines a map from column names to values for database operations.

func SetColumns

func SetColumns(names []string) []ColumnValue

SetColumns defines a list of column (names) to update using the set of proposed insert columns during an on conflict update.

type Columns

type Columns []string

Columns defines a set of column names

type ConstBackoff

type ConstBackoff struct {
	DurationMs time.Duration
}

ConstBackoff defines a constant backoff for retrying transactions. See DoTx(...)

func (ConstBackoff) Duration

func (b ConstBackoff) Duration(attempt uint) time.Duration

Duration is the constant backoff duration based on the retry attempt

type Constraint

type Constraint string

Constraint defines database constraint name

type DB

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

DB is a wrapper around whatever is providing the interface for database operations (typically an ORM). DB uses database/sql to maintain connection pool.

func Open

func Open(dbType DbType, connectionUrl string, opt ...Option) (*DB, error)

Open a database connection which is long-lived. The options of WithLogger, WithLogLevel and WithMaxOpenConnections are supported.

Note: Consider if you need to call Close() on the returned DB. Typically the answer is no, but there are occasions when it's necessary. See the sql.DB docs for more information.

func OpenWith

func OpenWith(dialector Dialector, opt ...Option) (*DB, error)

OpenWith will open a database connection using a Dialector which is long-lived. The options of WithLogger, WithLogLevel and WithMaxOpenConnections are supported.

Note: Consider if you need to call Close() on the returned DB. Typically the answer is no, but there are occasions when it's necessary. See the sql.DB docs for more information.

func TestSetup

func TestSetup(t *testing.T, opt ...TestOption) (*DB, string)

TestSetup is typically called before starting a test and will setup the database for the test (initialize the database one-time). Do not close the returned db. Supported test options: WithDebug, WithTestDialect, WithTestDatabaseUrl, WithTestMigration and WithTestMigrationUsingDB.

func TestSetupWithMock

func TestSetupWithMock(t *testing.T) (*DB, sqlmock.Sqlmock)

TestSetupWithMock will return a test DB and an associated Sqlmock which can be used to mock out the db responses.

func (*DB) Close

func (db *DB) Close(ctx context.Context) error

Close the database

Note: Consider if you need to call Close() on the returned DB. Typically the answer is no, but there are occasions when it's necessary. See the sql.DB docs for more information.

func (*DB) DbType

func (db *DB) DbType() (typ DbType, rawName string, e error)

DbType will return the DbType and raw name of the connection type

func (*DB) Debug

func (db *DB) Debug(on bool)

Debug will enable/disable debug info for the connection

func (*DB) LogLevel

func (db *DB) LogLevel(l LogLevel)

LogLevel will set the logging level for the db

func (*DB) SqlDB

func (db *DB) SqlDB(_ context.Context) (*sql.DB, error)

SqlDB returns the underlying sql.DB Note: this makes it possible to do things like set database/sql connection options like SetMaxIdleConns. If you're simply setting max/min connections then you should use the WithMinOpenConnections and WithMaxOpenConnections options when "opening" the database.

Care should be take when deciding to use this for basic database operations like Exec, Query, etc since these functions are already provided by dbw.RW which provides a layer of encapsulation of the underlying database.

type DbType

type DbType int

DbType defines a database type. It's not an exhaustive list of database types which can be used by the dbw package, since you can always use OpenWith(...) to connect to KnownDB types.

const (
	// UnknownDB is an unknown db type
	UnknownDB DbType = 0

	// Postgres is a postgre db type
	Postgres DbType = 1

	// Sqlite is a sqlite db type
	Sqlite DbType = 2
)

func StringToDbType

func StringToDbType(dialect string) (DbType, error)

StringToDbType provides a string to type conversion. If the type is known, then UnknownDB with and error is returned.

func (DbType) String

func (db DbType) String() string

String provides a string rep of the DbType.

type Dialector

type Dialector interface {
	gorm.Dialector
}

Dialector provides a set of functions the database dialect must satisfy to be used with OpenWith(...) It's a simple wrapper of the gorm.Dialector and provides the ability to open any support gorm dialect driver.

type DoNothing

type DoNothing bool

DoNothing defines an "on conflict" action of doing nothing

type ExpBackoff

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

ExpBackoff defines an exponential backoff for retrying transactions. See DoTx(...)

func (ExpBackoff) Duration

func (b ExpBackoff) Duration(attempt uint) time.Duration

Duration is the exponential backoff duration based on the retry attempt

type ExprValue

type ExprValue struct {
	Sql  string
	Vars []interface{}
}

ExprValue encapsulates an expression value for a column assignment. See Expr(...) to create these values.

func Expr

func Expr(expr string, args ...interface{}) ExprValue

Expr creates an expression value (ExprValue) which can be used when setting column values for database operations. See: Expr(...)

Set name column to null example:

SetColumnValues(map[string]interface{}{"name": Expr("NULL")})

Set exp_time column to N seconds from now:

SetColumnValues(map[string]interface{}{"exp_time": Expr("wt_add_seconds_to_now(?)", 10)})

type LogLevel

type LogLevel int

LogLevel defines a log level

const (
	// Default specifies the default log level
	Default LogLevel = iota

	// Silent is the silent log level
	Silent

	// Error is the error log level
	Error

	// Warn is the warning log level
	Warn

	// Info is the info log level
	Info
)

type OnConflict

type OnConflict struct {
	// Target specifies what conflict you want to define a policy for.  This can
	// be any one of these:
	//	Columns: the name of a specific column or columns
	//  Constraint: the name of a unique constraint
	Target interface{}

	// Action specifies the action to take on conflict. This can be any one of
	// these:
	//	DoNothing: leaves the conflicting record as-is
	//  UpdateAll: updates all the columns of the conflicting record using the resource's data
	//  []ColumnValue: update a set of columns of the conflicting record using the set of assignments
	Action interface{}
}

OnConflict specifies how to handle alternative actions to take when an insert results in a unique constraint or exclusion constraint error.

type OpType

type OpType int

OpType defines a set of database operation types

const (
	// UnknownOp is an unknown operaton
	UnknownOp OpType = 0

	// CreateOp is a create operation
	CreateOp OpType = 1

	// UpdateOp is an update operation
	UpdateOp OpType = 2

	// DeleteOp is a delete operation
	DeleteOp OpType = 3
)

type Option

type Option func(*Options)

Option - how Options are passed as arguments.

func WithAfterWrite

func WithAfterWrite(fn func(i interface{}, rowsAffected int) error) Option

WithAfterWrite provides and option to provide a func to be called after a write operation. The i interface{} passed at runtime will be the resource(s) being written.

func WithBeforeWrite

func WithBeforeWrite(fn func(i interface{}) error) Option

WithBeforeWrite provides and option to provide a func to be called before a write operation. The i interface{} passed at runtime will be the resource(s) being written.

func WithDebug

func WithDebug(with bool) Option

WithDebug specifies the given operation should invoke debug mode for the database output

func WithFieldMaskPaths

func WithFieldMaskPaths(paths []string) Option

WithFieldMaskPaths provides an option to provide field mask paths for update operations.

func WithLimit

func WithLimit(limit int) Option

WithLimit provides an option to provide a limit. Intentionally allowing negative integers. If WithLimit < 0, then unlimited results are returned. If WithLimit == 0, then default limits are used for results (see DefaultLimit const).

func WithLogLevel

func WithLogLevel(l LogLevel) Option

WithLogLevel specifies an option for setting the log level

func WithLogger

func WithLogger(l hclog.Logger) Option

WithLogger specifies an optional hclog to use for db operations. It's only valid for Open(..) and OpenWith(...)

func WithLookup

func WithLookup(enable bool) Option

WithLookup enables a lookup after a write operation.

func WithMaxOpenConnections

func WithMaxOpenConnections(max int) Option

WithMaxOpenConnections specifies and optional max open connections for the database. A value of zero equals unlimited connections

func WithMinOpenConnections

func WithMinOpenConnections(max int) Option

WithMinOpenConnections specifies and optional min open connections for the database. A value of zero means that there is no min.

func WithNullPaths

func WithNullPaths(paths []string) Option

WithNullPaths provides an option to provide null paths for update operations.

func WithOnConflict

func WithOnConflict(onConflict *OnConflict) Option

WithOnConflict specifies an optional on conflict criteria which specify alternative actions to take when an insert results in a unique constraint or exclusion constraint error

func WithOrder

func WithOrder(withOrder string) Option

WithOrder provides an option to provide an order when searching and looking up.

func WithPrngValues

func WithPrngValues(withPrngValues []string) Option

WithPrngValues provides an option to provide values to seed an PRNG when generating IDs

func WithReturnRowsAffected

func WithReturnRowsAffected(rowsAffected *int64) Option

WithReturnRowsAffected specifies an option for returning the rows affected and typically used with "bulk" write operations.

func WithSkipVetForWrite

func WithSkipVetForWrite(enable bool) Option

WithSkipVetForWrite provides an option to allow skipping vet checks to allow testing lower-level SQL triggers and constraints

func WithTable

func WithTable(name string) Option

WithTable specifies an option for setting a table name to use for the operation.

func WithVersion

func WithVersion(version *uint32) Option

WithVersion provides an option version number for update operations. Using this option requires that your resource has a version column that's incremented for every successful update operation. Version provides an optimistic locking mechanism for write operations.

func WithWhere

func WithWhere(whereClause string, args ...interface{}) Option

WithWhere provides an option to provide a where clause with arguments for an operation.

type Options

type Options struct {
	// WithBeforeWrite provides and option to provide a func to be called before a
	// write operation. The i interface{} passed at runtime will be the resource(s)
	// being written.
	WithBeforeWrite func(i interface{}) error

	// WithAfterWrite provides and option to provide a func to be called after a
	// write operation.  The i interface{} passed at runtime will be the resource(s)
	// being written.
	WithAfterWrite func(i interface{}, rowsAffected int) error

	// WithLookup enables a lookup after a write operation.
	WithLookup bool

	// WithLimit provides an option to provide a limit.  Intentionally allowing
	// negative integers.   If WithLimit < 0, then unlimited results are returned.
	// If WithLimit == 0, then default limits are used for results (see DefaultLimit
	// const).
	WithLimit int

	// WithFieldMaskPaths provides an option to provide field mask paths for update
	// operations.
	WithFieldMaskPaths []string

	// WithNullPaths provides an option to provide null paths for update
	// operations.
	WithNullPaths []string

	// WithVersion provides an option version number for update operations.  Using
	// this option requires that your resource has a version column that's
	// incremented for every successful update operation.  Version provides an
	// optimistic locking mechanism for write operations.
	WithVersion *uint32

	WithSkipVetForWrite bool

	// WithWhereClause provides an option to provide a where clause for an
	// operation.
	WithWhereClause string

	// WithWhereClauseArgs provides an option to provide a where clause arguments for an
	// operation.
	WithWhereClauseArgs []interface{}

	// WithOrder provides an option to provide an order when searching and looking
	// up.
	WithOrder string

	// WithPrngValues provides an option to provide values to seed an PRNG when generating IDs
	WithPrngValues []string

	// WithLogger specifies an optional hclog to use for db operations.  It's only
	// valid for Open(..) and OpenWith(...)
	WithLogger hclog.Logger

	// WithMinOpenConnections specifies and optional min open connections for the
	// database.  A value of zero means that there is no min.
	WithMaxOpenConnections int

	// WithMaxOpenConnections specifies and optional max open connections for the
	// database.  A value of zero equals unlimited connections
	WithMinOpenConnections int

	// WithDebug indicates that the given operation should invoke debug output
	// mode
	WithDebug bool

	// WithOnConflict specifies an optional on conflict criteria which specify
	// alternative actions to take when an insert results in a unique constraint or
	// exclusion constraint error
	WithOnConflict *OnConflict

	// WithRowsAffected specifies an option for returning the rows affected
	// and typically used with "bulk" write operations.
	WithRowsAffected *int64

	// WithTable specifies an option for setting a table name to use for the
	// operation.
	WithTable string
	// contains filtered or unexported fields
}

Options - how Options are represented which have been set via an Option function. Use GetOpts(...) to populated this struct with the options that have been specified for an operation. All option fields are exported so they're available for use by other packages.

func GetOpts

func GetOpts(opt ...Option) Options

GetOpts - iterate the inbound Options and return a struct.

type RW

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

RW uses a DB as a connection for it's read/write operations. This is basically the primary type for the package's operations.

func New

func New(underlying *DB) *RW

New creates a new RW using an open DB. Note: there can by many RWs that share the same DB, since the DB manages the connection pool.

func (*RW) Begin

func (rw *RW) Begin(ctx context.Context) (*RW, error)

Begin will start a transaction

func (*RW) Commit

func (rw *RW) Commit(ctx context.Context) error

Commit will commit a transaction

func (*RW) Create

func (rw *RW) Create(ctx context.Context, i interface{}, opt ...Option) error

Create a resource in the db with options: WithDebug, WithLookup, WithReturnRowsAffected, OnConflict, WithBeforeWrite, WithAfterWrite, WithVersion, WithTable, and WithWhere.

OnConflict specifies alternative actions to take when an insert results in a unique constraint or exclusion constraint error. If WithVersion is used with OnConflict, then the update for on conflict will include the version number, which basically makes the update use optimistic locking and the update will only succeed if the existing rows version matches the WithVersion option. Zero is not a valid value for the WithVersion option and will return an error. WithWhere allows specifying an additional constraint on the on conflict operation in addition to the on conflict target policy (columns or constraint).

func (*RW) CreateItems

func (rw *RW) CreateItems(ctx context.Context, createItems []interface{}, opt ...Option) error

CreateItems will create multiple items of the same type. Supported options: WithDebug, WithBeforeWrite, WithAfterWrite, WithReturnRowsAffected, OnConflict, WithVersion, WithTable, and WithWhere. WithLookup is not a supported option.

func (*RW) DB

func (rw *RW) DB() *DB

DB returns the underlying DB

func (*RW) Delete

func (rw *RW) Delete(ctx context.Context, i interface{}, opt ...Option) (int, error)

Delete a resource in the db with options: WithWhere, WithDebug, WithTable, and WithVersion. WithWhere and WithVersion allows specifying a additional constraints on the operation in addition to the PKs. Delete returns the number of rows deleted and any errors.

func (*RW) DeleteItems

func (rw *RW) DeleteItems(ctx context.Context, deleteItems []interface{}, opt ...Option) (int, error)

DeleteItems will delete multiple items of the same type. Options supported: WithDebug, WithTable

func (*RW) Dialect

func (rw *RW) Dialect() (_ DbType, rawName string, _ error)

func (*RW) DoTx

func (rw *RW) DoTx(ctx context.Context, retryErrorsMatchingFn func(error) bool, retries uint, backOff Backoff, handler TxHandler) (RetryInfo, error)

DoTx will wrap the Handler func passed within a transaction with retries you should ensure that any objects written to the db in your TxHandler are retryable, which means that the object may be sent to the db several times (retried), so things like the primary key may need to be reset before retry.

func (*RW) Exec

func (rw *RW) Exec(ctx context.Context, sql string, values []interface{}, opt ...Option) (int, error)

Exec will execute the sql with the values as parameters. The int returned is the number of rows affected by the sql. The WithDebug option is supported.

func (*RW) IsTx

func (rw *RW) IsTx() bool

IsTx returns true if there's an existing transaction in progress

func (*RW) LookupBy

func (rw *RW) LookupBy(ctx context.Context, resourceWithIder interface{}, opt ...Option) error

LookupBy will lookup a resource by it's primary keys, which must be unique. If the resource implements either ResourcePublicIder or ResourcePrivateIder interface, then they are used as the resource's primary key for lookup. Otherwise, the resource tags are used to determine it's primary key(s) for lookup. The WithDebug and WithTable options are supported.

func (*RW) LookupByPublicId

func (rw *RW) LookupByPublicId(ctx context.Context, resource ResourcePublicIder, opt ...Option) error

LookupByPublicId will lookup resource by its public_id, which must be unique. The WithTable option is supported.

func (*RW) LookupWhere

func (rw *RW) LookupWhere(ctx context.Context, resource interface{}, where string, args []interface{}, opt ...Option) error

LookupWhere will lookup the first resource using a where clause with parameters (it only returns the first one). Supports WithDebug, and WithTable options.

func (*RW) Query

func (rw *RW) Query(ctx context.Context, sql string, values []interface{}, opt ...Option) (*sql.Rows, error)

Query will run the raw query and return the *sql.Rows results. Query will operate within the context of any ongoing transaction for the Reader. The caller must close the returned *sql.Rows. Query can/should be used in combination with ScanRows. The WithDebug option is supported.

func (*RW) Rollback

func (rw *RW) Rollback(ctx context.Context) error

Rollback will rollback the current transaction

func (*RW) ScanRows

func (rw *RW) ScanRows(rows *sql.Rows, result interface{}) error

ScanRows will scan the rows into the interface

func (*RW) SearchWhere

func (rw *RW) SearchWhere(ctx context.Context, resources interface{}, where string, args []interface{}, opt ...Option) error

SearchWhere will search for all the resources it can find using a where clause with parameters. An error will be returned if args are provided without a where clause.

Supports WithTable and WithLimit options. If WithLimit < 0, then unlimited results are returned. If WithLimit == 0, then default limits are used for results. Supports the WithOrder, WithTable, and WithDebug options.

func (*RW) Update

func (rw *RW) Update(ctx context.Context, i interface{}, fieldMaskPaths []string, setToNullPaths []string, opt ...Option) (int, error)

Update a resource in the db, a fieldMask is required and provides field_mask.proto paths for fields that should be updated. The i interface parameter is the type the caller wants to update in the db and its fields are set to the update values. setToNullPaths is optional and provides field_mask.proto paths for the fields that should be set to null. fieldMaskPaths and setToNullPaths must not intersect. The caller is responsible for the transaction life cycle of the writer and if an error is returned the caller must decide what to do with the transaction, which almost always should be to rollback. Update returns the number of rows updated.

Supported options: WithBeforeWrite, WithAfterWrite, WithWhere, WithDebug, WithTable and WithVersion. If WithVersion is used, then the update will include the version number in the update where clause, which basically makes the update use optimistic locking and the update will only succeed if the existing rows version matches the WithVersion option. Zero is not a valid value for the WithVersion option and will return an error. WithWhere allows specifying an additional constraint on the operation in addition to the PKs. WithDebug will turn on debugging for the update call.

type Reader

type Reader interface {
	// LookupBy will lookup a resource by it's primary keys, which must be
	// unique. If the resource implements either ResourcePublicIder or
	// ResourcePrivateIder interface, then they are used as the resource's
	// primary key for lookup.  Otherwise, the resource tags are used to
	// determine it's primary key(s) for lookup.
	LookupBy(ctx context.Context, resource interface{}, opt ...Option) error

	// LookupByPublicId will lookup resource by its public_id which must be unique.
	LookupByPublicId(ctx context.Context, resource ResourcePublicIder, opt ...Option) error

	// LookupWhere will lookup and return the first resource using a where clause with parameters
	LookupWhere(ctx context.Context, resource interface{}, where string, args []interface{}, opt ...Option) error

	// SearchWhere will search for all the resources it can find using a where
	// clause with parameters. Supports the WithLimit option.  If
	// WithLimit < 0, then unlimited results are returned.  If WithLimit == 0, then
	// default limits are used for results.
	SearchWhere(ctx context.Context, resources interface{}, where string, args []interface{}, opt ...Option) error

	// Query will run the raw query and return the *sql.Rows results. Query will
	// operate within the context of any ongoing transaction for the dbw.Reader.  The
	// caller must close the returned *sql.Rows. Query can/should be used in
	// combination with ScanRows.
	Query(ctx context.Context, sql string, values []interface{}, opt ...Option) (*sql.Rows, error)

	// ScanRows will scan sql rows into the interface provided
	ScanRows(rows *sql.Rows, result interface{}) error

	// Dialect returns the dialect and raw connection name of the underlying database.
	Dialect() (_ DbType, rawName string, _ error)
}

Reader interface defines lookups/searching for resources

type ResourcePrivateIder

type ResourcePrivateIder interface {
	GetPrivateId() string
}

ResourcePrivateIder defines an interface that LookupBy() can use to get the resource's private id.

type ResourcePublicIder

type ResourcePublicIder interface {
	GetPublicId() string
}

ResourcePublicIder defines an interface that LookupByPublicId() and LookupBy() can use to get the resource's public id.

type RetryInfo

type RetryInfo struct {
	Retries int
	Backoff time.Duration
}

RetryInfo provides information on the retries of a transaction

type TestOption

type TestOption func(*testOptions)

TestOption - how Options are passed as arguments

func WithTestDatabaseUrl

func WithTestDatabaseUrl(url string) TestOption

WithTestDatabaseUrl provides a way to specify an existing database for tests

func WithTestDialect

func WithTestDialect(dialect string) TestOption

WithTestDialect provides a way to specify the test database dialect

func WithTestMigration

func WithTestMigration(migrationFn func(ctx context.Context, dialect, url string) error) TestOption

WithTestMigration provides a way to specify an option func which runs a required database migration to initialize the database

func WithTestMigrationUsingDB

func WithTestMigrationUsingDB(migrationFn func(ctx context.Context, db *sql.DB) error) TestOption

WithTestMigrationUsingDB provides a way to specify an option func which runs a required database migration to initialize the database using an existing open sql.DB

type TxHandler

type TxHandler func(Reader, Writer) error

TxHandler defines a handler for a func that writes a transaction for use with DoTx

type UpdateAll

type UpdateAll bool

UpdateAll defines an "on conflict" action of updating all columns using the proposed insert column values

type VetForWriter

type VetForWriter interface {
	VetForWrite(ctx context.Context, r Reader, opType OpType, opt ...Option) error
}

VetForWriter provides an interface that Create and Update can use to vet the resource before before writing it to the db. For optType == UpdateOp, options WithFieldMaskPath and WithNullPaths are supported. For optType == CreateOp, no options are supported

type Writer

type Writer interface {
	// DoTx will wrap the TxHandler in a retryable transaction
	DoTx(ctx context.Context, retryErrorsMatchingFn func(error) bool, retries uint, backOff Backoff, Handler TxHandler) (RetryInfo, error)

	// Update an object in the db, fieldMask is required and provides
	// field_mask.proto paths for fields that should be updated. The i interface
	// parameter is the type the caller wants to update in the db and its
	// fields are set to the update values. setToNullPaths is optional and
	// provides field_mask.proto paths for the fields that should be set to
	// null.  fieldMaskPaths and setToNullPaths must not intersect. The caller
	// is responsible for the transaction life cycle of the writer and if an
	// error is returned the caller must decide what to do with the transaction,
	// which almost always should be to rollback.  Update returns the number of
	// rows updated or an error.
	Update(ctx context.Context, i interface{}, fieldMaskPaths []string, setToNullPaths []string, opt ...Option) (int, error)

	// Create a resource in the database. The caller is responsible for the
	// transaction life cycle of the writer and if an error is returned the
	// caller must decide what to do with the transaction, which almost always
	// should be to rollback.
	Create(ctx context.Context, i interface{}, opt ...Option) error

	// CreateItems will create multiple items of the same type. The caller is
	// responsible for the transaction life cycle of the writer and if an error
	// is returned the caller must decide what to do with the transaction, which
	// almost always should be to rollback.
	CreateItems(ctx context.Context, createItems []interface{}, opt ...Option) error

	// Delete a resource in the database. The caller is responsible for the
	// transaction life cycle of the writer and if an error is returned the
	// caller must decide what to do with the transaction, which almost always
	// should be to rollback. Delete returns the number of rows deleted or an
	// error.
	Delete(ctx context.Context, i interface{}, opt ...Option) (int, error)

	// DeleteItems will delete multiple items of the same type. The caller is
	// responsible for the transaction life cycle of the writer and if an error
	// is returned the caller must decide what to do with the transaction, which
	// almost always should be to rollback. Delete returns the number of rows
	// deleted or an error.
	DeleteItems(ctx context.Context, deleteItems []interface{}, opt ...Option) (int, error)

	// Exec will execute the sql with the values as parameters. The int returned
	// is the number of rows affected by the sql. No options are currently
	// supported.
	Exec(ctx context.Context, sql string, values []interface{}, opt ...Option) (int, error)

	// Query will run the raw query and return the *sql.Rows results.  The
	// caller must close the returned *sql.Rows. Query can/should be used in
	// combination with ScanRows.  Query is included in the Writer interface
	// so callers can execute updates and inserts with returning values.
	Query(ctx context.Context, sql string, values []interface{}, opt ...Option) (*sql.Rows, error)

	// ScanRows will scan sql rows into the interface provided
	ScanRows(rows *sql.Rows, result interface{}) error

	// Begin will start a transaction.  NOTE: consider using DoTx(...) with a
	// TxHandler since it supports a better interface for managing transactions
	// via a TxHandler.
	Begin(ctx context.Context) (*RW, error)

	// Rollback will rollback the current transaction.  NOTE: consider using
	// DoTx(...) with a TxHandler since it supports a better interface for
	// managing transactions  via a TxHandler.
	Rollback(ctx context.Context) error

	// Commit will commit a transaction.  NOTE: consider using DoTx(...) with a
	// TxHandler since it supports a better interface for managing transactions
	// via a TxHandler.
	Commit(ctx context.Context) error

	// Dialect returns the dialect and raw connection name of the underlying database.
	Dialect() (_ DbType, rawName string, _ error)
}

Writer interface defines create, update and retryable transaction handlers

Directories

Path Synopsis
internal
dbtest
Package db_test provides some helper funcs for testing db integrations
Package db_test provides some helper funcs for testing db integrations

Jump to

Keyboard shortcuts

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