dbq: bitbucket.org/ulfurinn/dbq Index | Files

package dbq

import "bitbucket.org/ulfurinn/dbq"

Package dbq builds SQL ASTs and generates query strings from them.

dbq works by dynamically constructing SQL syntax trees and generating queries from them. It can be used separately from any data modeling packages and even without an open database connection.

Examples in this document assume the package is dot-imported for brevity.

Getting started

A *Dbq value is needed to generate queries. Obtain it like this:

q := NewQ(dbconn, PostgresDialect{})

dbconn doesn't need to be a valid connection unless you want to use dbq for loading data (which is only partially implemented at the moment). PostgresDialect is currently the only available dialect.

Expressions and composition

Two basic types in dbq are Node and Expression. Everything is a Node; most things are also Expressions. An Expression can be combined with other Expressions to form more complex ones.

The basic expressions are literals, created with Literal(), and identifiers, created with Ident(). They can be combined with binary operations to abritrary levels of nesting. Other expressions are aliases, column references (obtained from types that implement Tabular), and entire select queries, allowing subqueries as values.

Keep in mind that dbq is generally very liberal in what types of arguments it accepts, and not all combinations result in valid SQL. Aliases are one such example: there is no structural difference between a table alias and a column/expression alias, but the database engine will complain if you mix them up.

SELECT

A SELECT expression has the following basic structure:

q.Select(columns...).From(tables...).Where(conditions...).Limit(n).Offset(n)

Each of the methods returns the same *SelectQuery value, so you can chain them as you like. Multiple calls to the same method will accumulate arguments.

Column list

Any Expression can be used as a column. You can wrap them with Alias() to give them a name. A bare string is also accepted here, and is identical to using an identifier.

Table list

...

Condition list

...

Limit and Offset

...

Index

Package Files

dbq.go dialect.go doc.go expression.go model.go postgres.go select.go

type AggFuncExpr Uses

type AggFuncExpr struct {
    Primitive
    // contains filtered or unexported fields
}

func (*AggFuncExpr) String Uses

func (f *AggFuncExpr) String(c Ctx) (string, error)

type AliasExpr Uses

type AliasExpr struct {
    Expression // alias
    Source     Node
}

func Alias Uses

func Alias(source interface{}, name string) *AliasExpr

Alias returns an alias expression.

source can be of the following types:

string - will be cast to an Identifier
Node - will be used as is

Anything else will panic.

func (*AliasExpr) Col Uses

func (alias *AliasExpr) Col(column string) Expression

Col represents a column expression, using the alias as the table name.

func (*AliasExpr) Name Uses

func (alias *AliasExpr) Name() string

Name returns the alias part of the expression.

func (*AliasExpr) String Uses

func (alias *AliasExpr) String(c Ctx) (string, error)

String implements Node.

type All Uses

type All struct{} // All represents the ALL keyword

type Args Uses

type Args map[string]interface{}

type BinaryOp Uses

type BinaryOp struct {
    Compound
    // contains filtered or unexported fields
}

func (*BinaryOp) String Uses

func (op *BinaryOp) String(c Ctx) (string, error)

type Binding Uses

type Binding struct {
    Compound // required to work with IN(). should be cleaned up, maybe.
    // contains filtered or unexported fields
}

func (*Binding) IsNull Uses

func (b *Binding) IsNull(c Ctx) bool

func (*Binding) String Uses

func (b *Binding) String(c Ctx) (string, error)

type CastExpr Uses

type CastExpr struct {
    Primitive
    // contains filtered or unexported fields
}

func (*CastExpr) String Uses

func (cast *CastExpr) String(c Ctx) (string, error)

type ColumnExpr Uses

type ColumnExpr struct {
    Primitive
    // contains filtered or unexported fields
}

func (*ColumnExpr) String Uses

func (col *ColumnExpr) String(c Ctx) (string, error)

type Compound Uses

type Compound struct{}

Compound is a mixin for Node implementations that provides the IsCompound() method.

func (Compound) IsCompound Uses

func (Compound) IsCompound() bool

type Ctx Uses

