Documentation ¶
Overview ¶
Package sqlbuilder provides tools for building custom SQL queries.
Index ¶
- Variables
- func Map(item interface{}, options *MapOptions) ([]string, []interface{}, error)
- func Preprocess(in string, args []interface{}) (string, []interface{})
- func RegisterAdapter(name string, adapter *AdapterFuncMap)
- type AdapterFuncMap
- type BatchInserter
- type Database
- type Deleter
- type Execer
- type Getter
- type Inserter
- type Iterator
- type MapOptions
- type Paginator
- type Preparer
- type ResultMapper
- type SQLBuilder
- type ScannerValuer
- type Selector
- type Tx
- type Updater
- type ValueWrapper
Constants ¶
This section is empty.
Variables ¶
var ( // ValuerType is the reflection type for the driver.Valuer interface. ValuerType = reflect.TypeOf((*driver.Valuer)(nil)).Elem() // ScannerType is the reflection type for the sql.Scanner interface. ScannerType = reflect.TypeOf((*sql.Scanner)(nil)).Elem() // ValueWrapperType is the reflection type for the sql.ValueWrapper interface. ValueWrapperType = reflect.TypeOf((*ValueWrapper)(nil)).Elem() )
var ( ErrExpectingPointer = errors.New(`argument must be an address`) ErrExpectingSlicePointer = errors.New(`argument must be a slice address`) ErrExpectingSliceMapStruct = errors.New(`argument must be a slice address of maps or structs`) ErrExpectingMapOrStruct = errors.New(`argument must be either a map or a struct`) ErrExpectingPointerToEitherMapOrStruct = errors.New(`expecting a pointer to either a map or a struct`) )
Common error messages.
Functions ¶
func Map ¶
func Map(item interface{}, options *MapOptions) ([]string, []interface{}, error)
Map receives a pointer to map or struct and maps it to columns and values.
func Preprocess ¶
Preprocess expands arguments that needs to be expanded and compiles a query into a single string.
func RegisterAdapter ¶
func RegisterAdapter(name string, adapter *AdapterFuncMap)
RegisterAdapter registers a SQL database adapter. This function must be called from adapter packages upon initialization. RegisterAdapter calls RegisterAdapter automatically.
Types ¶
type AdapterFuncMap ¶
type AdapterFuncMap struct { New func(sqlDB *sql.DB) (Database, error) NewTx func(sqlTx *sql.Tx) (Tx, error) Open func(settings db.ConnectionURL) (Database, error) }
AdapterFuncMap is a struct that defines a set of functions that adapters need to provide.
type BatchInserter ¶
type BatchInserter struct {
// contains filtered or unexported fields
}
BatchInserter provides a helper that can be used to do massive insertions in batches.
func (*BatchInserter) Done ¶
func (b *BatchInserter) Done()
Done means that no more elements are going to be added.
func (*BatchInserter) Err ¶
func (b *BatchInserter) Err() error
Err returns any error while executing the batch.
func (*BatchInserter) NextResult ¶
func (b *BatchInserter) NextResult(dst interface{}) bool
NextResult is useful when using PostgreSQL and Returning(), it dumps the next slice of results to dst, which can mean having the IDs of all inserted elements in the batch.
func (*BatchInserter) Values ¶
func (b *BatchInserter) Values(values ...interface{}) *BatchInserter
Values pushes column values to be inserted as part of the batch.
func (*BatchInserter) Wait ¶
func (b *BatchInserter) Wait() error
Wait blocks until the whole batch is executed.
type Database ¶
type Database interface { // All db.Database methods are available on this session. db.Database // All SQLBuilder methods are available on this session. SQLBuilder // NewTx creates and returns a transaction that runs on the given context. // If a nil context is given, then the transaction will use the session's // default context. The user is responsible for committing or rolling back // the session. NewTx(ctx context.Context) (Tx, error) // Tx creates a new transaction that is passed as argument to the fn // function. The fn function defines a transactional operation. If the fn // function returns nil, the transaction is committed, else the transaction // is rolled back. The transaction session is closed after the function // exits, regardless of the error value returned by fn. Tx(ctx context.Context, fn func(sess Tx) error) 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 *sql.DB. You may close a copy at any point but that won't close the // parent session. WithContext(context.Context) Database // SetTxOptions sets the default TxOptions that is going to be used for new // transactions created in the session. SetTxOptions(sql.TxOptions) // TxOptions returns the defaultx TxOptions. TxOptions() *sql.TxOptions }
Database represents a SQL database.
func New ¶
New wraps an active *sql.DB session and returns a SQLBuilder database. The adapter needs to be imported to the blank namespace in order for it to be used here.
This method is internally used by upper-db to create a builder backed by the given database. You may want to use your adapter's New function instead of this one.
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 // Preparer provides methods for creating prepared statements. Preparer // Execer provides the Exec method. Execer // 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 Execer ¶
type Execer 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) }
Execer provides methods for executing statements that do not return results.
type Getter ¶
type Getter 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) }
Getter provides methods for executing statements that return results.
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 // Execer provides the Exec method. Execer // Preparer provides methods for creating prepared statements. Preparer // Getter provides methods to return query results from INSERT statements // that support such feature (e.g.: queries with Returning). Getter // 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.
func NewIterator ¶
NewIterator creates an iterator using the given *sql.Rows.
type MapOptions ¶
MapOptions represents options for the mapper.
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) // Preparer provides methods for creating prepared statements. Preparer // Getter provides methods to compile and execute a query that returns // results. Getter // 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 Preparer ¶
type Preparer interface { // Prepare creates a prepared statement. Prepare() (*sql.Stmt, error) // PrepareContext creates a prepared statement. PrepareContext(context.Context) (*sql.Stmt, error) }
Preparer provides the Prepare and PrepareContext methods for creating prepared statements.
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 SQLBuilder ¶
type SQLBuilder 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 }
SQLBuilder 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.
func WithSession ¶
func WithSession(sess interface{}, t *exql.Template) SQLBuilder
WithSession returns a query builder that is bound to the given database session.
func WithTemplate ¶
func WithTemplate(t *exql.Template) SQLBuilder
WithTemplate returns a builder that is based on the given template.
type ScannerValuer ¶
ScannerValuer represents a value that satisfies both driver.Valuer and sql.Scanner interfaces.
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 // Preparer provides methods for creating prepared statements. Preparer // Getter provides methods to compile and execute a query that returns // results. Getter // 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 Tx ¶
type Tx interface { // All db.Database methods are available on transaction sessions. They will // run on the same transaction. db.Database // All SQLBuilder methods are available on transaction sessions. They will // run on the same transaction. SQLBuilder // db.Tx adds Commit and Rollback methods to the transaction. db.Tx // Context returns the context used as default for queries on this transaction. // If no context has been set, a default context.Background() is returned. Context() context.Context // WithContext returns a copy of the transaction that uses the given context // as default. Copies are safe to use concurrently but they're backed by the // same *sql.Tx, so any copy may commit or rollback the parent transaction. WithContext(context.Context) Tx // SetTxOptions sets the default TxOptions that is going to be used for new // transactions created in the session. SetTxOptions(sql.TxOptions) // TxOptions returns the defaultx TxOptions. TxOptions() *sql.TxOptions }
Tx represents a transaction on a SQL database. A transaction is like a regular Database except it has two extra methods: Commit and Rollback.
A transaction needs to be committed (with Commit) to make changes permanent, changes can be discarded before committing by rolling back (with Rollback). After either committing or rolling back a transaction it can not longer be used and it's automatically closed.
func NewTx ¶
NewTx wraps an active *sql.Tx transation and returns a SQLBuilder transaction. The adapter needs to be imported to the blank namespace in order for it to be used.
This method is internally used by upper-db to create a builder backed by the given transaction. You may want to use your adapter's NewTx function instead of this one.
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 // Preparer provides methods for creating prepared statements. Preparer // Execer provides the Exec method. Execer // 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 ValueWrapper ¶
type ValueWrapper interface {
WrapValue(value interface{}) interface{}
}
ValueWrapper defines a method WrapValue that query arguments can use to wrap themselves around helper types right before being used in a query.
Example:
func (a MyCustomArray) WrapValue(value interface{}) interface{} { // postgresql.Array adds a driver.Valuer and sql.Scanner around // custom arrays. return postgresql.Array(values) }