pkgsite: Index | Files

package database

import ""

Package database adds some useful functionality to a sql.DB. It is independent of the database driver and the DB schema.


Package Files

database.go logging.go reflect.go


const OnConflictDoNothing = "ON CONFLICT DO NOTHING"


var QueryLoggingDisabled bool

QueryLoggingDisabled stops logging of queries when true. For use in tests only: not concurrency-safe.

func NullIsEmpty Uses

func NullIsEmpty(s *string) sql.Scanner

NullIsEmpty returns a sql.Scanner that writes the empty string to s if the sql.Value is NULL.

func NullPtr Uses

func NullPtr(p interface{}) nullPtr

NullPtr is for scanning nullable database columns into pointer variables or fields. When given a pointer to to a pointer to some type T, it returns a value that can be passed to a Scan function. If the corresponding column is nil, the variable will be set to nil. Otherwise, it will be set to a newly allocated pointer to the column value.

func StructScanner Uses

func StructScanner(s interface{}) func(p interface{}) []interface{}

StructScanner takes a struct and returns a function that, when called on a struct pointer of that type, returns a slice of arguments suitable for Row.Scan or Rows.Scan. The call to either Scan will populate the exported fields of the struct in the order they appear in the type definition.

StructScanner panics if p is not a struct or a pointer to a struct. The function it returns will panic if its argument is not a pointer to a struct.


type Player struct { Name string; Score int }
playerScanArgs := database.StructScanner(Player{})
err := db.RunQuery(ctx, "SELECT name, score FROM players", func(rows *sql.Rows) error {
    var p Player
    if err := rows.Scan(playerScanArgs(&p)...); err != nil {
        return err
    // use p
    return nil

type DB Uses

type DB struct {
    // contains filtered or unexported fields

DB wraps a sql.DB. The methods it exports correspond closely to those of sql.DB. They enhance the original by requiring a context argument, and by logging the query and any resulting errors.

A DB may represent a transaction. If so, its execution and query methods operate within the transaction.

func New Uses

func New(db *sql.DB, instanceID string) *DB

New creates a new DB from a sql.DB.

func Open Uses

func Open(driverName, dbinfo, instanceID string) (_ *DB, err error)

Open creates a new DB for the given connection string.

func (*DB) BulkInsert Uses

func (db *DB) BulkInsert(ctx context.Context, table string, columns []string, values []interface{}, conflictAction string) (err error)

BulkInsert constructs and executes a multi-value insert statement. The query is constructed using the format:

INSERT INTO <table> (<columns>) VALUES (<placeholders-for-each-item-in-values>)

If conflictAction is not empty, it is appended to the statement.

The query is executed using a PREPARE statement with the provided values.

func (*DB) BulkInsertReturning Uses

func (db *DB) BulkInsertReturning(ctx context.Context, table string, columns []string, values []interface{}, conflictAction string, returningColumns []string, scanFunc func(*sql.Rows) error) (err error)

BulkInsertReturning is like BulkInsert, but supports returning values from the INSERT statement. In addition to the arguments of BulkInsert, it takes a list of columns to return and a function to scan those columns. To get the returned values, provide a function that scans them as if they were the selected columns of a query. See TestBulkInsert for an example.

func (*DB) BulkUpdate Uses

func (db *DB) BulkUpdate(ctx context.Context, table string, columns, types []string, values [][]interface{}) (err error)

BulkUpdate executes multiple UPDATE statements in a transaction.

Columns must contain the names of some of table's columns. The first is treated as a key; that is, the values to update are matched with existing rows by comparing the values of the first column.

Types holds the database type of each column. For example,

[]string{"INT", "TEXT"}

Values contains one slice of values per column. (Note that this is unlike BulkInsert, which takes a single slice of interleaved values.)

func (*DB) BulkUpsert Uses

func (db *DB) BulkUpsert(ctx context.Context, table string, columns []string, values []interface{}, conflictColumns []string) error

BulkUpsert is like BulkInsert, but instead of a conflict action, a list of conflicting columns is provided. An "ON CONFLICT (conflict_columns) DO UPDATE" clause is added to the statement, with assignments "c=excluded.c" for every column c.

func (*DB) BulkUpsertReturning Uses

func (db *DB) BulkUpsertReturning(ctx context.Context, table string, columns []string, values []interface{}, conflictColumns, returningColumns []string, scanFunc func(*sql.Rows) error) error

BulkUpsertReturning is like BulkInsertReturning, but performs an upsert like BulkUpsert.

func (*DB) Close Uses

func (db *DB) Close() error

Close closes the database connection.

func (*DB) CollectStructs Uses

func (db *DB) CollectStructs(ctx context.Context, pslice interface{}, query string, args ...interface{}) error

CollectStructs scans the the rows from the query into structs and appends them to pslice, which must be a pointer to a slice of structs. Example:

type Player struct { Name string; Score int }
var players []Player
err := db.CollectStructs(ctx, &players, "SELECT name, score FROM players")

func (*DB) Exec Uses

func (db *DB) Exec(ctx context.Context, query string, args ...interface{}) (_ int64, err error)

Exec executes a SQL statement and returns the number of rows it affected.

func (*DB) InTransaction Uses

func (db *DB) InTransaction() bool

func (*DB) MaxRetries Uses

func (db *DB) MaxRetries() int

MaxRetries returns the maximum number of times thata serializable transaction was retried.

func (*DB) Ping Uses

func (db *DB) Ping() error

func (*DB) Prepare Uses

func (db *DB) Prepare(ctx context.Context, query string) (*sql.Stmt, error)

func (*DB) Query Uses

func (db *DB) Query(ctx context.Context, query string, args ...interface{}) (_ *sql.Rows, err error)

Query runs the DB query.

func (*DB) QueryRow Uses

func (db *DB) QueryRow(ctx context.Context, query string, args ...interface{}) *sql.Row

QueryRow runs the query and returns a single row.

func (*DB) RunQuery Uses

func (db *DB) RunQuery(ctx context.Context, query string, f func(*sql.Rows) error, params ...interface{}) error

RunQuery executes query, then calls f on each row.

func (*DB) Transact Uses

func (db *DB) Transact(ctx context.Context, iso sql.IsolationLevel, txFunc func(*DB) error) (err error)

Transact executes the given function in the context of a SQL transaction at the given isolation level, rolling back the transaction if the function panics or returns an error.

The given function is called with a DB that is associated with a transaction. The DB should be used only inside the function; if it is used to access the database after the function returns, the calls will return errors.

If the isolation level requires it, Transact will retry the transaction upon serialization failure, so txFunc may be called more than once.

Package database imports 17 packages (graph) and is imported by 3 packages. Updated 2021-01-17. Refresh now. Tools for package owners.