README

upper/db Build Status GoDoc

upper/db is a productive data access layer (DAL) for Go that provides agnostic tools to work with different data sources, such as:

See upper.io/v4 for documentation and code samples.

The tour

tour

Take the tour to see real live examples in your browser.

License

Licensed under MIT License

Contributors

See the list of contributors.

Expand ▾ Collapse ▴

Documentation

Overview

Package db (or upper/db) provides an agnostic data access layer to work with different databases.

Install upper/db:

go get github.com/upper/db

Usage

package main

import (
	"log"

	"github.com/upper/db/v4/adapter/postgresql" // Imports the postgresql adapter.
)

var settings = postgresql.ConnectionURL{
	Database: `booktown`,
	Host:     `demo.upper.io`,
	User:     `demouser`,
	Password: `demop4ss`,
}

// Book represents a book.
type Book struct {
	ID        uint   `db:"id"`
	Title     string `db:"title"`
	AuthorID  uint   `db:"author_id"`
	SubjectID uint   `db:"subject_id"`
}

func main() {
	sess, err := postgresql.Open(settings)
	if err != nil {
		log.Fatal(err)
	}
	defer sess.Close()

	var books []Book
	if err := sess.Collection("books").Find().OrderBy("title").All(&books); err != nil {
		log.Fatal(err)
	}

	log.Println("Books:")
	for _, book := range books {
		log.Printf("%q (ID: %d)\n", book.Title, book.ID)
	}
}

Index

Constants

This section is empty.

Variables

var (
	ErrMissingAdapter           = errors.New(`upper: missing adapter`)
	ErrAlreadyWithinTransaction = errors.New(`upper: already within a transaction`)
	ErrCollectionDoesNotExist   = errors.New(`upper: collection does not exist`)
	ErrExpectingNonNilModel     = errors.New(`upper: expecting non nil model`)
	ErrExpectingPointerToStruct = errors.New(`upper: expecting pointer to struct`)
	ErrGivingUpTryingToConnect  = errors.New(`upper: giving up trying to connect: too many clients`)
	ErrInvalidCollection        = errors.New(`upper: invalid collection`)
	ErrMissingCollectionName    = errors.New(`upper: missing collection name`)
	ErrMissingConditions        = errors.New(`upper: missing selector conditions`)
	ErrMissingConnURL           = errors.New(`upper: missing DSN`)
	ErrMissingDatabaseName      = errors.New(`upper: missing database name`)
	ErrNoMoreRows               = errors.New(`upper: no more rows in this result set`)
	ErrNotConnected             = errors.New(`upper: not connected to a database`)
	ErrNotImplemented           = errors.New(`upper: call not implemented`)
	ErrQueryIsPending           = errors.New(`upper: can't execute this instruction while the result set is still open`)
	ErrQueryLimitParam          = errors.New(`upper: a query can accept only one limit parameter`)
	ErrQueryOffsetParam         = errors.New(`upper: a query can accept only one offset parameter`)
	ErrQuerySortParam           = errors.New(`upper: a query can accept only one order-by parameter`)
	ErrSockerOrHost             = errors.New(`upper: you may connect either to a UNIX socket or a TCP address, but not both`)
	ErrTooManyClients           = errors.New(`upper: can't connect to database server: too many clients`)
	ErrUndefined                = errors.New(`upper: value is undefined`)
	ErrUnknownConditionType     = errors.New(`upper: arguments of type %T can't be used as constraints`)
	ErrUnsupported              = errors.New(`upper: action is not supported by the DBMS`)
	ErrUnsupportedDestination   = errors.New(`upper: unsupported destination type`)
	ErrUnsupportedType          = errors.New(`upper: type does not support marshaling`)
	ErrUnsupportedValue         = errors.New(`upper: value does not support unmarshaling`)
	ErrNilRecord                = errors.New(`upper: invalid item (nil)`)
	ErrRecordIDIsZero           = errors.New(`upper: item ID is not defined`)
	ErrMissingPrimaryKeys       = errors.New(`upper: collection has no primary keys`)
	ErrWarnSlowQuery            = errors.New(`upper: slow query`)
	ErrTransactionAborted       = errors.New(`upper: transaction was aborted`)
	ErrNotWithinTransaction     = errors.New(`upper: not within transaction`)
	ErrNotSupportedByAdapter    = errors.New(`upper: not supported by adapter`)
)

Error messages


Functions

func RegisterAdapter

func RegisterAdapter(name string, adapter Adapter)

RegisterAdapter registers a generic database adapter.

Types

type Adapter

type Adapter interface {
	Open(ConnectionURL) (Session, error)
}

Adapter interface defines an adapter

func LookupAdapter

func LookupAdapter(name string) Adapter

LookupAdapter returns a previously registered adapter by name.

type AfterCreateHook

type AfterCreateHook interface {
	AfterCreate(Session) error
}

AfterCreateHook is an interface for records that defines an AfterCreate method that is called after creating a record. If AfterCreate returns an error the create process is cancelled and rolled back.

type AfterDeleteHook

type AfterDeleteHook interface {
	AfterDelete(Session) error
}

AfterDeleteHook is an interface for records that defines a AfterDelete method that is called after removing a record. If AfterDelete returns an error the delete process is cancelled and rolled back.

type AfterUpdateHook

type AfterUpdateHook interface {
	AfterUpdate(Session) error
}

AfterUpdateHook is an interface for records that defines an AfterUpdate method that is called after updating a record. If AfterUpdate returns an error the update process is cancelled and rolled back.

type AndExpr

type AndExpr struct {
	*adapter.LogicalExprGroup
}

AndExpr represents an expression joined by a logical conjuction (AND).

func And

func And(conds ...LogicalExpr) *AndExpr

And joins conditions under logical conjunction. Conditions can be represented by `db.Cond{}`, `db.Or()` or `db.And()`.

Examples:

// name = "Peter" AND last_name = "Parker"
db.And(
	db.Cond{"name": "Peter"},
	db.Cond{"last_name": "Parker "},
)

// (name = "Peter" OR name = "Mickey") AND last_name = "Mouse"
db.And(
	db.Or(
		db.Cond{"name": "Peter"},
		db.Cond{"name": "Mickey"},
	),
	db.Cond{"last_name": "Mouse"},
)