type Ctx interface {
    Select(*SelectExpr) (string, error)
    Column(*ColumnExpr) (string, error)
    BinaryOp(*BinaryOp) (string, error)
    Alias(*AliasExpr) (string, error)
    StaticPlaceholder(interface{}) (string, error)
    DynamicPlaceholder(*Binding) (string, error)
    Join(*JoinExpr) (string, error)
    JoinCondition(*JoinCondition) (string, error)
    In(*InExpr) (string, error)
    BindValue(*Binding) (interface{}, bool)
    Cast(*CastExpr) (string, error)
    Func(*FuncExpr) (string, error)
    AggFunc(*AggFuncExpr) (string, error)
    OrderBy(*OrderExpr) (string, error)
}

Ctx is the interface used by Nodes to return (possibly dialect-specific) SQL. It provides a mapping between a dbq type and an SQL subexpression. Ctx is used because a query may contain shared state that needs to be accessible by all Nodes (like lists of known placeholders).

type Dbq Uses

type Dbq struct {
    Dialect
    *sql.DB
}

func NewQ Uses

func NewQ(db *sql.DB, d Dialect) *Dbq

NewQ returns a new dbq handle.

func (*Dbq) Select Uses

func (q *Dbq) Select(spec ...interface{}) *SelectQuery

Select returns a new SelectQuery.

spec is a column specification. An element can be of types:

string   // interpreted as a column name
Node     // used as is
Distinct

type Dialect Uses

type Dialect interface {
    SQL(e Expression, v Args) (sql string, values []interface{}, err error) // serializes an Expression to string and collects all placeholder bindings, explicit and implicit
    SQLString(e Expression) (sql string, err error)
}

type Distinct Uses

type Distinct struct{} // Distinct represents the DISTINCT keyword

type Expr Uses

type Expr struct {
    Node
}

func (*Expr) And Uses

func (e *Expr) And(other interface{}) Expression

func (*Expr) Cast Uses

func (e *Expr) Cast(typ string) Expression

func (*Expr) Div Uses

func (e *Expr) Div(other interface{}) Expression

func (*Expr) Eq Uses

func (e *Expr) Eq(other interface{}) Expression

func (*Expr) Greater Uses

func (e *Expr) Greater(other interface{}) Expression

func (*Expr) GreaterEq Uses

func (e *Expr) GreaterEq(other interface{}) Expression

func (*Expr) In Uses

func (e *Expr) In(other interface{}) Expression

func (*Expr) IsNull Uses

func (e *Expr) IsNull(c Ctx) bool

func (*Expr) Less Uses

func (e *Expr) Less(other interface{}) Expression

func (*Expr) LessEq Uses

func (e *Expr) LessEq(other interface{}) Expression

func (*Expr) Minus Uses

func (e *Expr) Minus(other interface{}) Expression

func (*Expr) Mult Uses

func (e *Expr) Mult(other interface{}) Expression

func (*Expr) NotEq Uses

func (e *Expr) NotEq(other interface{}) Expression

func (*Expr) Or Uses

func (e *Expr) Or(other interface{}) Expression

func (*Expr) Plus Uses

func (e *Expr) Plus(other interface{}) Expression

type Expression Uses

type Expression interface {
    Node
    Plus(other interface{}) Expression
    Minus(other interface{}) Expression
    Mult(other interface{}) Expression
    Div(other interface{}) Expression

    Eq(other interface{}) Expression
    NotEq(other interface{}) Expression
    Less(other interface{}) Expression
    LessEq(other interface{}) Expression
    Greater(other interface{}) Expression
    GreaterEq(other interface{}) Expression

    In(other interface{}) Expression

    And(other interface{}) Expression
    Or(other interface{}) Expression

    Cast(string) Expression
}

func AggFunc Uses

func AggFunc(name string, args ...interface{}) Expression

func Binary Uses

func Binary(a interface{}, op string, b interface{}) Expression

func Bind Uses

func Bind(name string) Expression

Bind returns an explicit placeholder.

Concrete values can be specified when calling *Dbq.SQL(). Note that the string representation returned by *Dbq.SQL() may changed based on the values provided.

func Cast Uses

func Cast(e Expression, typ string) Expression

Cast returns a typecase expression.

func Func Uses

func Func(name string, args ...Expression) Expression

func In Uses

func In(element interface{}, list interface{}) Expression

In returns an IN(...) expression. The argument can be an Expression (probably a LiteralList) or a []interface{}, in which case a number of implicit placeholders may be generated.

func Literal Uses

func Literal(value interface{}) Expression

type FuncExpr Uses

type FuncExpr struct {
    Primitive
    // contains filtered or unexported fields
}

func (*FuncExpr) String Uses

