sqlboiler/queries/query.go

284 lines
6.1 KiB
Go
Raw Normal View History

package queries
import (
"database/sql"
"fmt"
"github.com/lbryio/lbry.go/extras/errors"
2017-05-08 19:25:15 +02:00
"github.com/lbryio/sqlboiler/boil"
)
// joinKind is the type of join
type joinKind int
// Join type constants
const (
JoinInner joinKind = iota
JoinOuterLeft
JoinOuterRight
JoinNatural
)
// Query holds the state for the built up query
type Query struct {
executor boil.Executor
2016-09-09 19:14:18 +02:00
dialect *Dialect
2016-09-15 05:57:07 +02:00
rawSQL rawSQL
load []string
delete bool
update map[string]interface{}
selectCols []string
count bool
from []string
joins []join
where []where
in []in
groupBy []string
orderBy []string
having []having
limit int
offset int
2016-08-30 05:13:00 +02:00
forlock string
}
2016-09-09 19:14:18 +02:00
// Dialect holds values that direct the query builder
// how to build compatible queries for each database.
// Each database driver needs to implement functions
// that provide these values.
type Dialect struct {
// The left quote character for SQL identifiers
2016-09-09 19:30:46 +02:00
LQ byte
2016-09-09 19:14:18 +02:00
// The right quote character for SQL identifiers
2016-09-09 19:30:46 +02:00
RQ byte
2016-09-09 19:14:18 +02:00
// Bool flag indicating whether indexed
// placeholders ($1) are used, or ? placeholders.
IndexPlaceholders bool
// Bool flag indicating whether "TOP" or "LIMIT" clause
// must be used for rows limitation
UseTopClause bool
2016-09-09 19:14:18 +02:00
}
2016-08-06 23:42:22 +02:00
type where struct {
clause string
orSeparator bool
args []interface{}
}
2016-08-17 07:19:23 +02:00
type in struct {
clause string
orSeparator bool
args []interface{}
}
type having struct {
clause string
args []interface{}
}
2016-09-15 05:57:07 +02:00
type rawSQL struct {
2016-08-06 23:42:22 +02:00
sql string
args []interface{}
}
2016-08-06 23:42:22 +02:00
type join struct {
kind joinKind
clause string
args []interface{}
2016-08-04 06:29:18 +02:00
}
2016-09-15 05:57:07 +02:00
// Raw makes a raw query, usually for use with bind
func Raw(exec boil.Executor, query string, args ...interface{}) *Query {
2016-08-08 08:36:11 +02:00
return &Query{
executor: exec,
2016-09-15 05:57:07 +02:00
rawSQL: rawSQL{
2016-08-08 08:36:11 +02:00
sql: query,
args: args,
},
}
}
2016-09-15 05:57:07 +02:00
// RawG makes a raw query using the global boil.Executor, usually for use with bind
func RawG(query string, args ...interface{}) *Query {
return Raw(boil.GetDB(), query, args...)
}
// Exec executes a query that does not need a row returned
func (q *Query) Exec() (sql.Result, error) {
2016-04-20 15:03:33 +02:00
qs, args := buildQuery(q)
if boil.DebugMode {
fmt.Fprintln(boil.DebugWriter, qs)
fmt.Fprintln(boil.DebugWriter, args)
}
2016-04-20 15:03:33 +02:00
return q.executor.Exec(qs, args...)
}
// QueryRow executes the query for the One finisher and returns a row
func (q *Query) QueryRow() *sql.Row {
qs, args := buildQuery(q)
if boil.DebugMode {
fmt.Fprintln(boil.DebugWriter, qs)
fmt.Fprintln(boil.DebugWriter, args)
}
return q.executor.QueryRow(qs, args...)
}
// Query executes the query for the All finisher and returns multiple rows
func (q *Query) Query() (*sql.Rows, error) {
2016-04-20 15:03:33 +02:00
qs, args := buildQuery(q)
if boil.DebugMode {
fmt.Fprintln(boil.DebugWriter, qs)
fmt.Fprintln(boil.DebugWriter, args)
}
return q.executor.Query(qs, args...)
}
// ExecP executes a query that does not need a row returned
// It will panic on error
func (q *Query) ExecP() sql.Result {
res, err := q.Exec()
if err != nil {
2018-02-07 15:35:46 +01:00
panic(errors.Err(err))
}
return res
}
// QueryP executes the query for the All finisher and returns multiple rows
// It will panic on error
func (q *Query) QueryP() *sql.Rows {
rows, err := q.Query()
if err != nil {
2018-02-07 15:35:46 +01:00
panic(errors.Err(err))
}
return rows
}
2016-08-17 07:19:23 +02:00
// SetExecutor on the query.
func SetExecutor(q *Query, exec boil.Executor) {
2016-08-17 07:19:23 +02:00
q.executor = exec
}
2016-08-29 14:38:19 +02:00
// GetExecutor on the query.
func GetExecutor(q *Query) boil.Executor {
2016-08-29 14:38:19 +02:00
return q.executor
}
2016-09-09 19:14:18 +02:00
// SetDialect on the query.
func SetDialect(q *Query, dialect *Dialect) {
q.dialect = dialect
}
// SetSQL on the query.
func SetSQL(q *Query, sql string, args ...interface{}) {
2016-09-15 05:57:07 +02:00
q.rawSQL = rawSQL{sql: sql, args: args}
}
// SetLoad on the query.
func SetLoad(q *Query, relationships ...string) {
q.load = append([]string(nil), relationships...)
}
// AppendLoad on the query.
func AppendLoad(q *Query, relationships ...string) {
q.load = append(q.load, relationships...)
}
// SetSelect on the query.
func SetSelect(q *Query, sel []string) {
q.selectCols = sel
}
// SetCount on the query.
2016-05-10 12:20:29 +02:00
func SetCount(q *Query) {
q.count = true
2016-05-10 12:20:29 +02:00
}
// SetDelete on the query.
func SetDelete(q *Query) {
q.delete = true
}
2016-08-17 07:19:23 +02:00
// SetLimit on the query.
func SetLimit(q *Query, limit int) {
q.limit = limit
}
// SetOffset on the query.
func SetOffset(q *Query, offset int) {
q.offset = offset
}
2016-08-30 05:13:00 +02:00
// SetFor on the query.
func SetFor(q *Query, clause string) {
q.forlock = clause
}
2016-08-04 06:29:18 +02:00
// SetUpdate on the query.
func SetUpdate(q *Query, cols map[string]interface{}) {
q.update = cols
}
// AppendSelect on the query.
func AppendSelect(q *Query, columns ...string) {
q.selectCols = append(q.selectCols, columns...)
}
// AppendFrom on the query.
func AppendFrom(q *Query, from ...string) {
2016-08-04 06:50:26 +02:00
q.from = append(q.from, from...)
}
// SetFrom replaces the current from statements.
func SetFrom(q *Query, from ...string) {
q.from = append([]string(nil), from...)
}
// AppendInnerJoin on the query.
func AppendInnerJoin(q *Query, clause string, args ...interface{}) {
q.joins = append(q.joins, join{clause: clause, kind: JoinInner, args: args})
}
2016-08-17 07:19:23 +02:00
// AppendHaving on the query.
func AppendHaving(q *Query, clause string, args ...interface{}) {
q.having = append(q.having, having{clause: clause, args: args})
}
// AppendWhere on the query.
func AppendWhere(q *Query, clause string, args ...interface{}) {
q.where = append(q.where, where{clause: clause, args: args})
}
2016-08-17 07:19:23 +02:00
// AppendIn on the query.
func AppendIn(q *Query, clause string, args ...interface{}) {
q.in = append(q.in, in{clause: clause, args: args})
}
2016-08-17 07:19:23 +02:00
// SetLastWhereAsOr sets the or separator for the tail "WHERE" in the slice
func SetLastWhereAsOr(q *Query) {
if len(q.where) == 0 {
return
}
q.where[len(q.where)-1].orSeparator = true
}
2016-08-17 07:19:23 +02:00
// SetLastInAsOr sets the or separator for the tail "IN" in the slice
func SetLastInAsOr(q *Query) {
if len(q.in) == 0 {
return
}
2016-08-17 07:19:23 +02:00
q.in[len(q.in)-1].orSeparator = true
}
2016-08-17 07:19:23 +02:00
// AppendGroupBy on the query.
func AppendGroupBy(q *Query, clause string) {
q.groupBy = append(q.groupBy, clause)
}
2016-08-17 07:19:23 +02:00
// AppendOrderBy on the query.
func AppendOrderBy(q *Query, clause string) {
q.orderBy = append(q.orderBy, clause)
2016-08-01 04:21:06 +02:00
}