func (*AndExpr) And

func (a *AndExpr) And(andConds ...LogicalExpr) *AndExpr

And adds more expressions to the group.

func (*AndExpr) Empty

func (a *AndExpr) Empty() bool

Empty returns false if the expressions has zero conditions.

type BatchInserter

type BatchInserter interface {
	// Values pushes column values to be inserted as part of the batch.
	Values(...interface{}) BatchInserter

	// NextResult dumps the next slice of results to dst, which can mean having
	// the IDs of all inserted elements in the batch.
	NextResult(dst interface{}) bool

	// Done signals that no more elements are going to be added.
	Done()

	// Wait blocks until the whole batch is executed.
	Wait() error

	// Err returns the last error that happened while executing the batch (or nil
	// if no error happened).
	Err() error
}

BatchInserter provides an interface to do massive insertions in batches.

type BeforeCreateHook

type BeforeCreateHook interface {
	BeforeCreate(Session) error
}

BeforeCreateHook is an interface for records that defines an BeforeCreate method that is called before creating a record. If BeforeCreate returns an error the create process is cancelled and rolled back.

type BeforeDeleteHook

type BeforeDeleteHook interface {
	BeforeDelete(Session) error
}

BeforeDeleteHook is an interface for records that defines a BeforeDelete method that is called before removing a record. If BeforeDelete returns an error the delete process is cancelled and rolled back.

type BeforeUpdateHook

type BeforeUpdateHook interface {
	BeforeUpdate(Session) error
}

BeforeUpdateHook is an interface for records that defines a BeforeUpdate method that is called before updating a record. If BeforeUpdate returns an error the update process is cancelled and rolled back.

type Collection

type Collection interface {

	// Name returns the name of the collection.
	Name() string

	// Session returns the Session that was used to create the collection
	// reference.
	Session() Session

	// Find defines a new result set.
	Find(...interface{}) Result

	Count() (uint64, error)

	// Insert inserts a new item into the collection, the type of this item could
	// be a map, a struct or pointer to either of them. If the call succeeds and
	// if the collection has a primary key, Insert returns the ID of the newly
	// added element as an `interface{}`. The underlying type of this ID depends
	// on both the database adapter and the column storing the ID.  The ID
	// returned by Insert() could be passed directly to Find() to retrieve the
	// newly added element.
	Insert(interface{}) (*InsertResult, error)

	// InsertReturning is like Insert() but it takes a pointer to map or struct
	// and, if the operation succeeds, updates it with data from the newly
	// inserted row. If the database does not support transactions this method
	// returns db.ErrUnsupported.
	InsertReturning(interface{}) error

	// UpdateReturning takes a pointer to a map or struct and tries to update the
	// row the item is refering to. If the element is updated sucessfully,
	// UpdateReturning will fetch the row and update the fields of the passed
	// item.  If the database does not support transactions this method returns
	// db.ErrUnsupported
	UpdateReturning(interface{}) error

	// Exists returns true if the collection exists, false otherwise.
	Exists() (bool, error)

	// Truncate removes all elements on the collection.
	Truncate() error
}

Collection defines methods to work with database tables or collections.

type Comparison

type Comparison struct {
	*adapter.Comparison
}

Comparison represents a relationship between values.

func After

func After(value time.Time) *Comparison

After is a comparison that means: is after the (time.Time) value.

func Before

func Before(value time.Time) *Comparison

Before is a comparison that means: is before the (time.Time) value.

func Between

func Between(lowerBound interface{}, upperBound interface{}) *Comparison

Between is a comparison that means: is between lowerBound and upperBound.

func Eq

func Eq(value interface{}) *Comparison

Eq is a comparison that means: is equal to value.

func Gt

func Gt(value interface{}) *Comparison

Gt is a comparison that means: is greater than value.

func Gte

func Gte(value interface{}) *Comparison

Gte is a comparison that means: is greater than or equal to value.

func In

func In(value ...interface{}) *Comparison

In is a comparison that means: is any of the values.

func Is

func Is(value interface{}) *Comparison

Is is a comparison that means: is equivalent to nil, true or false.

func IsNot

func IsNot(value interface{}) *Comparison

IsNot is a comparison that means: is not equivalent to nil, true nor false.

func IsNotNull

func IsNotNull() *Comparison

IsNotNull is a comparison that means: is not equivalent to nil.

func IsNull

func IsNull() *Comparison

IsNull is a comparison that means: is equivalent to nil.

func Like

func Like(value string) *Comparison

Like is a comparison that checks whether the reference matches the wildcard value.

func Lt

func Lt(value interface{}) *Comparison

Lt is a comparison that means: is less than value.

func Lte

func Lte(value interface{}) *Comparison

Lte is a comparison that means: is less than or equal to value.

func NotBetween

func NotBetween(lowerBound interface{}, upperBound interface{}) *Comparison

NotBetween is a comparison that means: is not between lowerBound and upperBound.

func NotEq

func NotEq(value interface{}) *Comparison

NotEq is a comparison that means: is not equal to value.

func NotIn

func NotIn(value ...interface{}) *Comparison

NotIn is a comparison that means: is none of the values.

func NotLike

func NotLike(value string) *Comparison

NotLike is a comparison that checks whether the reference does not match the wildcard value.

func NotRegExp

func NotRegExp(value string) *Comparison

NotRegExp is a comparison that checks whether the reference does not match the regular expression.

func OnOrAfter

func OnOrAfter(value time.Time) *Comparison

OnOrAfter is a comparison that means: is on or after the (time.Time) value.

func OnOrBefore

func OnOrBefore(value time.Time) *Comparison

OnOrBefore is a comparison that means: is on or before the (time.Time) value.

func Op

func Op(customOperator string, value interface{}) *Comparison

Op returns a custom comparison operator.

func RegExp

func RegExp(value string) *Comparison

RegExp is a comparison that checks whether the reference matches the regular expression.

type Cond

type Cond map[interface{}]interface{}

Cond is a map that defines conditions for a query.

Each entry of the map represents a condition (a column-value relation bound by a comparison Operator). The comparison can be specified after the column name, if no comparison operator is provided the equality operator is used as default.

Examples:

// Age equals 18.
db.Cond{"age": 18}

// Age is greater than or equal to 18.
db.Cond{"age >=": 18}