func (f *FuncExpr) String(c Ctx) (string, error)

type IdentExpr Uses

type IdentExpr struct {
    Expr
}

func (*IdentExpr) Col Uses

func (id *IdentExpr) Col(column string) Expression

func (*IdentExpr) Name Uses

func (id *IdentExpr) Name() string

type Identifier Uses

type Identifier string

func (Identifier) IsCompound Uses

func (Identifier) IsCompound() bool

func (Identifier) String Uses

func (id Identifier) String(Ctx) (string, error)

type InExpr Uses

type InExpr struct {
    Primitive
    // contains filtered or unexported fields
}

func (*InExpr) String Uses

func (in *InExpr) String(c Ctx) (string, error)

type JoinCondition Uses

type JoinCondition struct {
    Compound
    // contains filtered or unexported fields
}

func On Uses

func On(condition Node) *JoinCondition

func Using Uses

func Using(condition Node) *JoinCondition

func (*JoinCondition) String Uses

func (jc *JoinCondition) String(c Ctx) (string, error)

type JoinConditionKind Uses

type JoinConditionKind int
const (
    JoinOn    JoinConditionKind = iota
    JoinUsing JoinConditionKind = iota
)

type JoinExpr Uses

type JoinExpr struct {
    Primitive
    // contains filtered or unexported fields
}

func Join Uses

func Join(table interface{}, condition *JoinCondition) *JoinExpr

func LeftJoin Uses

func LeftJoin(table interface{}, condition *JoinCondition) *JoinExpr

func OuterJoin Uses

func OuterJoin(table interface{}, condition *JoinCondition) *JoinExpr

func RightJoin Uses

func RightJoin(table interface{}, condition *JoinCondition) *JoinExpr

func (*JoinExpr) String Uses

func (jc *JoinExpr) String(c Ctx) (string, error)

type JoinKind Uses

type JoinKind int
const (
    InnerJoinKind JoinKind = iota
    LeftJoinKind  JoinKind = iota
    RightJoinKind JoinKind = iota
    OuterJoinKind JoinKind = iota
    CrossJoinKind JoinKind = iota
)

type LiteralInt64 Uses

type LiteralInt64 int64

LiteralInt64 represents an SQL integer literal.

func (LiteralInt64) IsCompound Uses

func (LiteralInt64) IsCompound() bool

func (LiteralInt64) String Uses

func (i LiteralInt64) String(Ctx) (string, error)

type LiteralList Uses

type LiteralList []interface{}

func (LiteralList) IsCompound Uses

func (LiteralList) IsCompound() bool

func (LiteralList) String Uses

func (l LiteralList) String(c Ctx) (string, error)

type LiteralNull Uses

type LiteralNull struct{}

func (LiteralNull) IsCompound Uses

func (LiteralNull) IsCompound() bool

func (LiteralNull) IsNull Uses

func (LiteralNull) IsNull(Ctx) bool

func (LiteralNull) String Uses

func (LiteralNull) String(Ctx) (string, error)

type LiteralString Uses

type LiteralString string

func (LiteralString) IsCompound Uses

func (LiteralString) IsCompound() bool

func (LiteralString) String Uses

func (s LiteralString) String(c Ctx) (string, error)

String returns an implicitly generated placeholder instead of the actual literal. This is necessary because database/sql does not expose an interface to safely quote string literals, so we are forced to inject a placeholder.

type Node Uses

type Node interface {
    String(Ctx) (string, error) // the string representation
    IsCompound() bool           // used to decide when to surround subexpressions with parentheses
}

A Node is the basic building block in dbq. All syntax trees are built from Nodes.

A Node is supposed to be able to return a string representation of itself, corresponding to an SQL subexpression.

type Nullable Uses

type Nullable interface {
    IsNull(Ctx) bool
}

Nullable is used by the equality operator to decide when to use IS NOT/IS NOT NULL instead of =/!=. It is most useful with bindings.

type OrderClause Uses

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

func Order Uses

func Order(column interface{}, order interface{}) (result OrderClause)

type OrderExpr Uses

type OrderExpr struct {
    Primitive
    // contains filtered or unexported fields
}

func OrderBy Uses

func OrderBy(clauses ...interface{}) *OrderExpr

func (*OrderExpr) String Uses

func (order *OrderExpr) String(c Ctx) (string, error)

type OrderKind Uses

