123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 |
- // +build go1.8
- package sqlx
- import (
- "context"
- "database/sql"
- )
- // A union interface of contextPreparer and binder, required to be able to
- // prepare named statements with context (as the bindtype must be determined).
- type namedPreparerContext interface {
- PreparerContext
- binder
- }
- func prepareNamedContext(ctx context.Context, p namedPreparerContext, query string) (*NamedStmt, error) {
- bindType := BindType(p.DriverName())
- q, args, err := compileNamedQuery([]byte(query), bindType)
- if err != nil {
- return nil, err
- }
- stmt, err := PreparexContext(ctx, p, q)
- if err != nil {
- return nil, err
- }
- return &NamedStmt{
- QueryString: q,
- Params: args,
- Stmt: stmt,
- }, nil
- }
- // ExecContext executes a named statement using the struct passed.
- // Any named placeholder parameters are replaced with fields from arg.
- func (n *NamedStmt) ExecContext(ctx context.Context, arg interface{}) (sql.Result, error) {
- args, err := bindAnyArgs(n.Params, arg, n.Stmt.Mapper)
- if err != nil {
- return *new(sql.Result), err
- }
- return n.Stmt.ExecContext(ctx, args...)
- }
- // QueryContext executes a named statement using the struct argument, returning rows.
- // Any named placeholder parameters are replaced with fields from arg.
- func (n *NamedStmt) QueryContext(ctx context.Context, arg interface{}) (*sql.Rows, error) {
- args, err := bindAnyArgs(n.Params, arg, n.Stmt.Mapper)
- if err != nil {
- return nil, err
- }
- return n.Stmt.QueryContext(ctx, args...)
- }
- // QueryRowContext executes a named statement against the database. Because sqlx cannot
- // create a *sql.Row with an error condition pre-set for binding errors, sqlx
- // returns a *sqlx.Row instead.
- // Any named placeholder parameters are replaced with fields from arg.
- func (n *NamedStmt) QueryRowContext(ctx context.Context, arg interface{}) *Row {
- args, err := bindAnyArgs(n.Params, arg, n.Stmt.Mapper)
- if err != nil {
- return &Row{err: err}
- }
- return n.Stmt.QueryRowxContext(ctx, args...)
- }
- // MustExecContext execs a NamedStmt, panicing on error
- // Any named placeholder parameters are replaced with fields from arg.
- func (n *NamedStmt) MustExecContext(ctx context.Context, arg interface{}) sql.Result {
- res, err := n.ExecContext(ctx, arg)
- if err != nil {
- panic(err)
- }
- return res
- }
- // QueryxContext using this NamedStmt
- // Any named placeholder parameters are replaced with fields from arg.
- func (n *NamedStmt) QueryxContext(ctx context.Context, arg interface{}) (*Rows, error) {
- r, err := n.QueryContext(ctx, arg)
- if err != nil {
- return nil, err
- }
- return &Rows{Rows: r, Mapper: n.Stmt.Mapper, unsafe: isUnsafe(n)}, err
- }
- // QueryRowxContext this NamedStmt. Because of limitations with QueryRow, this is
- // an alias for QueryRow.
- // Any named placeholder parameters are replaced with fields from arg.
- func (n *NamedStmt) QueryRowxContext(ctx context.Context, arg interface{}) *Row {
- return n.QueryRowContext(ctx, arg)
- }
- // SelectContext using this NamedStmt
- // Any named placeholder parameters are replaced with fields from arg.
- func (n *NamedStmt) SelectContext(ctx context.Context, dest interface{}, arg interface{}) error {
- rows, err := n.QueryxContext(ctx, arg)
- if err != nil {
- return err
- }
- // if something happens here, we want to make sure the rows are Closed
- defer rows.Close()
- return scanAll(rows, dest, false)
- }
- // GetContext using this NamedStmt
- // Any named placeholder parameters are replaced with fields from arg.
- func (n *NamedStmt) GetContext(ctx context.Context, dest interface{}, arg interface{}) error {
- r := n.QueryRowxContext(ctx, arg)
- return r.scanAny(dest, false)
- }
- // NamedQueryContext binds a named query and then runs Query on the result using the
- // provided Ext (sqlx.Tx, sqlx.Db). It works with both structs and with
- // map[string]interface{} types.
- func NamedQueryContext(ctx context.Context, e ExtContext, query string, arg interface{}) (*Rows, error) {
- q, args, err := bindNamedMapper(BindType(e.DriverName()), query, arg, mapperFor(e))
- if err != nil {
- return nil, err
- }
- return e.QueryxContext(ctx, q, args...)
- }
- // NamedExecContext uses BindStruct to get a query executable by the driver and
- // then runs Exec on the result. Returns an error from the binding
- // or the query execution itself.
- func NamedExecContext(ctx context.Context, e ExtContext, query string, arg interface{}) (sql.Result, error) {
- q, args, err := bindNamedMapper(BindType(e.DriverName()), query, arg, mapperFor(e))
- if err != nil {
- return nil, err
- }
- return e.ExecContext(ctx, q, args...)
- }
|