// id is any of the values 1, 2 or 3.
db.Cond{"id IN": []{1, 2, 3}}

// Age is lower than 18 (MongoDB syntax)
db.Cond{"age $lt": 18}

// age > 32 and age < 35
db.Cond{"age >": 32, "age <": 35}

func (Cond) Constraints

func (c Cond) Constraints() []adapter.Constraint

Constraints returns each one of the Cond map entires as a constraint.

func (Cond) Empty

func (c Cond) Empty() bool

Empty returns false if there are no conditions.

func (Cond) Expressions

func (c Cond) Expressions() []LogicalExpr

Expressions returns all the expressions contained in the condition.

func (Cond) Operator

func (c Cond) Operator() LogicalOperator

Operator returns the equality operator.

type ConnectionURL

type ConnectionURL interface {
	// String returns the connection string that is going to be passed to the
	// adapter.
	String() string
}

ConnectionURL represents a data source name (DSN).

type Deleter

type Deleter interface {
	// Where represents the WHERE clause.
	//
	// See Selector.Where for documentation and usage examples.
	Where(...interface{}) Deleter

	// And appends more constraints to the WHERE clause without overwriting
	// conditions that have been already set.
	And(conds ...interface{}) Deleter

	// Limit represents the LIMIT clause.
	//
	// See Selector.Limit for documentation and usage examples.
	Limit(int) Deleter

	// Amend lets you alter the query's text just before sending it to the
	// database server.
	Amend(func(queryIn string) (queryOut string)) Deleter

	// SQLPreparer provides methods for creating prepared statements.
	SQLPreparer

	// SQLExecer provides the Exec method.
	SQLExecer

	// fmt.Stringer provides `String() string`, you can use `String()` to compile
	// the `Inserter` into a string.
	fmt.Stringer

	// Arguments returns the arguments that are prepared for this query.
	Arguments() []interface{}
}

Deleter represents a DELETE statement.

type FuncExpr

type FuncExpr = adapter.FuncExpr

FuncExpr represents functions.

func Func

func Func(name string, args ...interface{}) *FuncExpr

Func returns a database function expression.

Examples:

// MOD(29, 9)
db.Func("MOD", 29, 9)

// CONCAT("foo", "bar")
db.Func("CONCAT", "foo", "bar")

// NOW()
db.Func("NOW")

// RTRIM("Hello  ")
db.Func("RTRIM", "Hello  ")

type HasConstraints

type HasConstraints interface {
	Constraints() Cond
}

HasConstraints is an interface for records that defines a Constraints method that returns the record's own constraints.

type ID

type ID interface{}

ID represents a record ID

type InsertResult

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

InsertResult provides infomation about an insert operation.

func NewInsertResult

func NewInsertResult(id interface{}) *InsertResult

NewInsertResult creates an InsertResult

func (*InsertResult) ID

func (r *InsertResult) ID() ID

ID returns the ID of the newly inserted record.

func (InsertResult) Value

func (r InsertResult) Value() (driver.Value, error)

Value satisfies driver.Valuer

type Inserter

type Inserter interface {
	// Columns represents the COLUMNS clause.
	//
	// COLUMNS defines the columns that we are going to provide values for.
	//
	//   i.Columns("name", "last_name").Values(...)
	Columns(...string) Inserter

	// Values represents the VALUES clause.
	//
	// VALUES defines the values of the columns.
	//
	//   i.Columns(...).Values("María", "Méndez")
	//
	//   i.Values(map[string][string]{"name": "María"})
	Values(...interface{}) Inserter

	// Arguments returns the arguments that are prepared for this query.
	Arguments() []interface{}

	// Returning represents a RETURNING clause.
	//
	// RETURNING specifies which columns should be returned after INSERT.
	//
	// RETURNING may not be supported by all SQL databases.
	Returning(columns ...string) Inserter

	// Iterator provides methods to iterate over the results returned by the
	// Inserter. This is only possible when using Returning().
	Iterator() Iterator

	// IteratorContext provides methods to iterate over the results returned by
	// the Inserter. This is only possible when using Returning().
	IteratorContext(ctx context.Context) Iterator

	// Amend lets you alter the query's text just before sending it to the
	// database server.
	Amend(func(queryIn string) (queryOut string)) Inserter

	// Batch provies a BatchInserter that can be used to insert many elements at
	// once by issuing several calls to Values(). It accepts a size parameter
	// which defines the batch size. If size is < 1, the batch size is set to 1.
	Batch(size int) BatchInserter

	// SQLExecer provides the Exec method.
	SQLExecer

	// SQLPreparer provides methods for creating prepared statements.
	SQLPreparer

	// SQLGetter provides methods to return query results from INSERT statements
	// that support such feature (e.g.: queries with Returning).
	SQLGetter

	// fmt.Stringer provides `String() string`, you can use `String()` to compile
	// the `Inserter` into a string.
	fmt.Stringer
}

Inserter represents an INSERT statement.

type Iterator

type Iterator interface {
	// ResultMapper provides methods to retrieve and map results.
	ResultMapper

	// Scan dumps the current result into the given pointer variable pointers.
	Scan(dest ...interface{}) error

	// NextScan advances the iterator and performs Scan.
	NextScan(dest ...interface{}) error

	// ScanOne advances the iterator, performs Scan and closes the iterator.
	ScanOne(dest ...interface{}) error

	// Next dumps the current element into the given destination, which could be
	// a pointer to either a map or a struct.
	Next(dest ...interface{}) bool

	// Err returns the last error produced by the cursor.
	Err() error

	// Close closes the iterator and frees up the cursor.
	Close() error
}

Iterator provides methods for iterating over query results.

type LogLevel

type LogLevel int8

LogLevel represents a verbosity level for logs

const (
	LogLevelTrace LogLevel = -1

	LogLevelDebug LogLevel = iota
	LogLevelInfo
	LogLevelWarn
	LogLevelError
	LogLevelFatal
	LogLevelPanic
)

Log levels

func (LogLevel) String

func (ll LogLevel) String() string

type Logger

type Logger interface {
	Fatal(v ...interface{})
	Fatalf(format string, v ...interface{})

	Print(v ...interface{})
	Printf(format string, v ...interface{})

	Panic(v ...interface{})
	Panicf(format string, v ...interface{})
}