type OrderKind int
const (
    OrderDefault OrderKind = iota
    OrderAsc     OrderKind = iota
    OrderDesc    OrderKind = iota
)

type PostgresCtx Uses

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

func (*PostgresCtx) AggFunc Uses

func (c *PostgresCtx) AggFunc(f *AggFuncExpr) (sql string, err error)

func (*PostgresCtx) Alias Uses

func (c *PostgresCtx) Alias(alias *AliasExpr) (sql string, err error)

func (*PostgresCtx) BinaryOp Uses

func (c *PostgresCtx) BinaryOp(e *BinaryOp) (sql string, err error)

func (*PostgresCtx) BindValue Uses

func (c *PostgresCtx) BindValue(b *Binding) (value interface{}, ok bool)

func (*PostgresCtx) Cast Uses

func (c *PostgresCtx) Cast(cast *CastExpr) (sql string, err error)

func (*PostgresCtx) Column Uses

func (c *PostgresCtx) Column(col *ColumnExpr) (sql string, err error)

func (*PostgresCtx) DynamicPlaceholder Uses

func (c *PostgresCtx) DynamicPlaceholder(b *Binding) (sql string, err error)

func (*PostgresCtx) Func Uses

func (c *PostgresCtx) Func(f *FuncExpr) (sql string, err error)

func (*PostgresCtx) In Uses

func (c *PostgresCtx) In(in *InExpr) (sql string, err error)

func (*PostgresCtx) Join Uses

func (c *PostgresCtx) Join(j *JoinExpr) (sql string, err error)

func (*PostgresCtx) JoinCondition Uses

func (c *PostgresCtx) JoinCondition(jc *JoinCondition) (sql string, err error)

func (*PostgresCtx) OrderBy Uses

func (c *PostgresCtx) OrderBy(order *OrderExpr) (sql string, err error)

func (*PostgresCtx) Select Uses

func (c *PostgresCtx) Select(s *SelectExpr) (query string, err error)

func (*PostgresCtx) StaticPlaceholder Uses

func (c *PostgresCtx) StaticPlaceholder(value interface{}) (sql string, err error)

type PostgresDialect Uses

type PostgresDialect struct{}

func (PostgresDialect) Ctx Uses

func (PostgresDialect) Ctx() *PostgresCtx

func (PostgresDialect) SQL Uses

func (d PostgresDialect) SQL(e Expression, v Args) (sql string, values []interface{}, err error)

func (PostgresDialect) SQLString Uses

func (d PostgresDialect) SQLString(e Expression) (sql string, err error)

type Primitive Uses

type Primitive struct{}

Primitive is a mixin for Node implementations that provides the IsCompound() method.

func (Primitive) IsCompound Uses

func (Primitive) IsCompound() bool

type SelectExpr Uses

type SelectExpr struct {
    Compound
    // contains filtered or unexported fields
}

SelectExpr represents a SELECT query.

func (*SelectExpr) String Uses

func (s *SelectExpr) String(c Ctx) (string, error)

type SelectQuery Uses

type SelectQuery struct {
    Expr
    // contains filtered or unexported fields
}

SelectQuery is a higher-level interface to SelectExpr.

func (*SelectQuery) From Uses

func (s *SelectQuery) From(specs ...interface{}) *SelectQuery

func (*SelectQuery) Group Uses

func (s *SelectQuery) Group(exprs ...interface{}) *SelectQuery

func (*SelectQuery) Into Uses

func (s *SelectQuery) Into(target interface{}, args ...Args) error

func (*SelectQuery) Limit Uses

func (s *SelectQuery) Limit(l uint) *SelectQuery

func (*SelectQuery) Offset Uses

func (s *SelectQuery) Offset(o uint) *SelectQuery

func (*SelectQuery) OrderBy Uses

func (s *SelectQuery) OrderBy(clauses ...interface{}) *SelectQuery

func (*SelectQuery) Where Uses

func (s *SelectQuery) Where(specs ...interface{}) *SelectQuery

type Tabular Uses

type Tabular interface {
    Name() string
    Col(name string) Expression // creates a column reference
}

Tabular is a value that can represent a table or a table-like expression.

type TabularExpression Uses

type TabularExpression interface {
    Tabular
    Expression
}

func Ident Uses

func Ident(id string) TabularExpression

Ident returns an identifier expression.

Package dbq imports 7 packages (graph). Updated 2016-12-05. Refresh now. Tools for package owners.