sqlutil

package module
v1.1.0 Latest Latest
Warning

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

Go to latest
Published: Jun 26, 2022 License: MIT Imports: 10 Imported by: 3

Documentation

Overview

Package sqlutil provides miscellaneous useful utilities for use with the database/sql package.

Index

Constants

This section is empty.

Variables

View Source
var ErrMisorderedMigrations = errors.New("misordered migrations")
View Source
var ErrMultipleRows = errors.New("multiple rows")

ErrMultipleRows is the error produced by Row.Scan when the query has produced more than one row.

Functions

func ForQueryRows

func ForQueryRows(ctx context.Context, db QueryerContext, query string, args ...interface{}) error

ForQueryRows encapsulates a lot of boilerplate when making db queries. Call it like this:

err = ForQueryRows(ctx, db, query, queryArg1, queryArg2, ..., func(scanVar1 type1, scanVar2 type2, ...) {
  ...process a row from the result...
})

This is equivalent to:

rows, err = db.Query(ctx, query, queryArg1, queryArg2, ...)
if err != nil {
  return err
}
defer rows.Close()
for rows.Next() {
  var (
    scanVar1 type1
    scanVar2 type2
  )
  err = rows.Scan(&scanVar1, &scanVar2, ...)
  if err != nil {
    return err
  }
  ...process a row from the result...
}
if err = rows.Err(); err != nil {
  return err
}

The callback is invoked once for each row in the result. The number and types of parameters to the callback must match the values to be scanned with rows.Scan. The space for the callback's arguments is not reused between calls. The callback may return a single error-type value. If any invocation yields a non-nil result, ForQueryRows will abort and return it.

func Migrate

func Migrate(ctx context.Context, db DB, migrations []string) error

Migrate executes database migrations.

func WithDB

func WithDB(ctx context.Context, db DB) context.Context

WithDB creates a child of the given context object containing a DB. The DB in the context can be retrieved with GetDB.

Types

type DB

type DB interface {
	PreparerContext
	QueryerContext
	ExecerContext
	Begin() (*sql.Tx, error)
}

func GetDB

func GetDB(ctx context.Context) DB

GetDB extracts the DB previously stored in ctx (or some parent of ctx) with WithDB.

type ExecerContext

type ExecerContext interface {
	ExecContext(context.Context, string, ...interface{}) (sql.Result, error)
}

ExecerContext has an ExecContext method.

type Lease

type Lease struct {
	Lessor *Lessor `json:"-"`
	Name   string
	Exp    time.Time
	Key    string
}

Lease is the type of a lease acquired from a Lessor. Its fields are exported so that callers can port a lease between processes. (The receiving process copies the sending process's values for Name, Exp, and Key, and assigns its own value for Lessor.)

func (*Lease) Context

func (l *Lease) Context(ctx context.Context) (context.Context, context.CancelFunc)

Context produces a context object with a deadline equal to the lease's expiration time. Callers should be sure to call the associated cancel function before the context goes out of scope. E.g.:

ctx, cancel := lease.Context(ctx)
defer cancel()

func (*Lease) Release

func (l *Lease) Release(ctx context.Context) error

Release releases the lease.

func (*Lease) Renew

func (l *Lease) Renew(ctx context.Context, exp time.Time) error

Renew updates the expiration time of the lease. It fails if the lease is expired or otherwise not held.

type Lessor

type Lessor struct {

	// Table is the name of the db table holding lease info.
	// The default if this is unspecified is "leases".
	Table string

	// Name is the name of the column in the lease-info table that holds a lease's name.
	// The column must have a string-compatible type (like TEXT).
	// It must be uniquely indexed (and would make a suitable PRIMARY KEY for the table).
	// The default if this is unspecified is "name".
	Name string

	// Exp is the name of the column in the lease-info table that holds a lease's expiration time.
	// The column must have a time.Time-compatible type (like DATETIME).
	// For performance, a non-unique index should be defined on it.
	// The default if this is unspecified is "exp".
	Exp string

	// Key is the name of the column in the lease-info table that holds the per-lease key.
	// It must have a type capable of storing a 32-byte string.
	// The default if this is unspecified is "key".
	Key string
	// contains filtered or unexported fields
}

Lessor is a provider of leases. It's a wrapper around a database handle that specifies the name of the database's lease-info table, and the important column names in that table.

func NewLessor

func NewLessor(db ExecerContext) *Lessor

func (*Lessor) Acquire

func (l *Lessor) Acquire(ctx context.Context, name string, exp time.Time) (*Lease, error)

Acquire attempts to acquire the lease named `name` from a Lessor. This will fail (without blocking) if that lease is already held and unexpired. If the lease is acquired, it expires at `exp`. It is also assigned a unique Key that is required in Renew and Release operations.

type PreparerContext

type PreparerContext interface {
	PrepareContext(context.Context, string) (*sql.Stmt, error)
}

PreparerContext has a PrepareContext method.

type QueryerContext

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

QueryerContext has QueryContext and QueryRowContext methods.

type Row added in v1.1.0

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

Row is the type of result produced by QueryRowContext. It is the same as "database/sql".Rows, except that it can return the ErrMultipleRows error.

func QueryRowContext added in v1.1.0

func QueryRowContext(ctx context.Context, db QueryerContext, query string, args ...interface{}) *Row

QueryRowContext is just like the db.QueryRowContext method but additionally detects whether the query produces more than one row. In that case the Row.Scan method returns ErrMultipleRows.

func (*Row) Err added in v1.1.0

func (r *Row) Err() error

Err returns the error in r, if any.

func (*Row) Scan added in v1.1.0

func (r *Row) Scan(dest ...interface{}) error

Scan scans the values in r and assigns them to the pointers supplied as arguments. See "database/sql".Row.Scan. Note that when this function returns ErrMultipleRows, the pointers are populated anyway, with values from the first row of query results.

Jump to

Keyboard shortcuts

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