Logger represents a logging interface that is compatible with the standard "log" and with many other logging libraries.

type LoggingCollector

type LoggingCollector interface {
	Enabled(LogLevel) bool

	Level() LogLevel

	SetLogger(Logger)
	SetLevel(LogLevel)

	Trace(v ...interface{})
	Tracef(format string, v ...interface{})

	Debug(v ...interface{})
	Debugf(format string, v ...interface{})

	Info(v ...interface{})
	Infof(format string, v ...interface{})

	Warn(v ...interface{})
	Warnf(format string, v ...interface{})

	Error(v ...interface{})
	Errorf(format string, v ...interface{})

	Fatal(v ...interface{})
	Fatalf(format string, v ...interface{})

	Panic(v ...interface{})
	Panicf(format string, v ...interface{})
}

LoggingCollector provides different methods for collecting and classifying log messages.

func LC

func LC() LoggingCollector

LC returns the logging collector.

type LogicalExpr

type LogicalExpr = adapter.LogicalExpr

LogicalExpr represents an expression to be used in logical statements.

type LogicalOperator

type LogicalOperator = adapter.LogicalOperator

LogicalOperator represents a logical operation.

type Marshaler

type Marshaler interface {
	// MarshalDB returns the internal database representation of the Go value.
	MarshalDB() (interface{}, error)
}

Marshaler is the interface implemented by struct fields that can transform themselves into values to be stored in a database.

type OrExpr

type OrExpr struct {
	*adapter.LogicalExprGroup
}

OrExpr represents a logical expression joined by logical disjunction (OR).

func Or

func Or(conds ...LogicalExpr) *OrExpr

Or joins conditions under logical disjunction. Conditions can be represented by `db.Cond{}`, `db.Or()` or `db.And()`.

Example:

// year = 2012 OR year = 1987
db.Or(
	db.Cond{"year": 2012},
	db.Cond{"year": 1987},
)

func (*OrExpr) Empty

func (o *OrExpr) Empty() bool

Empty returns false if the expressions has zero conditions.

func (*OrExpr) Or

func (o *OrExpr) Or(orConds ...LogicalExpr) *OrExpr

Or adds more expressions to the group.

type Paginator

type Paginator interface {
	// Page sets the page number.
	Page(uint) Paginator

	// Cursor defines the column that is going to be taken as basis for
	// cursor-based pagination.
	//
	// Example:
	//
	//   a = q.Paginate(10).Cursor("id")
	//	 b = q.Paginate(12).Cursor("-id")
	//
	// You can set "" as cursorColumn to disable cursors.
	Cursor(cursorColumn string) Paginator

	// NextPage returns the next page according to the cursor. It expects a
	// cursorValue, which is the value the cursor column has on the last item of
	// the current result set (lower bound).
	//
	// Example:
	//
	//   p = q.NextPage(items[len(items)-1].ID)
	NextPage(cursorValue interface{}) Paginator

	// PrevPage returns the previous page according to the cursor. It expects a
	// cursorValue, which is the value the cursor column has on the fist item of
	// the current result set (upper bound).
	//
	// Example:
	//
	//   p = q.PrevPage(items[0].ID)
	PrevPage(cursorValue interface{}) Paginator

	// TotalPages returns the total number of pages in the query.
	TotalPages() (uint, error)

	// TotalEntries returns the total number of entries in the query.
	TotalEntries() (uint64, error)

	// SQLPreparer provides methods for creating prepared statements.
	SQLPreparer

	// SQLGetter provides methods to compile and execute a query that returns
	// results.
	SQLGetter

	// Iterator provides methods to iterate over the results returned by the
	// Selector.
	Iterator() Iterator

	// IteratorContext provides methods to iterate over the results returned by
	// the Selector.
	IteratorContext(ctx context.Context) Iterator

	// ResultMapper provides methods to retrieve and map results.
	ResultMapper

	// fmt.Stringer provides `String() string`, you can use `String()` to compile
	// the `Selector` into a string.
	fmt.Stringer

	// Arguments returns the arguments that are prepared for this query.
	Arguments() []interface{}
}

Paginator provides tools for splitting the results of a query into chunks containing a fixed number of items.

type RawExpr

type RawExpr = adapter.RawExpr

RawExpr represents a raw (non-filtered) expression.

func Raw

func Raw(value string, args ...interface{}) *RawExpr

Raw marks chunks of data as protected, so they pass directly to the query without any filtering. Use with care.

Example:

// SOUNDEX('Hello')
Raw("SOUNDEX('Hello')")

type Record

type Record interface {
	Store(sess Session) Store
}

Record is the equivalence between concrete database schemas and Go values.

type Result

type Result interface {

	// String returns the SQL statement to be used in the query.
	String() string

	// Limit defines the maximum number of results for this set. It only has
	// effect on `One()`, `All()` and `Next()`. A negative limit cancels any
	// previous limit settings.
	Limit(int) Result

	// Offset ignores the first n results. It only has effect on `One()`, `All()`
	// and `Next()`. A negative offset cancels any previous offset settings.
	Offset(int) Result

	// OrderBy receives one or more field names that define the order in which
	// elements will be returned in a query, field names may be prefixed with a
	// minus sign (-) indicating descending order, ascending order will be used
	// otherwise.
	OrderBy(...interface{}) Result

	// Select defines specific columns to be fetched on every column in the
	// result set.
	Select(...interface{}) Result

	// And adds more filtering conditions on top of the existing constraints.
	//
	//   res := col.Find(...).And(...)
	And(...interface{}) Result

	// GroupBy is used to group results that have the same value in the same column
	// or columns.
	GroupBy(...interface{}) Result

	// Delete deletes all items within the result set. `Offset()` and `Limit()`
	// are not honoured by `Delete()`.
	Delete() error

	// Update modifies all items within the result set. `Offset()` and `Limit()`
	// are not honoured by `Update()`.
	Update(interface{}) error

	// Count returns the number of items that match the set conditions.
	// `Offset()` and `Limit()` are not honoured by `Count()`
	Count() (uint64, error)

	// Exists returns true if at least one item on the collection exists. False
	// otherwise.
	Exists() (bool, error)

	// Next fetches the next result within the result set and dumps it into the
	// given pointer to struct or pointer to map. You must call
	// `Close()` after finishing using `Next()`.
	Next(ptrToStruct interface{}) bool

	// Err returns the last error that has happened with the result set, nil
	// otherwise.
	Err() error

	// One fetches the first result within the result set and dumps it into the
	// given pointer to struct or pointer to map. The result set is automatically
	// closed after picking the element, so there is no need to call Close()
	// after using One().
	One(ptrToStruct interface{}) error

	// All fetches all results within the result set and dumps them into the
	// given pointer to slice of maps or structs.  The result set is
	// automatically closed, so there is no need to call Close() after
	// using All().
	All(sliceOfStructs interface{}) error

	// Paginate splits the results of the query into pages containing pageSize
	// items. When using pagination previous settings for `Limit()` and
	// `Offset()` are ignored. Page numbering starts at 1.
	//
	// Use `Page()` to define the specific page to get results from.
	//
	// Example:
	//
	//   r = q.Paginate(12)
	//
	// You can provide constraints an order settings when using pagination:
	//
	// Example:
	//
	//   res := q.Where(conds).OrderBy("-id").Paginate(12)
	//   err := res.Page(4).All(&items)
	Paginate(pageSize uint) Result

	// Page makes the result set return results only from the page identified by
	// pageNumber. Page numbering starts from 0.
	//
	// Example:
	//
	//   r = q.Paginate(12).Page(4)
	Page(pageNumber uint) Result

	// Cursor defines the column that is going to be taken as basis for
	// cursor-based pagination.
	//
	// Example:
	//
	//   a = q.Paginate(10).Cursor("id")
	//   b = q.Paginate(12).Cursor("-id")
	//
	// You can set "" as cursorColumn to disable cursors.
	Cursor(cursorColumn string) Result

	// NextPage returns the next results page according to the cursor. It expects
	// a cursorValue, which is the value the cursor column had on the last item
	// of the current result set (lower bound).
	//
	// Example:
	//
	//   cursor = q.Paginate(12).Cursor("id")
	//   res = cursor.NextPage(items[len(items)-1].ID)
	//
	// Note that `NextPage()` requires a cursor, any column with an absolute
	// order (given two values one always precedes the other) can be a cursor.
	//
	// You can define the pagination order and add constraints to your result:
	//
	//	 cursor = q.Where(...).OrderBy("id").Paginate(10).Cursor("id")
	//   res = cursor.NextPage(lowerBound)
	NextPage(cursorValue interface{}) Result

	// PrevPage returns the previous results page according to the cursor. It
	// expects a cursorValue, which is the value the cursor column had on the
	// fist item of the current result set.
	//
	// Example:
	//
	//   current = current.PrevPage(items[0].ID)
	//
	// Note that PrevPage requires a cursor, any column with an absolute order
	// (given two values one always precedes the other) can be a cursor.
	//
	// You can define the pagination order and add constraints to your result:
	//
	//   cursor = q.Where(...).OrderBy("id").Paginate(10).Cursor("id")
	//   res = cursor.PrevPage(upperBound)
	PrevPage(cursorValue interface{}) Result

	// TotalPages returns the total number of pages the result set could produce.
	// If no pagination parameters have been set this value equals 1.
	TotalPages() (uint, error)

	// TotalEntries returns the total number of matching items in the result set.
	TotalEntries() (uint64, error)

	// Close closes the result set and frees all locked resources.
	Close() error
}

Result is an interface that defines methods for result sets.

type ResultMapper

type ResultMapper interface {
	// All dumps all the results into the given slice, All() expects a pointer to
	// slice of maps or structs.
	//
	// The behaviour of One() extends to each one of the results.
	All(destSlice interface{}) error

	// One maps the row that is in the current query cursor into the
	// given interface, which can be a pointer to either a map or a
	// struct.
	//
	// If dest is a pointer to map, each one of the columns will create a new map
	// key and the values of the result will be set as values for the keys.
	//
	// Depending on the type of map key and value, the results columns and values
	// may need to be transformed.
	//
	// If dest if a pointer to struct, each one of the fields will be tested for
	// a `db` tag which defines the column mapping. The value of the result will
	// be set as the value of the field.
	One(dest interface{}) error
}

ResultMapper defined methods for a result mapper.

type SQL

type SQL interface {

	// Select initializes and returns a Selector, it accepts column names as
	// parameters.
	//
	// The returned Selector does not initially point to any table, a call to
	// From() is required after Select() to complete a valid query.
	//
	// Example:
	//
	//  q := sqlbuilder.Select("first_name", "last_name").From("people").Where(...)
	Select(columns ...interface{}) Selector

	// SelectFrom creates a Selector that selects all columns (like SELECT *)
	// from the given table.
	//
	// Example:
	//
	//  q := sqlbuilder.SelectFrom("people").Where(...)
	SelectFrom(table ...interface{}) Selector

	// InsertInto prepares and returns an Inserter targeted at the given table.
	//
	// Example:
	//
	//   q := sqlbuilder.InsertInto("books").Columns(...).Values(...)
	InsertInto(table string) Inserter

	// DeleteFrom prepares a Deleter targeted at the given table.
	//
	// Example:
	//
	//  q := sqlbuilder.DeleteFrom("tasks").Where(...)
	DeleteFrom(table string) Deleter

	// Update prepares and returns an Updater targeted at the given table.
	//
	// Example:
	//
	//  q := sqlbuilder.Update("profile").Set(...).Where(...)
	Update(table string) Updater

	// Exec executes a SQL query that does not return any rows, like sql.Exec.
	// Queries can be either strings or upper-db statements.
	//
	// Example:
	//
	//  sqlbuilder.Exec(`INSERT INTO books (title) VALUES("La Ciudad y los Perros")`)
	Exec(query interface{}, args ...interface{}) (sql.Result, error)

	// ExecContext executes a SQL query that does not return any rows, like sql.ExecContext.
	// Queries can be either strings or upper-db statements.
	//
	// Example:
	//
	//  sqlbuilder.ExecContext(ctx, `INSERT INTO books (title) VALUES(?)`, "La Ciudad y los Perros")
	ExecContext(ctx context.Context, query interface{}, args ...interface{}) (sql.Result, error)

	// Prepare creates a prepared statement for later queries or executions. The
	// caller must call the statement's Close method when the statement is no
	// longer needed.
	Prepare(query interface{}) (*sql.Stmt, error)

	// Prepare creates a prepared statement on the guiven context for later
	// queries or executions. The caller must call the statement's Close method
	// when the statement is no longer needed.
	PrepareContext(ctx context.Context, query interface{}) (*sql.Stmt, error)

	// Query executes a SQL query that returns rows, like sql.Query.  Queries can
	// be either strings or upper-db statements.
	//
	// Example:
	//
	//  sqlbuilder.Query(`SELECT * FROM people WHERE name = "Mateo"`)
	Query(query interface{}, args ...interface{}) (*sql.Rows, error)

	// QueryContext executes a SQL query that returns rows, like
	// sql.QueryContext.  Queries can be either strings or upper-db statements.
	//
	// Example:
	//
	//  sqlbuilder.QueryContext(ctx, `SELECT * FROM people WHERE name = ?`, "Mateo")
	QueryContext(ctx context.Context, query interface{}, args ...interface{}) (*sql.Rows, error)

	// QueryRow executes a SQL query that returns one row, like sql.QueryRow.
	// Queries can be either strings or upper-db statements.
	//
	// Example:
	//
	//  sqlbuilder.QueryRow(`SELECT * FROM people WHERE name = "Haruki" AND last_name = "Murakami" LIMIT 1`)
	QueryRow(query interface{}, args ...interface{}) (*sql.Row, error)

	// QueryRowContext executes a SQL query that returns one row, like
	// sql.QueryRowContext.  Queries can be either strings or upper-db statements.
	//
	// Example:
	//
	//  sqlbuilder.QueryRowContext(ctx, `SELECT * FROM people WHERE name = "Haruki" AND last_name = "Murakami" LIMIT 1`)
	QueryRowContext(ctx context.Context, query interface{}, args ...interface{}) (*sql.Row, error)

	// Iterator executes a SQL query that returns rows and creates an Iterator
	// with it.
	//
	// Example:
	//
	//  sqlbuilder.Iterator(`SELECT * FROM people WHERE name LIKE "M%"`)
	Iterator(query interface{}, args ...interface{}) Iterator

	// IteratorContext executes a SQL query that returns rows and creates an Iterator
	// with it.
	//
	// Example:
	//
	//  sqlbuilder.IteratorContext(ctx, `SELECT * FROM people WHERE name LIKE "M%"`)
	IteratorContext(ctx context.Context, query interface{}, args ...interface{}) Iterator

	// NewIterator converts a *sql.Rows value into an Iterator.
	NewIterator(rows *sql.Rows) Iterator

	// NewIteratorContext converts a *sql.Rows value into an Iterator.
	NewIteratorContext(ctx context.Context, rows *sql.Rows) Iterator
}

SQL defines methods that can be used to build a SQL query with chainable method calls.

Queries are immutable, so every call to any method will return a new pointer, if you want to build a query using variables you need to reassign them, like this:

a = builder.Select("name").From("foo") // "a" is created

a.Where(...) // No effect, the value returned from Where is ignored.

a = a.Where(...) // "a" is reassigned and points to a different address.

type SQLEngine

type SQLEngine interface {
	Exec(string, ...interface{}) (sql.Result, error)
	Prepare(string) (*sql.Stmt, error)
	Query(string, ...interface{}) (*sql.Rows, error)
	QueryRow(string, ...interface{}) *sql.Row

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

SQLEngine represents a SQL engine that can execute SQL queries. This is compatible with *sql.DB.

type SQLExecer

type SQLExecer interface {
	// Exec executes a statement and returns sql.Result.
	Exec() (sql.Result, error)

	// ExecContext executes a statement and returns sql.Result.
	ExecContext(context.Context) (sql.Result, error)
}

SQLExecer provides methods for executing statements that do not return results.

type SQLGetter

type SQLGetter interface {
	// Query returns *sql.Rows.
	Query() (*sql.Rows, error)

	// QueryContext returns *sql.Rows.
	QueryContext(context.Context) (*sql.Rows, error)

	// QueryRow returns only one row.
	QueryRow() (*sql.Row, error)

	// QueryRowContext returns only one row.
	QueryRowContext(ctx context.Context) (*sql.Row, error)
}

SQLGetter provides methods for executing statements that return results.

type SQLPreparer

type SQLPreparer interface {
	// Prepare creates a prepared statement.
	Prepare() (*sql.Stmt, error)

	// PrepareContext creates a prepared statement.
	PrepareContext(context.Context) (*sql.Stmt, error)
}

SQLPreparer provides the Prepare and PrepareContext methods for creating prepared statements.

type Selector

type Selector interface {
	// Columns defines which columns to retrive.
	//
	// You should call From() after Columns() if you want to query data from an
	// specific table.
	//
	//   s.Columns("name", "last_name").From(...)
	//
	// It is also possible to use an alias for the column, this could be handy if
	// you plan to use the alias later, use the "AS" keyword to denote an alias.
	//
	//   s.Columns("name AS n")
	//
	// or the shortcut:
	//
	//   s.Columns("name n")
	//
	// If you don't want the column to be escaped use the db.Raw
	// function.
	//
	//   s.Columns(db.Raw("MAX(id)"))
	//
	// The above statement is equivalent to:
	//
	//   s.Columns(db.Func("MAX", "id"))
	Columns(columns ...interface{}) Selector

	// From represents a FROM clause and is tipically used after Columns().
	//
	// FROM defines from which table data is going to be retrieved
	//
	//   s.Columns(...).From("people")
	//
	// It is also possible to use an alias for the table, this could be handy if
	// you plan to use the alias later:
	//
	//   s.Columns(...).From("people AS p").Where("p.name = ?", ...)
	//
	// Or with the shortcut:
	//
	//   s.Columns(...).From("people p").Where("p.name = ?", ...)
	From(tables ...interface{}) Selector

	// Distict represents a DISTINCT clause
	//
	// DISTINCT is used to ask the database to return only values that are
	// different.
	Distinct(columns ...interface{}) Selector

	// As defines an alias for a table.
	As(string) Selector

	// Where specifies the conditions that columns must match in order to be
	// retrieved.
	//
	// Where accepts raw strings and fmt.Stringer to define conditions and
	// interface{} to specify parameters. Be careful not to embed any parameters
	// within the SQL part as that could lead to security problems. You can use
	// que question mark (?) as placeholder for parameters.
	//
	//   s.Where("name = ?", "max")
	//
	//   s.Where("name = ? AND last_name = ?", "Mary", "Doe")
	//
	//   s.Where("last_name IS NULL")
	//
	// You can also use other types of parameters besides only strings, like:
	//
	//   s.Where("online = ? AND last_logged <= ?", true, time.Now())
	//
	// and Where() will transform them into strings before feeding them to the
	// database.
	//
	// When an unknown type is provided, Where() will first try to match it with
	// the Marshaler interface, then with fmt.Stringer and finally, if the
	// argument does not satisfy any of those interfaces Where() will use
	// fmt.Sprintf("%v", arg) to transform the type into a string.
	//
	// Subsequent calls to Where() will overwrite previously set conditions, if
	// you want these new conditions to be appended use And() instead.
	Where(conds ...interface{}) Selector

	// And appends more constraints to the WHERE clause without overwriting
	// conditions that have been already set.
	And(conds ...interface{}) Selector

	// GroupBy represents a GROUP BY statement.
	//
	// GROUP BY defines which columns should be used to aggregate and group
	// results.
	//
	//   s.GroupBy("country_id")
	//
	// GroupBy accepts more than one column:
	//
	//   s.GroupBy("country_id", "city_id")
	GroupBy(columns ...interface{}) Selector

	// OrderBy represents a ORDER BY statement.
	//
	// ORDER BY is used to define which columns are going to be used to sort
	// results.
	//
	// Use the column name to sort results in ascendent order.
	//
	//   // "last_name" ASC
	//   s.OrderBy("last_name")
	//
	// Prefix the column name with the minus sign (-) to sort results in
	// descendent order.
	//
	//   // "last_name" DESC
	//   s.OrderBy("-last_name")
	//
	// If you would rather be very explicit, you can also use ASC and DESC.
	//
	//   s.OrderBy("last_name ASC")
	//
	//   s.OrderBy("last_name DESC", "name ASC")
	OrderBy(columns ...interface{}) Selector

	// Join represents a JOIN statement.
	//
	// JOIN statements are used to define external tables that the user wants to
	// include as part of the result.
	//
	// You can use the On() method after Join() to define the conditions of the
	// join.
	//
	//   s.Join("author").On("author.id = book.author_id")
	//
	// If you don't specify conditions for the join, a NATURAL JOIN will be used.
	//
	// On() accepts the same arguments as Where()
	//
	// You can also use Using() after Join().
	//
	//   s.Join("employee").Using("department_id")
	Join(table ...interface{}) Selector

	// FullJoin is like Join() but with FULL JOIN.
	FullJoin(...interface{}) Selector

	// CrossJoin is like Join() but with CROSS JOIN.
	CrossJoin(...interface{}) Selector

	// RightJoin is like Join() but with RIGHT JOIN.
	RightJoin(...interface{}) Selector

	// LeftJoin is like Join() but with LEFT JOIN.
	LeftJoin(...interface{}) Selector

	// Using represents the USING clause.
	//
	// USING is used to specifiy columns to join results.
	//
	//   s.LeftJoin(...).Using("country_id")
	Using(...interface{}) Selector

	// On represents the ON clause.
	//
	// ON is used to define conditions on a join.
	//
	//   s.Join(...).On("b.author_id = a.id")
	On(...interface{}) Selector

	// Limit represents the LIMIT parameter.
	//
	// LIMIT defines the maximum number of rows to return from the table.  A
	// negative limit cancels any previous limit settings.
	//
	//  s.Limit(42)
	Limit(int) Selector

	// Offset represents the OFFSET parameter.
	//
	// OFFSET defines how many results are going to be skipped before starting to
	// return results. A negative offset cancels any previous offset settings.
	//
	// s.Offset(56)
	Offset(int) Selector

	// Amend lets you alter the query's text just before sending it to the
	// database server.
	Amend(func(queryIn string) (queryOut string)) Selector

	// Paginate returns a paginator that can display a paginated lists of items.
	// Paginators ignore previous Offset and Limit settings. Page numbering
	// starts at 1.
	Paginate(uint) Paginator

	// Iterator provides methods to iterate over the results returned by the
	// Selector.
	Iterator() Iterator

	// IteratorContext provides methods to iterate over the results returned by
	// the Selector.
	IteratorContext(ctx context.Context) Iterator

	// SQLPreparer provides methods for creating prepared statements.
	SQLPreparer

	// SQLGetter provides methods to compile and execute a query that returns
	// results.
	SQLGetter

	// ResultMapper provides methods to retrieve and map results.
	ResultMapper

	// fmt.Stringer provides `String() string`, you can use `String()` to compile
	// the `Selector` into a string.
	fmt.Stringer

	// Arguments returns the arguments that are prepared for this query.
	Arguments() []interface{}
}

Selector represents a SELECT statement.

type Session

type Session interface {
	// ConnectionURL returns the DSN that was used to set up the adapter.
	ConnectionURL() ConnectionURL

	// Name returns the name of the database.
	Name() string

	// Ping returns an error if the DBMS could not be reached.
	Ping() error

	// Collection receives a table name and returns a collection reference. The
	// information retrieved from a collection is cached.
	Collection(name string) Collection

	// Collections returns a collection reference of all non system tables on the
	// database.
	Collections() ([]Collection, error)

	// Save creates or updates a record.
	Save(record Record) error

	// Get retrieves a record that matches the given condition.
	Get(record Record, cond interface{}) error

	// Delete deletes a record.
	Delete(record Record) error

	// Reset resets all the caching mechanisms the adapter is using.
	Reset()

	// Close terminates the currently active connection to the DBMS and clears
	// all caches.
	Close() error

	// Driver returns the underlying driver of the adapter as an interface.
	//
	// In order to actually use the driver, the `interface{}` value needs to be
	// casted into the appropriate type.
	//
	// Example:
	//  internalSQLDriver := sess.Driver().(*sql.DB)
	Driver() interface{}

	// SQL returns a special interface for SQL databases.
	SQL() SQL

	// Tx creates a transaction block on the default database context and passes
	// it to the function fn. If fn returns no error the transaction is commited,
	// else the transaction is rolled back. After being commited or rolled back
	// the transaction is closed automatically.
	Tx(fn func(sess Session) error) error

	// TxContext creates a transaction block on the given context and passes it to
	// the function fn. If fn returns no error the transaction is commited, else
	// the transaction is rolled back. After being commited or rolled back the
	// transaction is closed automatically.
	TxContext(ctx context.Context, fn func(sess Session) error, opts *sql.TxOptions) error

	// Context returns the context used as default for queries on this session
	// and for new transactions.  If no context has been set, a default
	// context.Background() is returned.
	Context() context.Context

	// WithContext returns a copy of the session that uses the given context as
	// default. Copies are safe to use concurrently but they're backed by the
	// same Session. You may close a copy at any point but that won't close the
	// parent session.
	WithContext(ctx context.Context) Session

	Settings
}

Session is an interface that defines methods for database adapters.

func Open

func Open(adapterName string, settings ConnectionURL) (Session, error)

Open attempts to stablish a connection with a database.

type Settings

type Settings interface {
	// SetPreparedStatementCache enables or disables the prepared statement
	// cache.
	SetPreparedStatementCache(bool)

	// PreparedStatementCacheEnabled returns true if the prepared statement cache
	// is enabled, false otherwise.
	PreparedStatementCacheEnabled() bool

	// SetConnMaxLifetime sets the default maximum amount of time a connection
	// may be reused.
	SetConnMaxLifetime(time.Duration)

	// ConnMaxLifetime returns the default maximum amount of time a connection
	// may be reused.
	ConnMaxLifetime() time.Duration

	// SetMaxIdleConns sets the default maximum number of connections in the idle
	// connection pool.
	SetMaxIdleConns(int)

	// MaxIdleConns returns the default maximum number of connections in the idle
	// connection pool.
	MaxIdleConns() int

	// SetMaxOpenConns sets the default maximum number of open connections to the
	// database.
	SetMaxOpenConns(int)

	// MaxOpenConns returns the default maximum number of open connections to the
	// database.
	MaxOpenConns() int

	// SetMaxTransactionRetries sets the number of times a transaction can
	// be retried.
	SetMaxTransactionRetries(int)

	// MaxTransactionRetries returns the maximum number of times a
	// transaction can be retried.
	MaxTransactionRetries() int
}

Settings defines methods to get or set configuration values.

var DefaultSettings Settings = &settings{
	preparedStatementCacheEnabled: 0,
	connMaxLifetime:               time.Duration(0),
	maxIdleConns:                  10,
	maxOpenConns:                  0,
	maxTransactionRetries:         1,
}

DefaultSettings provides default global configuration settings for database sessions.

func NewSettings

func NewSettings() Settings

NewSettings returns a new settings value prefilled with the current default settings.

type Store

type Store interface {
	Collection
}

Store represents a data store.

type StoreCreator

type StoreCreator interface {
	Create(record Record) error
}

StoreCreator is an interface for data stores that defines a Create method that has the task of creating a new record.

type StoreDeleter

type StoreDeleter interface {
	Delete(record Record) error
}

StoreDeleter is an interface for data stores that defines a Delete method that has the task of removing a record.

type StoreGetter

type StoreGetter interface {
	Get(record Record, id interface{}) error
}

StoreGetter is an interface for data stores that defines a Get method that has the task of retrieving a record.

type StoreSaver

type StoreSaver interface {
	Save(record Record) error
}

StoreSaver is an interface for data stores that defines a Save method that has the task of persisting a record.

type StoreUpdater

type StoreUpdater interface {
	Update(record Record) error
}

StoreUpdater is an interface for data stores that defines a Update method that has the task of updating a record.

type Unmarshaler

type Unmarshaler interface {
	// UnmarshalDB receives an internal database representation of a value and
	// transforms it into a Go value.
	UnmarshalDB(interface{}) error
}

Unmarshaler is the interface implemented by struct fields that can transform themselves from database values into Go values.

type Updater

type Updater interface {
	// Set represents the SET clause.
	Set(...interface{}) Updater

	// Where represents the WHERE clause.
	//
	// See Selector.Where for documentation and usage examples.
	Where(...interface{}) Updater

	// And appends more constraints to the WHERE clause without overwriting
	// conditions that have been already set.
	And(conds ...interface{}) Updater

	// Limit represents the LIMIT parameter.
	//
	// See Selector.Limit for documentation and usage examples.
	Limit(int) Updater

	// SQLPreparer provides methods for creating prepared statements.
	SQLPreparer

	// SQLExecer provides the Exec method.
	SQLExecer

	// fmt.Stringer provides `String() string`, you can use `String()` to compile
	// the `Inserter` into a string.
	fmt.Stringer

	// Arguments returns the arguments that are prepared for this query.
	Arguments() []interface{}

	// Amend lets you alter the query's text just before sending it to the
	// database server.
	Amend(func(queryIn string) (queryOut string)) Updater
}

Updater represents an UPDATE statement.

type Validator

type Validator interface {
	Validate() error
}

Validator is an interface for records that defines an (optional) Validate method that is called before persisting a record (creating or updating). If Validate returns an error the current operation is cancelled and rolled back.

Directories

Path Synopsis
adapter/cockroachdb Package cockroachdb wraps the github.com/lib/pq driver and provides a compatibility later with CockroachDB.
adapter/mongo Package mongo wraps the gopkg.in/mgo.v2 MongoDB driver.
adapter/mssql Package mssql wraps the github.com/go-sql-driver/mssql MySQL driver.
adapter/mysql Package mysql wraps the github.com/go-sql-driver/mysql MySQL driver.
adapter/postgresql Package postgresql wraps the github.com/lib/pq PostgreSQL driver.
adapter/ql Package ql wraps the modernc.org/ql/driver QL driver.
adapter/sqlite Package sqlite wraps the github.com/lib/sqlite SQLite driver.
internal/adapter
internal/cache
internal/cache/hashstructure
internal/immutable
internal/reflectx Package reflectx implements extensions to the standard reflect lib suitable for implementing marshaling and unmarshaling packages.
internal/sqladapter Package sqladapter provides common logic for SQL adapters.
internal/sqladapter/compat
internal/sqladapter/exql
internal/sqlbuilder Package sqlbuilder provides tools for building custom SQL queries.
internal/testsuite