Support for raw sql input.

This commit is contained in:
zer0sub 2019-06-04 12:10:23 +02:00
parent 384c0c67f5
commit 8f51662fe5
31 changed files with 307 additions and 279 deletions

View file

@ -1,11 +1,11 @@
package sqlbuilder package sqlbuilder
type Alias struct { type Alias struct {
expression expression expression Expression
alias string alias string
} }
func NewAlias(expression expression, alias string) *Alias { func NewAlias(expression Expression, alias string) *Alias {
return &Alias{ return &Alias{
expression: expression, expression: expression,
alias: alias, alias: alias,

View file

@ -1,7 +1,7 @@
package sqlbuilder package sqlbuilder
type BoolExpression interface { type BoolExpression interface {
expression Expression
EQ(expression BoolExpression) BoolExpression EQ(expression BoolExpression) BoolExpression
NOT_EQ(expression BoolExpression) BoolExpression NOT_EQ(expression BoolExpression) BoolExpression
@ -79,7 +79,7 @@ type binaryBoolExpression struct {
binaryOpExpression binaryOpExpression
} }
func newBinaryBoolExpression(lhs, rhs expression, operator string) BoolExpression { func newBinaryBoolExpression(lhs, rhs Expression, operator string) BoolExpression {
boolExpression := binaryBoolExpression{} boolExpression := binaryBoolExpression{}
boolExpression.binaryOpExpression = newBinaryExpression(lhs, rhs, operator) boolExpression.binaryOpExpression = newBinaryExpression(lhs, rhs, operator)
@ -97,7 +97,7 @@ type prefixBoolExpression struct {
prefixOpExpression prefixOpExpression
} }
func newPrefixBoolExpression(expression expression, operator string) BoolExpression { func newPrefixBoolExpression(expression Expression, operator string) BoolExpression {
exp := prefixBoolExpression{} exp := prefixBoolExpression{}
exp.prefixOpExpression = newPrefixExpression(expression, operator) exp.prefixOpExpression = newPrefixExpression(expression, operator)
@ -115,7 +115,7 @@ type postfixBoolOpExpression struct {
postfixOpExpression postfixOpExpression
} }
func newPostifxBoolExpression(expression expression, operator string) BoolExpression { func newPostifxBoolExpression(expression Expression, operator string) BoolExpression {
exp := postfixBoolOpExpression{} exp := postfixBoolOpExpression{}
exp.postfixOpExpression = newPostfixOpExpression(expression, operator) exp.postfixOpExpression = newPostfixOpExpression(expression, operator)

View file

@ -1,19 +1,19 @@
package sqlbuilder package sqlbuilder
type cast struct { type cast struct {
expression Expression
castType string castType string
} }
func newCast(expression expression, castType string) *cast { func newCast(expression Expression, castType string) *cast {
return &cast{ return &cast{
expression: expression, Expression: expression,
castType: castType, castType: castType,
} }
} }
func (b *cast) serialize(statement statementType, out *queryData, options ...serializeOption) error { func (b *cast) serialize(statement statementType, out *queryData, options ...serializeOption) error {
err := b.expression.serialize(statement, out, options...) err := b.Expression.serialize(statement, out, options...)
out.writeString("::" + b.castType) out.writeString("::" + b.castType)
return err return err
} }
@ -24,7 +24,7 @@ type boolCast struct {
cast cast
} }
func newBoolCast(expression expression) BoolExpression { func newBoolCast(expression Expression) BoolExpression {
boolCast := &boolCast{cast: *newCast(expression, "boolean")} boolCast := &boolCast{cast: *newCast(expression, "boolean")}
boolCast.boolInterfaceImpl.parent = boolCast boolCast.boolInterfaceImpl.parent = boolCast
@ -39,7 +39,7 @@ type integerCast struct {
cast cast
} }
func newIntegerCast(expression expression) IntegerExpression { func newIntegerCast(expression Expression) IntegerExpression {
integerCast := &integerCast{cast: *newCast(expression, "integer")} integerCast := &integerCast{cast: *newCast(expression, "integer")}
integerCast.integerInterfaceImpl.parent = integerCast integerCast.integerInterfaceImpl.parent = integerCast
@ -54,7 +54,7 @@ type floatCast struct {
cast cast
} }
func newDoubleCast(expression expression) FloatExpression { func newDoubleCast(expression Expression) FloatExpression {
floatCast := &floatCast{cast: *newCast(expression, "double precision")} floatCast := &floatCast{cast: *newCast(expression, "double precision")}
floatCast.floatInterfaceImpl.parent = floatCast floatCast.floatInterfaceImpl.parent = floatCast
@ -69,7 +69,7 @@ type textCast struct {
cast cast
} }
func newTextCast(expression expression) StringExpression { func newTextCast(expression Expression) StringExpression {
textCast := &textCast{cast: *newCast(expression, "text")} textCast := &textCast{cast: *newCast(expression, "text")}
textCast.stringInterfaceImpl.parent = textCast textCast.stringInterfaceImpl.parent = textCast
@ -84,7 +84,7 @@ type dateCast struct {
cast cast
} }
func newDateCast(expression expression) DateExpression { func newDateCast(expression Expression) DateExpression {
dateCast := &dateCast{cast: *newCast(expression, "date")} dateCast := &dateCast{cast: *newCast(expression, "date")}
dateCast.dateInterfaceImpl.parent = dateCast dateCast.dateInterfaceImpl.parent = dateCast
@ -99,7 +99,7 @@ type timeCast struct {
cast cast
} }
func newTimeCast(expression expression) TimeExpression { func newTimeCast(expression Expression) TimeExpression {
timeCast := &timeCast{cast: *newCast(expression, "time without time zone")} timeCast := &timeCast{cast: *newCast(expression, "time without time zone")}
timeCast.timeInterfaceImpl.parent = timeCast timeCast.timeInterfaceImpl.parent = timeCast
@ -114,7 +114,7 @@ type timezCast struct {
cast cast
} }
func newTimezCast(expression expression) TimezExpression { func newTimezCast(expression Expression) TimezExpression {
timezCast := &timezCast{cast: *newCast(expression, "time with time zone")} timezCast := &timezCast{cast: *newCast(expression, "time with time zone")}
timezCast.timezInterfaceImpl.parent = timezCast timezCast.timezInterfaceImpl.parent = timezCast
@ -129,7 +129,7 @@ type timestampCast struct {
cast cast
} }
func newTimestampCast(expression expression) TimestampExpression { func newTimestampCast(expression Expression) TimestampExpression {
timestampCast := &timestampCast{cast: *newCast(expression, "timestamp without time zone")} timestampCast := &timestampCast{cast: *newCast(expression, "timestamp without time zone")}
timestampCast.timestampInterfaceImpl.parent = timestampCast timestampCast.timestampInterfaceImpl.parent = timestampCast
@ -144,7 +144,7 @@ type timestampzCast struct {
cast cast
} }
func newTimestampzCast(expression expression) TimestampzExpression { func newTimestampzCast(expression Expression) TimestampzExpression {
timestampzCast := &timestampzCast{cast: *newCast(expression, "timestamp with time zone")} timestampzCast := &timestampzCast{cast: *newCast(expression, "timestamp with time zone")}
timestampzCast.timestampzInterfaceImpl.parent = timestampzCast timestampzCast.timestampzInterfaceImpl.parent = timestampzCast

View file

@ -76,7 +76,7 @@ func (q *queryData) writeFrom(statement statementType, table tableInterface) err
return err return err
} }
func (q *queryData) writeWhere(statement statementType, where expression) error { func (q *queryData) writeWhere(statement statementType, where Expression) error {
q.nextLine() q.nextLine()
q.writeString("WHERE") q.writeString("WHERE")
@ -98,7 +98,7 @@ func (q *queryData) writeGroupBy(statement statementType, groupBy []groupByClaus
return err return err
} }
func (q *queryData) writeOrderBy(statement statementType, orderBy []orderByClause) error { func (q *queryData) writeOrderBy(statement statementType, orderBy []OrderByClause) error {
q.nextLine() q.nextLine()
q.writeString("ORDER BY") q.writeString("ORDER BY")
@ -109,7 +109,7 @@ func (q *queryData) writeOrderBy(statement statementType, orderBy []orderByClaus
return err return err
} }
func (q *queryData) writeHaving(statement statementType, having expression) error { func (q *queryData) writeHaving(statement statementType, having Expression) error {
q.nextLine() q.nextLine()
q.writeString("HAVING") q.writeString("HAVING")

View file

@ -7,7 +7,7 @@ import (
) )
type column interface { type column interface {
expression Expression
Name() string Name() string
TableName() string TableName() string

View file

@ -1,7 +1,7 @@
package sqlbuilder package sqlbuilder
type DateExpression interface { type DateExpression interface {
expression Expression
EQ(rhs DateExpression) BoolExpression EQ(rhs DateExpression) BoolExpression
NOT_EQ(rhs DateExpression) BoolExpression NOT_EQ(rhs DateExpression) BoolExpression

View file

@ -6,13 +6,13 @@ import (
"github.com/sub0zero/go-sqlbuilder/sqlbuilder/execution" "github.com/sub0zero/go-sqlbuilder/sqlbuilder/execution"
) )
type deleteStatement interface { type DeleteStatement interface {
Statement Statement
WHERE(expression BoolExpression) deleteStatement WHERE(expression BoolExpression) DeleteStatement
} }
func newDeleteStatement(table writableTable) deleteStatement { func newDeleteStatement(table writableTable) DeleteStatement {
return &deleteStatementImpl{ return &deleteStatementImpl{
table: table, table: table,
} }
@ -23,7 +23,7 @@ type deleteStatementImpl struct {
where BoolExpression where BoolExpression
} }
func (d *deleteStatementImpl) WHERE(expression BoolExpression) deleteStatement { func (d *deleteStatementImpl) WHERE(expression BoolExpression) DeleteStatement {
d.where = expression d.where = expression
return d return d
} }

View file

@ -4,25 +4,25 @@ import (
"github.com/dropbox/godropbox/errors" "github.com/dropbox/godropbox/errors"
) )
// An expression // An Expression
type expression interface { type Expression interface {
clause clause
projection projection
groupByClause groupByClause
orderByClause OrderByClause
IS_NULL() BoolExpression IS_NULL() BoolExpression
IS_NOT_NULL() BoolExpression IS_NOT_NULL() BoolExpression
IN(expressions ...expression) BoolExpression IN(expressions ...Expression) BoolExpression
NOT_IN(expressions ...expression) BoolExpression NOT_IN(expressions ...Expression) BoolExpression
AS(alias string) projection AS(alias string) projection
ASC() orderByClause ASC() OrderByClause
DESC() orderByClause DESC() OrderByClause
CAST_TO(dbType string) expression CAST_TO(dbType string) Expression
CAST_TO_BOOL() BoolExpression CAST_TO_BOOL() BoolExpression
CAST_TO_INTEGER() IntegerExpression CAST_TO_INTEGER() IntegerExpression
CAST_TO_DOUBLE() FloatExpression CAST_TO_DOUBLE() FloatExpression
@ -35,7 +35,7 @@ type expression interface {
} }
type expressionInterfaceImpl struct { type expressionInterfaceImpl struct {
parent expression parent Expression
} }
func (e *expressionInterfaceImpl) IS_NULL() BoolExpression { func (e *expressionInterfaceImpl) IS_NULL() BoolExpression {
@ -46,11 +46,11 @@ func (e *expressionInterfaceImpl) IS_NOT_NULL() BoolExpression {
return newPostifxBoolExpression(e.parent, "IS NOT NULL") return newPostifxBoolExpression(e.parent, "IS NOT NULL")
} }
func (e *expressionInterfaceImpl) IN(expressions ...expression) BoolExpression { func (e *expressionInterfaceImpl) IN(expressions ...Expression) BoolExpression {
return newBinaryBoolExpression(e.parent, WRAP(expressions...), "IN") return newBinaryBoolExpression(e.parent, WRAP(expressions...), "IN")
} }
func (e *expressionInterfaceImpl) NOT_IN(expressions ...expression) BoolExpression { func (e *expressionInterfaceImpl) NOT_IN(expressions ...Expression) BoolExpression {
return newBinaryBoolExpression(e.parent, WRAP(expressions...), "NOT IN") return newBinaryBoolExpression(e.parent, WRAP(expressions...), "NOT IN")
} }
@ -58,15 +58,15 @@ func (e *expressionInterfaceImpl) AS(alias string) projection {
return NewAlias(e.parent, alias) return NewAlias(e.parent, alias)
} }
func (e *expressionInterfaceImpl) ASC() orderByClause { func (e *expressionInterfaceImpl) ASC() OrderByClause {
return &orderByClauseImpl{expression: e.parent, ascent: true} return &orderByClauseImpl{expression: e.parent, ascent: true}
} }
func (e *expressionInterfaceImpl) DESC() orderByClause { func (e *expressionInterfaceImpl) DESC() OrderByClause {
return &orderByClauseImpl{expression: e.parent, ascent: false} return &orderByClauseImpl{expression: e.parent, ascent: false}
} }
func (e *expressionInterfaceImpl) CAST_TO(dbType string) expression { func (e *expressionInterfaceImpl) CAST_TO(dbType string) Expression {
return newCast(e.parent, dbType) return newCast(e.parent, dbType)
} }
@ -120,11 +120,11 @@ func (e *expressionInterfaceImpl) serializeAsOrderBy(statement statementType, ou
// Representation of binary operations (e.g. comparisons, arithmetic) // Representation of binary operations (e.g. comparisons, arithmetic)
type binaryOpExpression struct { type binaryOpExpression struct {
lhs, rhs expression lhs, rhs Expression
operator string operator string
} }
func newBinaryExpression(lhs, rhs expression, operator string, parent ...expression) binaryOpExpression { func newBinaryExpression(lhs, rhs Expression, operator string) binaryOpExpression {
binaryExpression := binaryOpExpression{ binaryExpression := binaryOpExpression{
lhs: lhs, lhs: lhs,
rhs: rhs, rhs: rhs,
@ -136,7 +136,7 @@ func newBinaryExpression(lhs, rhs expression, operator string, parent ...express
func (c *binaryOpExpression) serialize(statement statementType, out *queryData, options ...serializeOption) error { func (c *binaryOpExpression) serialize(statement statementType, out *queryData, options ...serializeOption) error {
if c == nil { if c == nil {
return errors.New("Binary expression is nil.") return errors.New("Binary Expression is nil.")
} }
if c.lhs == nil { if c.lhs == nil {
return errors.Newf("nil lhs.") return errors.Newf("nil lhs.")
@ -168,13 +168,13 @@ func (c *binaryOpExpression) serialize(statement statementType, out *queryData,
return nil return nil
} }
// A prefix operator expression // A prefix operator Expression
type prefixOpExpression struct { type prefixOpExpression struct {
expression expression expression Expression
operator string operator string
} }
func newPrefixExpression(expression expression, operator string) prefixOpExpression { func newPrefixExpression(expression Expression, operator string) prefixOpExpression {
prefixExpression := prefixOpExpression{ prefixExpression := prefixOpExpression{
expression: expression, expression: expression,
operator: operator, operator: operator,
@ -185,13 +185,13 @@ func newPrefixExpression(expression expression, operator string) prefixOpExpress
func (p *prefixOpExpression) serialize(statement statementType, out *queryData, options ...serializeOption) error { func (p *prefixOpExpression) serialize(statement statementType, out *queryData, options ...serializeOption) error {
if p == nil { if p == nil {
return errors.New("Prefix expression is nil.") return errors.New("Prefix Expression is nil.")
} }
out.writeString(p.operator + " ") out.writeString(p.operator + " ")
if p.expression == nil { if p.expression == nil {
return errors.Newf("nil prefix expression.") return errors.Newf("nil prefix Expression.")
} }
if err := p.expression.serialize(statement, out); err != nil { if err := p.expression.serialize(statement, out); err != nil {
return err return err
@ -200,13 +200,13 @@ func (p *prefixOpExpression) serialize(statement statementType, out *queryData,
return nil return nil
} }
// A postifx operator expression // A postifx operator Expression
type postfixOpExpression struct { type postfixOpExpression struct {
expression expression expression Expression
operator string operator string
} }
func newPostfixOpExpression(expression expression, operator string) postfixOpExpression { func newPostfixOpExpression(expression Expression, operator string) postfixOpExpression {
postfixOpExpression := postfixOpExpression{ postfixOpExpression := postfixOpExpression{
expression: expression, expression: expression,
operator: operator, operator: operator,
@ -217,11 +217,11 @@ func newPostfixOpExpression(expression expression, operator string) postfixOpExp
func (p *postfixOpExpression) serialize(statement statementType, out *queryData, options ...serializeOption) error { func (p *postfixOpExpression) serialize(statement statementType, out *queryData, options ...serializeOption) error {
if p == nil { if p == nil {
return errors.New("Postifx operator expression is nil.") return errors.New("Postifx operator Expression is nil.")
} }
if p.expression == nil { if p.expression == nil {
return errors.Newf("nil prefix expression.") return errors.Newf("nil prefix Expression.")
} }
if err := p.expression.serialize(statement, out); err != nil { if err := p.expression.serialize(statement, out); err != nil {
return err return err

View file

@ -3,7 +3,7 @@ package sqlbuilder
import "errors" import "errors"
type expressionTable interface { type expressionTable interface {
readableTable ReadableTable
RefIntColumnName(name string) *IntegerColumn RefIntColumnName(name string) *IntegerColumn
RefIntColumn(column column) *IntegerColumn RefIntColumn(column column) *IntegerColumn
@ -11,7 +11,7 @@ type expressionTable interface {
} }
type expressionTableImpl struct { type expressionTableImpl struct {
statement expression statement Expression
alias string alias string
} }
@ -66,33 +66,33 @@ func (e *expressionTableImpl) serialize(statement statementType, out *queryData,
} }
// Generates a select query on the current tableName. // Generates a select query on the current tableName.
func (e *expressionTableImpl) SELECT(projections ...projection) selectStatement { func (e *expressionTableImpl) SELECT(projections ...projection) SelectStatement {
return newSelectStatement(e, projections) return newSelectStatement(e, projections)
} }
// Creates a inner join tableName expression using onCondition. // Creates a inner join tableName Expression using onCondition.
func (e *expressionTableImpl) INNER_JOIN(table readableTable, onCondition BoolExpression) readableTable { func (e *expressionTableImpl) INNER_JOIN(table ReadableTable, onCondition BoolExpression) ReadableTable {
return InnerJoinOn(e, table, onCondition) return InnerJoinOn(e, table, onCondition)
} }
//func (s *expressionTableImpl) InnerJoinUsing(table readableTable, col1 column, col2 column) readableTable { //func (s *expressionTableImpl) InnerJoinUsing(table ReadableTable, col1 column, col2 column) ReadableTable {
// return INNER_JOIN(s, table, col1.EQ(col2)) // return INNER_JOIN(s, table, col1.EQ(col2))
//} //}
// Creates a left join tableName expression using onCondition. // Creates a left join tableName Expression using onCondition.
func (e *expressionTableImpl) LEFT_JOIN(table readableTable, onCondition BoolExpression) readableTable { func (e *expressionTableImpl) LEFT_JOIN(table ReadableTable, onCondition BoolExpression) ReadableTable {
return LeftJoinOn(e, table, onCondition) return LeftJoinOn(e, table, onCondition)
} }
// Creates a right join tableName expression using onCondition. // Creates a right join tableName Expression using onCondition.
func (e *expressionTableImpl) RIGHT_JOIN(table readableTable, onCondition BoolExpression) readableTable { func (e *expressionTableImpl) RIGHT_JOIN(table ReadableTable, onCondition BoolExpression) ReadableTable {
return RightJoinOn(e, table, onCondition) return RightJoinOn(e, table, onCondition)
} }
func (e *expressionTableImpl) FULL_JOIN(table readableTable, onCondition BoolExpression) readableTable { func (e *expressionTableImpl) FULL_JOIN(table ReadableTable, onCondition BoolExpression) ReadableTable {
return FullJoin(e, table, onCondition) return FullJoin(e, table, onCondition)
} }
func (e *expressionTableImpl) CROSS_JOIN(table readableTable) readableTable { func (e *expressionTableImpl) CROSS_JOIN(table ReadableTable) ReadableTable {
return CrossJoin(e, table) return CrossJoin(e, table)
} }

View file

@ -3,7 +3,7 @@ package sqlbuilder
import "errors" import "errors"
type FloatExpression interface { type FloatExpression interface {
expression Expression
EQ(rhs FloatExpression) BoolExpression EQ(rhs FloatExpression) BoolExpression
NOT_EQ(rhs FloatExpression) BoolExpression NOT_EQ(rhs FloatExpression) BoolExpression
@ -107,10 +107,10 @@ type floatExpressionWrapper struct {
expressionInterfaceImpl expressionInterfaceImpl
floatInterfaceImpl floatInterfaceImpl
expression expression expression Expression
} }
func newFloatExpressionWrap(expression expression) FloatExpression { func newFloatExpressionWrap(expression Expression) FloatExpression {
floatExpressionWrap := floatExpressionWrapper{} floatExpressionWrap := floatExpressionWrapper{}
floatExpressionWrap.expression = expression floatExpressionWrap.expression = expression

View file

@ -6,11 +6,11 @@ type funcExpressionImpl struct {
expressionInterfaceImpl expressionInterfaceImpl
name string name string
expressions []expression expressions []Expression
noBrackets bool noBrackets bool
} }
func newFunc(name string, expressions []expression, parent expression) *funcExpressionImpl { func newFunc(name string, expressions []Expression, parent Expression) *funcExpressionImpl {
funcExp := &funcExpressionImpl{ funcExp := &funcExpressionImpl{
name: name, name: name,
expressions: expressions, expressions: expressions,
@ -55,7 +55,7 @@ type boolFunc struct {
boolInterfaceImpl boolInterfaceImpl
} }
func newBoolFunc(name string, expressions ...expression) BoolExpression { func newBoolFunc(name string, expressions ...Expression) BoolExpression {
boolFunc := &boolFunc{} boolFunc := &boolFunc{}
boolFunc.funcExpressionImpl = *newFunc(name, expressions, boolFunc) boolFunc.funcExpressionImpl = *newFunc(name, expressions, boolFunc)
@ -69,7 +69,7 @@ type floatFunc struct {
floatInterfaceImpl floatInterfaceImpl
} }
func newFloatFunc(name string, expressions ...expression) FloatExpression { func newFloatFunc(name string, expressions ...Expression) FloatExpression {
floatFunc := &floatFunc{} floatFunc := &floatFunc{}
floatFunc.funcExpressionImpl = *newFunc(name, expressions, floatFunc) floatFunc.funcExpressionImpl = *newFunc(name, expressions, floatFunc)
@ -83,7 +83,7 @@ type integerFunc struct {
integerInterfaceImpl integerInterfaceImpl
} }
func newIntegerFunc(name string, expressions ...expression) IntegerExpression { func newIntegerFunc(name string, expressions ...Expression) IntegerExpression {
floatFunc := &integerFunc{} floatFunc := &integerFunc{}
floatFunc.funcExpressionImpl = *newFunc(name, expressions, floatFunc) floatFunc.funcExpressionImpl = *newFunc(name, expressions, floatFunc)
@ -97,7 +97,7 @@ type stringFunc struct {
stringInterfaceImpl stringInterfaceImpl
} }
func newStringFunc(name string, expressions ...expression) StringExpression { func newStringFunc(name string, expressions ...Expression) StringExpression {
stringFunc := &stringFunc{} stringFunc := &stringFunc{}
stringFunc.funcExpressionImpl = *newFunc(name, expressions, stringFunc) stringFunc.funcExpressionImpl = *newFunc(name, expressions, stringFunc)
@ -111,7 +111,7 @@ type dateFunc struct {
dateInterfaceImpl dateInterfaceImpl
} }
func newDateFunc(name string, expressions ...expression) *dateFunc { func newDateFunc(name string, expressions ...Expression) *dateFunc {
dateFunc := &dateFunc{} dateFunc := &dateFunc{}
dateFunc.funcExpressionImpl = *newFunc(name, expressions, dateFunc) dateFunc.funcExpressionImpl = *newFunc(name, expressions, dateFunc)
@ -125,7 +125,7 @@ type timeFunc struct {
timeInterfaceImpl timeInterfaceImpl
} }
func newTimeFunc(name string, expressions ...expression) *timeFunc { func newTimeFunc(name string, expressions ...Expression) *timeFunc {
timeFun := &timeFunc{} timeFun := &timeFunc{}
timeFun.funcExpressionImpl = *newFunc(name, expressions, timeFun) timeFun.funcExpressionImpl = *newFunc(name, expressions, timeFun)
@ -139,7 +139,7 @@ type timezFunc struct {
timezInterfaceImpl timezInterfaceImpl
} }
func newTimezFunc(name string, expressions ...expression) *timezFunc { func newTimezFunc(name string, expressions ...Expression) *timezFunc {
timezFun := &timezFunc{} timezFun := &timezFunc{}
timezFun.funcExpressionImpl = *newFunc(name, expressions, timezFun) timezFun.funcExpressionImpl = *newFunc(name, expressions, timezFun)
@ -153,7 +153,7 @@ type timestampFunc struct {
timestampInterfaceImpl timestampInterfaceImpl
} }
func newTimestampFunc(name string, expressions ...expression) *timestampFunc { func newTimestampFunc(name string, expressions ...Expression) *timestampFunc {
timestampFunc := &timestampFunc{} timestampFunc := &timestampFunc{}
timestampFunc.funcExpressionImpl = *newFunc(name, expressions, timestampFunc) timestampFunc.funcExpressionImpl = *newFunc(name, expressions, timestampFunc)
@ -167,7 +167,7 @@ type timestampzFunc struct {
timestampzInterfaceImpl timestampzInterfaceImpl
} }
func newTimestampzFunc(name string, expressions ...expression) *timestampzFunc { func newTimestampzFunc(name string, expressions ...Expression) *timestampzFunc {
timestampzFunc := &timestampzFunc{} timestampzFunc := &timestampzFunc{}
timestampzFunc.funcExpressionImpl = *newFunc(name, expressions, timestampzFunc) timestampzFunc.funcExpressionImpl = *newFunc(name, expressions, timestampzFunc)
@ -176,7 +176,7 @@ func newTimestampzFunc(name string, expressions ...expression) *timestampzFunc {
return timestampzFunc return timestampzFunc
} }
func ROW(expressions ...expression) expression { func ROW(expressions ...Expression) Expression {
return newFunc("ROW", expressions, nil) return newFunc("ROW", expressions, nil)
} }
@ -266,7 +266,7 @@ func BOOL_OR(boolExpression BoolExpression) BoolExpression {
return newBoolFunc("BOOL_OR", boolExpression) return newBoolFunc("BOOL_OR", boolExpression)
} }
func COUNT(expression expression) IntegerExpression { func COUNT(expression Expression) IntegerExpression {
return newIntegerFunc("COUNT", expression) return newIntegerFunc("COUNT", expression)
} }
@ -343,11 +343,11 @@ func CHR(integerExpression IntegerExpression) StringExpression {
} }
// //
//func CONCAT(expressions ...expression) StringExpression { //func CONCAT(expressions ...Expression) StringExpression {
// return newStringFunc("CONCAT", expressions...) // return newStringFunc("CONCAT", expressions...)
//} //}
// //
//func CONCAT_WS(expressions ...expression) StringExpression { //func CONCAT_WS(expressions ...Expression) StringExpression {
// return newStringFunc("CONCAT_WS", expressions...) // return newStringFunc("CONCAT_WS", expressions...)
//} //}
@ -452,7 +452,7 @@ func TO_HEX(number IntegerExpression) StringExpression {
//----------Data Type Formatting Functions ----------------------// //----------Data Type Formatting Functions ----------------------//
func TO_CHAR(expression expression, text StringExpression) StringExpression { func TO_CHAR(expression Expression, text StringExpression) StringExpression {
return newStringFunc("TO_CHAR", expression, text) return newStringFunc("TO_CHAR", expression, text)
} }
@ -538,24 +538,24 @@ func NOW() TimestampzExpression {
// --------------- Conditional Expressions Functions -------------// // --------------- Conditional Expressions Functions -------------//
func COALESCE(value expression, values ...expression) expression { func COALESCE(value Expression, values ...Expression) Expression {
var allValues = []expression{value} var allValues = []Expression{value}
allValues = append(allValues, values...) allValues = append(allValues, values...)
return newFunc("COALESCE", allValues, nil) return newFunc("COALESCE", allValues, nil)
} }
func NULLIF(value1, value2 expression) expression { func NULLIF(value1, value2 Expression) Expression {
return newFunc("NULLIF", []expression{value1, value2}, nil) return newFunc("NULLIF", []Expression{value1, value2}, nil)
} }
func GREATEST(value expression, values ...expression) expression { func GREATEST(value Expression, values ...Expression) Expression {
var allValues = []expression{value} var allValues = []Expression{value}
allValues = append(allValues, values...) allValues = append(allValues, values...)
return newFunc("GREATEST", allValues, nil) return newFunc("GREATEST", allValues, nil)
} }
func LEAST(value expression, values ...expression) expression { func LEAST(value Expression, values ...Expression) Expression {
var allValues = []expression{value} var allValues = []Expression{value}
allValues = append(allValues, values...) allValues = append(allValues, values...)
return newFunc("LEAST", allValues, nil) return newFunc("LEAST", allValues, nil)
} }

View file

@ -9,20 +9,20 @@ import (
"strings" "strings"
) )
type insertStatement interface { type InsertStatement interface {
Statement Statement
// Add a row of values to the insert Statement. // Add a row of values to the insert Statement.
VALUES(values ...interface{}) insertStatement VALUES(values ...interface{}) InsertStatement
// Map or stracture mapped to column names // Map or stracture mapped to column names
VALUES_MAPPING(data interface{}) insertStatement VALUES_MAPPING(data interface{}) InsertStatement
RETURNING(projections ...projection) insertStatement RETURNING(projections ...projection) InsertStatement
QUERY(selectStatement selectStatement) insertStatement QUERY(selectStatement SelectStatement) InsertStatement
} }
func newInsertStatement(t writableTable, columns ...column) insertStatement { func newInsertStatement(t writableTable, columns ...column) InsertStatement {
return &insertStatementImpl{ return &insertStatementImpl{
table: t, table: t,
columns: columns, columns: columns,
@ -33,7 +33,7 @@ type insertStatementImpl struct {
table writableTable table writableTable
columns []column columns []column
rows [][]clause rows [][]clause
query selectStatement query SelectStatement
returning []projection returning []projection
errors []string errors []string
@ -47,8 +47,8 @@ func (u *insertStatementImpl) Execute(db execution.Db) (res sql.Result, err erro
return Execute(u, db) return Execute(u, db)
} }
// expression or default keyword // Expression or default keyword
func (i *insertStatementImpl) VALUES(values ...interface{}) insertStatement { func (i *insertStatementImpl) VALUES(values ...interface{}) InsertStatement {
if len(values) == 0 { if len(values) == 0 {
return i return i
} }
@ -67,7 +67,7 @@ func (i *insertStatementImpl) VALUES(values ...interface{}) insertStatement {
return i return i
} }
func (i *insertStatementImpl) VALUES_MAPPING(data interface{}) insertStatement { func (i *insertStatementImpl) VALUES_MAPPING(data interface{}) InsertStatement {
if data == nil { if data == nil {
i.addError("ADD method data is nil.") i.addError("ADD method data is nil.")
return i return i
@ -105,13 +105,13 @@ func (i *insertStatementImpl) VALUES_MAPPING(data interface{}) insertStatement {
return i return i
} }
func (i *insertStatementImpl) RETURNING(projections ...projection) insertStatement { func (i *insertStatementImpl) RETURNING(projections ...projection) InsertStatement {
i.returning = defaultProjectionAliasing(projections) i.returning = defaultProjectionAliasing(projections)
return i return i
} }
func (i *insertStatementImpl) QUERY(selectStatement selectStatement) insertStatement { func (i *insertStatementImpl) QUERY(selectStatement SelectStatement) InsertStatement {
i.query = selectStatement i.query = selectStatement
return i return i

View file

@ -1,7 +1,7 @@
package sqlbuilder package sqlbuilder
type IntegerExpression interface { type IntegerExpression interface {
expression Expression
EQ(rhs IntegerExpression) BoolExpression EQ(rhs IntegerExpression) BoolExpression
NOT_EQ(rhs IntegerExpression) BoolExpression NOT_EQ(rhs IntegerExpression) BoolExpression

View file

@ -181,7 +181,7 @@ type nullLiteral struct {
expressionInterfaceImpl expressionInterfaceImpl
} }
func newNullLiteral() expression { func newNullLiteral() Expression {
nullExpression := &nullLiteral{} nullExpression := &nullLiteral{}
nullExpression.expressionInterfaceImpl.parent = nullExpression nullExpression.expressionInterfaceImpl.parent = nullExpression
@ -199,7 +199,7 @@ type starLiteral struct {
expressionInterfaceImpl expressionInterfaceImpl
} }
func newStarLiteral() expression { func newStarLiteral() Expression {
starExpression := &starLiteral{} starExpression := &starLiteral{}
starExpression.expressionInterfaceImpl.parent = starExpression starExpression.expressionInterfaceImpl.parent = starExpression
@ -216,7 +216,7 @@ func (n *starLiteral) serialize(statement statementType, out *queryData, options
type wrap struct { type wrap struct {
expressionInterfaceImpl expressionInterfaceImpl
expressions []expression expressions []Expression
} }
func (n *wrap) serialize(statement statementType, out *queryData, options ...serializeOption) error { func (n *wrap) serialize(statement statementType, out *queryData, options ...serializeOption) error {
@ -226,9 +226,28 @@ func (n *wrap) serialize(statement statementType, out *queryData, options ...ser
return err return err
} }
func WRAP(expression ...expression) expression { func WRAP(expression ...Expression) Expression {
wrap := &wrap{expressions: expression} wrap := &wrap{expressions: expression}
wrap.expressionInterfaceImpl.parent = wrap wrap.expressionInterfaceImpl.parent = wrap
return wrap return wrap
} }
//---------------------------------------------------//
type rawExpression struct {
expressionInterfaceImpl
raw string
}
func (n *rawExpression) serialize(statement statementType, out *queryData, options ...serializeOption) error {
out.writeString(n.raw)
return nil
}
func RAW(raw string) Expression {
rawExp := &rawExpression{raw: raw}
rawExp.expressionInterfaceImpl.parent = rawExp
return rawExp
}

View file

@ -0,0 +1,7 @@
package sqlbuilder
import "testing"
func TestRawExpression(t *testing.T) {
assertExpressionSerialize(t, RAW("current_database()"), "current_database()")
}

View file

@ -19,11 +19,11 @@ const (
LOCK_ACCESS_EXCLUSIVE = "ACCESS EXCLUSIVE" LOCK_ACCESS_EXCLUSIVE = "ACCESS EXCLUSIVE"
) )
type lockStatement interface { type LockStatement interface {
Statement Statement
IN(lockMode lockMode) lockStatement IN(lockMode lockMode) LockStatement
NOWAIT() lockStatement NOWAIT() LockStatement
} }
type lockStatementImpl struct { type lockStatementImpl struct {
@ -32,18 +32,18 @@ type lockStatementImpl struct {
nowait bool nowait bool
} }
func LOCK(tables ...tableInterface) lockStatement { func LOCK(tables ...tableInterface) LockStatement {
return &lockStatementImpl{ return &lockStatementImpl{
tables: tables, tables: tables,
} }
} }
func (l *lockStatementImpl) IN(lockMode lockMode) lockStatement { func (l *lockStatementImpl) IN(lockMode lockMode) LockStatement {
l.lockMode = lockMode l.lockMode = lockMode
return l return l
} }
func (l *lockStatementImpl) NOWAIT() lockStatement { func (l *lockStatementImpl) NOWAIT() LockStatement {
l.nowait = true l.nowait = true
return l return l
} }

View file

@ -12,40 +12,40 @@ func NOT(expr BoolExpression) BoolExpression {
//----------- Comparison operators ---------------// //----------- Comparison operators ---------------//
// Returns a representation of "a=b" // Returns a representation of "a=b"
func EQ(lhs, rhs expression) BoolExpression { func EQ(lhs, rhs Expression) BoolExpression {
return newBinaryBoolExpression(lhs, rhs, "=") return newBinaryBoolExpression(lhs, rhs, "=")
} }
// Returns a representation of "a!=b" // Returns a representation of "a!=b"
func NOT_EQ(lhs, rhs expression) BoolExpression { func NOT_EQ(lhs, rhs Expression) BoolExpression {
return newBinaryBoolExpression(lhs, rhs, "!=") return newBinaryBoolExpression(lhs, rhs, "!=")
} }
func IS_DISTINCT_FROM(lhs, rhs expression) BoolExpression { func IS_DISTINCT_FROM(lhs, rhs Expression) BoolExpression {
return newBinaryBoolExpression(lhs, rhs, "IS DISTINCT FROM") return newBinaryBoolExpression(lhs, rhs, "IS DISTINCT FROM")
} }
func IS_NOT_DISTINCT_FROM(lhs, rhs expression) BoolExpression { func IS_NOT_DISTINCT_FROM(lhs, rhs Expression) BoolExpression {
return newBinaryBoolExpression(lhs, rhs, "IS NOT DISTINCT FROM") return newBinaryBoolExpression(lhs, rhs, "IS NOT DISTINCT FROM")
} }
// Returns a representation of "a<b" // Returns a representation of "a<b"
func LT(lhs expression, rhs expression) BoolExpression { func LT(lhs Expression, rhs Expression) BoolExpression {
return newBinaryBoolExpression(lhs, rhs, "<") return newBinaryBoolExpression(lhs, rhs, "<")
} }
// Returns a representation of "a<=b" // Returns a representation of "a<=b"
func LT_EQ(lhs, rhs expression) BoolExpression { func LT_EQ(lhs, rhs Expression) BoolExpression {
return newBinaryBoolExpression(lhs, rhs, "<=") return newBinaryBoolExpression(lhs, rhs, "<=")
} }
// Returns a representation of "a>b" // Returns a representation of "a>b"
func GT(lhs, rhs expression) BoolExpression { func GT(lhs, rhs Expression) BoolExpression {
return newBinaryBoolExpression(lhs, rhs, ">") return newBinaryBoolExpression(lhs, rhs, ">")
} }
// Returns a representation of "a>=b" // Returns a representation of "a>=b"
func GT_EQ(lhs, rhs expression) BoolExpression { func GT_EQ(lhs, rhs Expression) BoolExpression {
return newBinaryBoolExpression(lhs, rhs, ">=") return newBinaryBoolExpression(lhs, rhs, ">=")
} }
@ -73,47 +73,47 @@ func IS_NOT_UNKNOWN(expr BoolExpression) BoolExpression {
return newPostifxBoolExpression(expr, "IS NOT UNKNOWN") return newPostifxBoolExpression(expr, "IS NOT UNKNOWN")
} }
func And(lhs, rhs expression) BoolExpression { func And(lhs, rhs Expression) BoolExpression {
return newBinaryBoolExpression(lhs, rhs, "AND") return newBinaryBoolExpression(lhs, rhs, "AND")
} }
// Returns a representation of "c[0] OR ... OR c[n-1]" for c in clauses // Returns a representation of "c[0] OR ... OR c[n-1]" for c in clauses
func Or(lhs, rhs expression) BoolExpression { func Or(lhs, rhs Expression) BoolExpression {
return newBinaryBoolExpression(lhs, rhs, "OR") return newBinaryBoolExpression(lhs, rhs, "OR")
} }
func Regexp(lhs, rhs expression) BoolExpression { func Regexp(lhs, rhs Expression) BoolExpression {
return newBinaryBoolExpression(lhs, rhs, "REGEXP") return newBinaryBoolExpression(lhs, rhs, "REGEXP")
} }
func RegexpL(lhs expression, val string) BoolExpression { func RegexpL(lhs Expression, val string) BoolExpression {
return Regexp(lhs, literal(val)) return Regexp(lhs, literal(val))
} }
func EXISTS(subQuery selectStatement) BoolExpression { func EXISTS(subQuery SelectStatement) BoolExpression {
return newPrefixBoolExpression(subQuery, "EXISTS") return newPrefixBoolExpression(subQuery, "EXISTS")
} }
// --------------- CASE operator -------------------// // --------------- CASE operator -------------------//
type caseOperatorExpression interface { type caseOperatorExpression interface {
expression Expression
WHEN(condition expression) caseOperatorExpression WHEN(condition Expression) caseOperatorExpression
THEN(then expression) caseOperatorExpression THEN(then Expression) caseOperatorExpression
ELSE(els expression) caseOperatorExpression ELSE(els Expression) caseOperatorExpression
} }
type caseOperatorImpl struct { type caseOperatorImpl struct {
expressionInterfaceImpl expressionInterfaceImpl
expression expression expression Expression
when []expression when []Expression
then []expression then []Expression
els expression els Expression
} }
func CASE(expression ...expression) caseOperatorExpression { func CASE(expression ...Expression) caseOperatorExpression {
caseExp := &caseOperatorImpl{} caseExp := &caseOperatorImpl{}
if len(expression) > 0 { if len(expression) > 0 {
@ -125,17 +125,17 @@ func CASE(expression ...expression) caseOperatorExpression {
return caseExp return caseExp
} }
func (c *caseOperatorImpl) WHEN(when expression) caseOperatorExpression { func (c *caseOperatorImpl) WHEN(when Expression) caseOperatorExpression {
c.when = append(c.when, when) c.when = append(c.when, when)
return c return c
} }
func (c *caseOperatorImpl) THEN(then expression) caseOperatorExpression { func (c *caseOperatorImpl) THEN(then Expression) caseOperatorExpression {
c.then = append(c.then, then) c.then = append(c.then, then)
return c return c
} }
func (c *caseOperatorImpl) ELSE(els expression) caseOperatorExpression { func (c *caseOperatorImpl) ELSE(els Expression) caseOperatorExpression {
c.els = els c.els = els
return c return c
@ -143,7 +143,7 @@ func (c *caseOperatorImpl) ELSE(els expression) caseOperatorExpression {
func (c *caseOperatorImpl) serialize(statement statementType, out *queryData, options ...serializeOption) error { func (c *caseOperatorImpl) serialize(statement statementType, out *queryData, options ...serializeOption) error {
if c == nil { if c == nil {
return errors.New("Case expression is nil. ") return errors.New("Case Expression is nil. ")
} }
out.writeString("(CASE") out.writeString("(CASE")
@ -157,11 +157,11 @@ func (c *caseOperatorImpl) serialize(statement statementType, out *queryData, op
} }
if len(c.when) == 0 || len(c.then) == 0 { if len(c.when) == 0 || len(c.then) == 0 {
return errors.New("Invalid case Statement. There should be at least one when/then expression pair. ") return errors.New("Invalid case Statement. There should be at least one when/then Expression pair. ")
} }
if len(c.when) != len(c.then) { if len(c.when) != len(c.then) {
return errors.New("When and then expression count mismatch. ") return errors.New("When and then Expression count mismatch. ")
} }
for i, when := range c.when { for i, when := range c.when {

View file

@ -2,12 +2,12 @@ package sqlbuilder
import "github.com/dropbox/godropbox/errors" import "github.com/dropbox/godropbox/errors"
type orderByClause interface { type OrderByClause interface {
serializeAsOrderBy(statement statementType, out *queryData) error serializeAsOrderBy(statement statementType, out *queryData) error
} }
type orderByClauseImpl struct { type orderByClauseImpl struct {
expression expression expression Expression
ascent bool ascent bool
} }
@ -29,10 +29,10 @@ func (o *orderByClauseImpl) serializeAsOrderBy(statement statementType, out *que
return nil return nil
} }
func ASC(expression expression) orderByClause { func ASC(expression Expression) OrderByClause {
return &orderByClauseImpl{expression: expression, ascent: true} return &orderByClauseImpl{expression: expression, ascent: true}
} }
func DESC(expression expression) orderByClause { func DESC(expression Expression) OrderByClause {
return &orderByClauseImpl{expression: expression, ascent: false} return &orderByClauseImpl{expression: expression, ascent: false}
} }

View file

@ -6,43 +6,43 @@ import (
"github.com/sub0zero/go-sqlbuilder/sqlbuilder/execution" "github.com/sub0zero/go-sqlbuilder/sqlbuilder/execution"
) )
type selectStatement interface { type SelectStatement interface {
Statement Statement
expression Expression
hasRows() hasRows()
DISTINCT() selectStatement DISTINCT() SelectStatement
FROM(table readableTable) selectStatement FROM(table ReadableTable) SelectStatement
WHERE(expression BoolExpression) selectStatement WHERE(expression BoolExpression) SelectStatement
GROUP_BY(groupByClauses ...groupByClause) selectStatement GROUP_BY(groupByClauses ...groupByClause) SelectStatement
HAVING(boolExpression BoolExpression) selectStatement HAVING(boolExpression BoolExpression) SelectStatement
ORDER_BY(orderByClauses ...orderByClause) selectStatement ORDER_BY(orderByClauses ...OrderByClause) SelectStatement
LIMIT(limit int64) selectStatement LIMIT(limit int64) SelectStatement
OFFSET(offset int64) selectStatement OFFSET(offset int64) SelectStatement
FOR_UPDATE() selectStatement FOR_UPDATE() SelectStatement
AsTable(alias string) expressionTable AsTable(alias string) expressionTable
} }
func SELECT(projection ...projection) selectStatement { func SELECT(projection ...projection) SelectStatement {
return newSelectStatement(nil, projection) return newSelectStatement(nil, projection)
} }
// NOTE: selectStatement purposely does not implement the Table interface since // NOTE: SelectStatement purposely does not implement the Table interface since
// mysql's subquery performance is horrible. // mysql's subquery performance is horrible.
type selectStatementImpl struct { type selectStatementImpl struct {
expressionInterfaceImpl expressionInterfaceImpl
isRowsType isRowsType
table readableTable table ReadableTable
distinct bool distinct bool
projections []projection projections []projection
where BoolExpression where BoolExpression
groupBy []groupByClause groupBy []groupByClause
having BoolExpression having BoolExpression
orderBy []orderByClause orderBy []OrderByClause
limit, offset int64 limit, offset int64
@ -65,7 +65,7 @@ func defaultProjectionAliasing(projections []projection) []projection {
return aliasedProjections return aliasedProjections
} }
func newSelectStatement(table readableTable, projections []projection) selectStatement { func newSelectStatement(table ReadableTable, projections []projection) SelectStatement {
newSelect := &selectStatementImpl{ newSelect := &selectStatementImpl{
table: table, table: table,
projections: defaultProjectionAliasing(projections), projections: defaultProjectionAliasing(projections),
@ -80,7 +80,7 @@ func newSelectStatement(table readableTable, projections []projection) selectSta
return newSelect return newSelect
} }
func (s *selectStatementImpl) FROM(table readableTable) selectStatement { func (s *selectStatementImpl) FROM(table ReadableTable) SelectStatement {
s.table = table s.table = table
return s return s
} }
@ -211,44 +211,44 @@ func (s *selectStatementImpl) AsTable(alias string) expressionTable {
} }
} }
func (s *selectStatementImpl) WHERE(expression BoolExpression) selectStatement { func (s *selectStatementImpl) WHERE(expression BoolExpression) SelectStatement {
s.where = expression s.where = expression
return s return s
} }
func (s *selectStatementImpl) GROUP_BY(groupByClauses ...groupByClause) selectStatement { func (s *selectStatementImpl) GROUP_BY(groupByClauses ...groupByClause) SelectStatement {
s.groupBy = groupByClauses s.groupBy = groupByClauses
return s return s
} }
func (s *selectStatementImpl) HAVING(expression BoolExpression) selectStatement { func (s *selectStatementImpl) HAVING(expression BoolExpression) SelectStatement {
s.having = expression s.having = expression
return s return s
} }
func (s *selectStatementImpl) ORDER_BY(clauses ...orderByClause) selectStatement { func (s *selectStatementImpl) ORDER_BY(clauses ...OrderByClause) SelectStatement {
s.orderBy = clauses s.orderBy = clauses
return s return s
} }
func (s *selectStatementImpl) OFFSET(offset int64) selectStatement { func (s *selectStatementImpl) OFFSET(offset int64) SelectStatement {
s.offset = offset s.offset = offset
return s return s
} }
func (s *selectStatementImpl) LIMIT(limit int64) selectStatement { func (s *selectStatementImpl) LIMIT(limit int64) SelectStatement {
s.limit = limit s.limit = limit
return s return s
} }
func (s *selectStatementImpl) DISTINCT() selectStatement { func (s *selectStatementImpl) DISTINCT() SelectStatement {
s.distinct = true s.distinct = true
return s return s
} }
func (s *selectStatementImpl) FOR_UPDATE() selectStatement { func (s *selectStatementImpl) FOR_UPDATE() SelectStatement {
s.forUpdate = true s.forUpdate = true
return s return s
} }
@ -261,6 +261,6 @@ func (s *selectStatementImpl) Execute(db execution.Db) (res sql.Result, err erro
return Execute(s, db) return Execute(s, db)
} }
func NumExp(expression expression) FloatExpression { func NumExp(expression Expression) FloatExpression {
return newFloatExpressionWrap(expression) return newFloatExpressionWrap(expression)
} }

View file

@ -6,14 +6,14 @@ import (
"github.com/sub0zero/go-sqlbuilder/sqlbuilder/execution" "github.com/sub0zero/go-sqlbuilder/sqlbuilder/execution"
) )
type setStatement interface { type SetStatement interface {
Statement Statement
expression Expression
hasRows() hasRows()
ORDER_BY(clauses ...orderByClause) setStatement ORDER_BY(clauses ...OrderByClause) SetStatement
LIMIT(limit int64) setStatement LIMIT(limit int64) SetStatement
OFFSET(offset int64) setStatement OFFSET(offset int64) SetStatement
AsTable(alias string) expressionTable AsTable(alias string) expressionTable
} }
@ -24,27 +24,27 @@ const (
except = "EXCEPT" except = "EXCEPT"
) )
func UNION(selects ...rowsType) setStatement { func UNION(selects ...rowsType) SetStatement {
return newSetStatementImpl(union, false, selects...) return newSetStatementImpl(union, false, selects...)
} }
func UNION_ALL(selects ...rowsType) setStatement { func UNION_ALL(selects ...rowsType) SetStatement {
return newSetStatementImpl(union, true, selects...) return newSetStatementImpl(union, true, selects...)
} }
func INTERSECT(selects ...rowsType) setStatement { func INTERSECT(selects ...rowsType) SetStatement {
return newSetStatementImpl(intersect, false, selects...) return newSetStatementImpl(intersect, false, selects...)
} }
func INTERSECT_ALL(selects ...rowsType) setStatement { func INTERSECT_ALL(selects ...rowsType) SetStatement {
return newSetStatementImpl(intersect, true, selects...) return newSetStatementImpl(intersect, true, selects...)
} }
func EXCEPT(selects ...rowsType) setStatement { func EXCEPT(selects ...rowsType) SetStatement {
return newSetStatementImpl(except, false, selects...) return newSetStatementImpl(except, false, selects...)
} }
func EXCEPT_ALL(selects ...rowsType) setStatement { func EXCEPT_ALL(selects ...rowsType) SetStatement {
return newSetStatementImpl(except, true, selects...) return newSetStatementImpl(except, true, selects...)
} }
@ -55,13 +55,13 @@ type setStatementImpl struct {
operator string operator string
selects []rowsType selects []rowsType
orderBy []orderByClause orderBy []OrderByClause
limit, offset int64 limit, offset int64
// True if results of the union should be deduped. // True if results of the union should be deduped.
all bool all bool
} }
func newSetStatementImpl(operator string, all bool, selects ...rowsType) setStatement { func newSetStatementImpl(operator string, all bool, selects ...rowsType) SetStatement {
setStatement := &setStatementImpl{ setStatement := &setStatementImpl{
operator: operator, operator: operator,
selects: selects, selects: selects,
@ -75,18 +75,18 @@ func newSetStatementImpl(operator string, all bool, selects ...rowsType) setStat
return setStatement return setStatement
} }
func (us *setStatementImpl) ORDER_BY(orderBy ...orderByClause) setStatement { func (us *setStatementImpl) ORDER_BY(orderBy ...OrderByClause) SetStatement {
us.orderBy = orderBy us.orderBy = orderBy
return us return us
} }
func (us *setStatementImpl) LIMIT(limit int64) setStatement { func (us *setStatementImpl) LIMIT(limit int64) SetStatement {
us.limit = limit us.limit = limit
return us return us
} }
func (us *setStatementImpl) OFFSET(offset int64) setStatement { func (us *setStatementImpl) OFFSET(offset int64) SetStatement {
us.offset = offset us.offset = offset
return us return us
} }

View file

@ -406,7 +406,7 @@ func (s *StmtSuite) TestUnlockStatement(c *gc.C) {
} }
func (s *StmtSuite) TestUnionSelectStatement(c *gc.C) { func (s *StmtSuite) TestUnionSelectStatement(c *gc.C) {
select_queries := make([]selectStatement, 0, 3) select_queries := make([]SelectStatement, 0, 3)
select_queries = append(select_queries, select_queries = append(select_queries,
table1.Select(table1Col1).Where(GtL(table1Col1, 123)), table1.Select(table1Col1).Where(GtL(table1Col1, 123)),
@ -428,7 +428,7 @@ func (s *StmtSuite) TestUnionSelectStatement(c *gc.C) {
} }
func (s *StmtSuite) TestUnionLimitWithoutOrderBy(c *gc.C) { func (s *StmtSuite) TestUnionLimitWithoutOrderBy(c *gc.C) {
select_queries := make([]selectStatement, 0, 3) select_queries := make([]SelectStatement, 0, 3)
select_queries = append(select_queries, select_queries = append(select_queries,
table1.Select(table1Col1).Where(GtL(table1Col1, 123)).OrderBy(table1ColFloat), table1.Select(table1Col1).Where(GtL(table1Col1, 123)).OrderBy(table1ColFloat),
@ -448,7 +448,7 @@ func (s *StmtSuite) TestUnionLimitWithoutOrderBy(c *gc.C) {
} }
func (s *StmtSuite) TestUnionSelectWithMismatchedColumns(c *gc.C) { func (s *StmtSuite) TestUnionSelectWithMismatchedColumns(c *gc.C) {
select_queries := make([]selectStatement, 0, 3) select_queries := make([]SelectStatement, 0, 3)
select_queries = append(select_queries, select_queries = append(select_queries,
@ -483,7 +483,7 @@ func (s *StmtSuite) TestComplicatedUnionSelectWithWhereStatement(c *gc.C) {
// tests on outer Statement: Group By, Order By, LIMIT // tests on outer Statement: Group By, Order By, LIMIT
// on inner Statement: AndWhere, WHERE (with AND), Order By, LIMIT // on inner Statement: AndWhere, WHERE (with AND), Order By, LIMIT
select_queries := make([]selectStatement, 0, 3) select_queries := make([]SelectStatement, 0, 3)
// We're not trying to write a SQL parser, so we won't warn if you do something silly like // We're not trying to write a SQL parser, so we won't warn if you do something silly like
// try to apply a where clause on more columns than you've selected in your union select // try to apply a where clause on more columns than you've selected in your union select

View file

@ -1,7 +1,7 @@
package sqlbuilder package sqlbuilder
type StringExpression interface { type StringExpression interface {
expression Expression
EQ(rhs StringExpression) BoolExpression EQ(rhs StringExpression) BoolExpression
NOT_EQ(rhs StringExpression) BoolExpression NOT_EQ(rhs StringExpression) BoolExpression
@ -13,7 +13,7 @@ type StringExpression interface {
GT(rhs StringExpression) BoolExpression GT(rhs StringExpression) BoolExpression
GT_EQ(rhs StringExpression) BoolExpression GT_EQ(rhs StringExpression) BoolExpression
CONCAT(rhs expression) StringExpression CONCAT(rhs Expression) StringExpression
LIKE(pattern StringExpression) BoolExpression LIKE(pattern StringExpression) BoolExpression
NOT_LIKE(pattern StringExpression) BoolExpression NOT_LIKE(pattern StringExpression) BoolExpression
@ -57,7 +57,7 @@ func (s *stringInterfaceImpl) LT_EQ(rhs StringExpression) BoolExpression {
return LT_EQ(s.parent, rhs) return LT_EQ(s.parent, rhs)
} }
func (s *stringInterfaceImpl) CONCAT(rhs expression) StringExpression { func (s *stringInterfaceImpl) CONCAT(rhs Expression) StringExpression {
return newBinaryStringExpression(s.parent, rhs, "||") return newBinaryStringExpression(s.parent, rhs, "||")
} }
@ -85,7 +85,7 @@ type binaryStringExpression struct {
binaryOpExpression binaryOpExpression
} }
func newBinaryStringExpression(lhs, rhs expression, operator string) StringExpression { func newBinaryStringExpression(lhs, rhs Expression, operator string) StringExpression {
boolExpression := binaryStringExpression{} boolExpression := binaryStringExpression{}
boolExpression.binaryOpExpression = newBinaryExpression(lhs, rhs, operator) boolExpression.binaryOpExpression = newBinaryExpression(lhs, rhs, operator)

View file

@ -16,35 +16,35 @@ type tableInterface interface {
// The sql tableName read interface. NOTE: NATURAL JOINs, and join "USING" clause // The sql tableName read interface. NOTE: NATURAL JOINs, and join "USING" clause
// are not supported. // are not supported.
type readableTable interface { type ReadableTable interface {
tableInterface tableInterface
// Generates a select query on the current tableName. // Generates a select query on the current tableName.
SELECT(projections ...projection) selectStatement SELECT(projections ...projection) SelectStatement
// Creates a inner join tableName expression using onCondition. // Creates a inner join tableName Expression using onCondition.
INNER_JOIN(table readableTable, onCondition BoolExpression) readableTable INNER_JOIN(table ReadableTable, onCondition BoolExpression) ReadableTable
// Creates a left join tableName expression using onCondition. // Creates a left join tableName Expression using onCondition.
LEFT_JOIN(table readableTable, onCondition BoolExpression) readableTable LEFT_JOIN(table ReadableTable, onCondition BoolExpression) ReadableTable
// Creates a right join tableName expression using onCondition. // Creates a right join tableName Expression using onCondition.
RIGHT_JOIN(table readableTable, onCondition BoolExpression) readableTable RIGHT_JOIN(table ReadableTable, onCondition BoolExpression) ReadableTable
FULL_JOIN(table readableTable, onCondition BoolExpression) readableTable FULL_JOIN(table ReadableTable, onCondition BoolExpression) ReadableTable
CROSS_JOIN(table readableTable) readableTable CROSS_JOIN(table ReadableTable) ReadableTable
} }
// The sql tableName write interface. // The sql tableName write interface.
type writableTable interface { type writableTable interface {
tableInterface tableInterface
INSERT(columns ...column) insertStatement INSERT(columns ...column) InsertStatement
UPDATE(columns ...column) updateStatement UPDATE(columns ...column) UpdateStatement
DELETE() deleteStatement DELETE() DeleteStatement
LOCK() lockStatement LOCK() LockStatement
} }
// Defines a physical tableName in the database that is both readable and writable. // Defines a physical tableName in the database that is both readable and writable.
@ -105,7 +105,7 @@ func (t *Table) Columns() []column {
return t.columns return t.columns
} }
// Generates the sql string for the current tableName expression. Note: the // Generates the sql string for the current tableName Expression. Note: the
// generated string may not be a valid/executable sql Statement. // generated string may not be a valid/executable sql Statement.
func (t *Table) serialize(statement statementType, out *queryData, options ...serializeOption) error { func (t *Table) serialize(statement statementType, out *queryData, options ...serializeOption) error {
if t == nil { if t == nil {
@ -125,55 +125,55 @@ func (t *Table) serialize(statement statementType, out *queryData, options ...se
} }
// Generates a select query on the current tableName. // Generates a select query on the current tableName.
func (t *Table) SELECT(projections ...projection) selectStatement { func (t *Table) SELECT(projections ...projection) SelectStatement {
return newSelectStatement(t, projections) return newSelectStatement(t, projections)
} }
// Creates a inner join tableName expression using onCondition. // Creates a inner join tableName Expression using onCondition.
func (t *Table) INNER_JOIN( func (t *Table) INNER_JOIN(
table readableTable, table ReadableTable,
onCondition BoolExpression) readableTable { onCondition BoolExpression) ReadableTable {
return InnerJoinOn(t, table, onCondition) return InnerJoinOn(t, table, onCondition)
} }
// Creates a left join tableName expression using onCondition. // Creates a left join tableName Expression using onCondition.
func (t *Table) LEFT_JOIN( func (t *Table) LEFT_JOIN(
table readableTable, table ReadableTable,
onCondition BoolExpression) readableTable { onCondition BoolExpression) ReadableTable {
return LeftJoinOn(t, table, onCondition) return LeftJoinOn(t, table, onCondition)
} }
// Creates a right join tableName expression using onCondition. // Creates a right join tableName Expression using onCondition.
func (t *Table) RIGHT_JOIN( func (t *Table) RIGHT_JOIN(
table readableTable, table ReadableTable,
onCondition BoolExpression) readableTable { onCondition BoolExpression) ReadableTable {
return RightJoinOn(t, table, onCondition) return RightJoinOn(t, table, onCondition)
} }
func (t *Table) FULL_JOIN(table readableTable, onCondition BoolExpression) readableTable { func (t *Table) FULL_JOIN(table ReadableTable, onCondition BoolExpression) ReadableTable {
return FullJoin(t, table, onCondition) return FullJoin(t, table, onCondition)
} }
func (t *Table) CROSS_JOIN(table readableTable) readableTable { func (t *Table) CROSS_JOIN(table ReadableTable) ReadableTable {
return CrossJoin(t, table) return CrossJoin(t, table)
} }
func (t *Table) INSERT(columns ...column) insertStatement { func (t *Table) INSERT(columns ...column) InsertStatement {
return newInsertStatement(t, columns...) return newInsertStatement(t, columns...)
} }
func (t *Table) UPDATE(columns ...column) updateStatement { func (t *Table) UPDATE(columns ...column) UpdateStatement {
return newUpdateStatement(t, columns) return newUpdateStatement(t, columns)
} }
func (t *Table) DELETE() deleteStatement { func (t *Table) DELETE() DeleteStatement {
return newDeleteStatement(t) return newDeleteStatement(t)
} }
func (t *Table) LOCK() lockStatement { func (t *Table) LOCK() LockStatement {
return LOCK(t) return LOCK(t)
} }
@ -189,17 +189,17 @@ const (
// Join expressions are pseudo readable tables. // Join expressions are pseudo readable tables.
type joinTable struct { type joinTable struct {
lhs readableTable lhs ReadableTable
rhs readableTable rhs ReadableTable
join_type joinType join_type joinType
onCondition BoolExpression onCondition BoolExpression
} }
func newJoinTable( func newJoinTable(
lhs readableTable, lhs ReadableTable,
rhs readableTable, rhs ReadableTable,
join_type joinType, join_type joinType,
onCondition BoolExpression) readableTable { onCondition BoolExpression) ReadableTable {
return &joinTable{ return &joinTable{
lhs: lhs, lhs: lhs,
@ -210,40 +210,40 @@ func newJoinTable(
} }
func InnerJoinOn( func InnerJoinOn(
lhs readableTable, lhs ReadableTable,
rhs readableTable, rhs ReadableTable,
onCondition BoolExpression) readableTable { onCondition BoolExpression) ReadableTable {
return newJoinTable(lhs, rhs, INNER_JOIN, onCondition) return newJoinTable(lhs, rhs, INNER_JOIN, onCondition)
} }
func LeftJoinOn( func LeftJoinOn(
lhs readableTable, lhs ReadableTable,
rhs readableTable, rhs ReadableTable,
onCondition BoolExpression) readableTable { onCondition BoolExpression) ReadableTable {
return newJoinTable(lhs, rhs, LEFT_JOIN, onCondition) return newJoinTable(lhs, rhs, LEFT_JOIN, onCondition)
} }
func RightJoinOn( func RightJoinOn(
lhs readableTable, lhs ReadableTable,
rhs readableTable, rhs ReadableTable,
onCondition BoolExpression) readableTable { onCondition BoolExpression) ReadableTable {
return newJoinTable(lhs, rhs, RIGHT_JOIN, onCondition) return newJoinTable(lhs, rhs, RIGHT_JOIN, onCondition)
} }
func FullJoin( func FullJoin(
lhs readableTable, lhs ReadableTable,
rhs readableTable, rhs ReadableTable,
onCondition BoolExpression) readableTable { onCondition BoolExpression) ReadableTable {
return newJoinTable(lhs, rhs, FULL_JOIN, onCondition) return newJoinTable(lhs, rhs, FULL_JOIN, onCondition)
} }
func CrossJoin( func CrossJoin(
lhs readableTable, lhs ReadableTable,
rhs readableTable) readableTable { rhs ReadableTable) ReadableTable {
return newJoinTable(lhs, rhs, CROSS_JOIN, nil) return newJoinTable(lhs, rhs, CROSS_JOIN, nil)
} }
@ -318,35 +318,35 @@ func (t *joinTable) serialize(statement statementType, out *queryData, options .
return nil return nil
} }
func (t *joinTable) SELECT(projections ...projection) selectStatement { func (t *joinTable) SELECT(projections ...projection) SelectStatement {
return newSelectStatement(t, projections) return newSelectStatement(t, projections)
} }
func (t *joinTable) INNER_JOIN( func (t *joinTable) INNER_JOIN(
table readableTable, table ReadableTable,
onCondition BoolExpression) readableTable { onCondition BoolExpression) ReadableTable {
return InnerJoinOn(t, table, onCondition) return InnerJoinOn(t, table, onCondition)
} }
func (t *joinTable) LEFT_JOIN( func (t *joinTable) LEFT_JOIN(
table readableTable, table ReadableTable,
onCondition BoolExpression) readableTable { onCondition BoolExpression) ReadableTable {
return LeftJoinOn(t, table, onCondition) return LeftJoinOn(t, table, onCondition)
} }
func (t *joinTable) FULL_JOIN(table readableTable, onCondition BoolExpression) readableTable { func (t *joinTable) FULL_JOIN(table ReadableTable, onCondition BoolExpression) ReadableTable {
return FullJoin(t, table, onCondition) return FullJoin(t, table, onCondition)
} }
func (t *joinTable) CROSS_JOIN(table readableTable) readableTable { func (t *joinTable) CROSS_JOIN(table ReadableTable) ReadableTable {
return CrossJoin(t, table) return CrossJoin(t, table)
} }
func (t *joinTable) RIGHT_JOIN( func (t *joinTable) RIGHT_JOIN(
table readableTable, table ReadableTable,
onCondition BoolExpression) readableTable { onCondition BoolExpression) ReadableTable {
return RightJoinOn(t, table, onCondition) return RightJoinOn(t, table, onCondition)
} }

View file

@ -49,7 +49,7 @@ var table3 = NewTable(
table3Col1, table3Col1,
table3StrCol) table3StrCol)
func assertExpressionSerialize(t *testing.T, expression expression, query string, args ...interface{}) { func assertExpressionSerialize(t *testing.T, expression Expression, query string, args ...interface{}) {
out := queryData{} out := queryData{}
err := expression.serialize(select_statement, &out) err := expression.serialize(select_statement, &out)

View file

@ -1,7 +1,7 @@
package sqlbuilder package sqlbuilder
type TimeExpression interface { type TimeExpression interface {
expression Expression
EQ(rhs TimeExpression) BoolExpression EQ(rhs TimeExpression) BoolExpression
NOT_EQ(rhs TimeExpression) BoolExpression NOT_EQ(rhs TimeExpression) BoolExpression
@ -58,7 +58,7 @@ type prefixTimeExpression struct {
prefixOpExpression prefixOpExpression
} }
func newPrefixTimeExpression(operator string, expression expression) TimeExpression { func newPrefixTimeExpression(operator string, expression Expression) TimeExpression {
timeExpr := prefixTimeExpression{} timeExpr := prefixTimeExpression{}
timeExpr.prefixOpExpression = newPrefixExpression(expression, operator) timeExpr.prefixOpExpression = newPrefixExpression(expression, operator)
@ -68,6 +68,6 @@ func newPrefixTimeExpression(operator string, expression expression) TimeExpress
return &timeExpr return &timeExpr
} }
func INTERVAL(interval string) expression { func INTERVAL(interval string) Expression {
return newPrefixTimeExpression("INTERVAL", literal(interval)) return newPrefixTimeExpression("INTERVAL", literal(interval))
} }

View file

@ -1,7 +1,7 @@
package sqlbuilder package sqlbuilder
type TimestampExpression interface { type TimestampExpression interface {
expression Expression
EQ(rhs TimestampExpression) BoolExpression EQ(rhs TimestampExpression) BoolExpression
NOT_EQ(rhs TimestampExpression) BoolExpression NOT_EQ(rhs TimestampExpression) BoolExpression

View file

@ -1,7 +1,7 @@
package sqlbuilder package sqlbuilder
type TimestampzExpression interface { type TimestampzExpression interface {
expression Expression
EQ(rhs TimestampzExpression) BoolExpression EQ(rhs TimestampzExpression) BoolExpression
NOT_EQ(rhs TimestampzExpression) BoolExpression NOT_EQ(rhs TimestampzExpression) BoolExpression

View file

@ -1,7 +1,7 @@
package sqlbuilder package sqlbuilder
type TimezExpression interface { type TimezExpression interface {
expression Expression
EQ(rhs TimezExpression) BoolExpression EQ(rhs TimezExpression) BoolExpression
NOT_EQ(rhs TimezExpression) BoolExpression NOT_EQ(rhs TimezExpression) BoolExpression
@ -58,7 +58,7 @@ type prefixTimezExpression struct {
prefixOpExpression prefixOpExpression
} }
func newPrefixTimezExpression(operator string, expression expression) TimezExpression { func newPrefixTimezExpression(operator string, expression Expression) TimezExpression {
timeExpr := prefixTimezExpression{} timeExpr := prefixTimezExpression{}
timeExpr.prefixOpExpression = newPrefixExpression(expression, operator) timeExpr.prefixOpExpression = newPrefixExpression(expression, operator)

View file

@ -6,15 +6,15 @@ import (
"github.com/sub0zero/go-sqlbuilder/sqlbuilder/execution" "github.com/sub0zero/go-sqlbuilder/sqlbuilder/execution"
) )
type updateStatement interface { type UpdateStatement interface {
Statement Statement
SET(values ...interface{}) updateStatement SET(values ...interface{}) UpdateStatement
WHERE(expression BoolExpression) updateStatement WHERE(expression BoolExpression) UpdateStatement
RETURNING(projections ...projection) updateStatement RETURNING(projections ...projection) UpdateStatement
} }
func newUpdateStatement(table writableTable, columns []column) updateStatement { func newUpdateStatement(table writableTable, columns []column) UpdateStatement {
return &updateStatementImpl{ return &updateStatementImpl{
table: table, table: table,
columns: columns, columns: columns,
@ -29,7 +29,7 @@ type updateStatementImpl struct {
returning []projection returning []projection
} }
func (u *updateStatementImpl) SET(values ...interface{}) updateStatement { func (u *updateStatementImpl) SET(values ...interface{}) UpdateStatement {
for _, value := range values { for _, value := range values {
if clause, ok := value.(clause); ok { if clause, ok := value.(clause); ok {
@ -42,12 +42,12 @@ func (u *updateStatementImpl) SET(values ...interface{}) updateStatement {
return u return u
} }
func (u *updateStatementImpl) WHERE(expression BoolExpression) updateStatement { func (u *updateStatementImpl) WHERE(expression BoolExpression) UpdateStatement {
u.where = expression u.where = expression
return u return u
} }
func (u *updateStatementImpl) RETURNING(projections ...projection) updateStatement { func (u *updateStatementImpl) RETURNING(projections ...projection) UpdateStatement {
u.returning = defaultProjectionAliasing(projections) u.returning = defaultProjectionAliasing(projections)
return u return u
} }

View file

@ -6,7 +6,7 @@ import (
"github.com/sub0zero/go-sqlbuilder/sqlbuilder/execution" "github.com/sub0zero/go-sqlbuilder/sqlbuilder/execution"
) )
func serializeOrderByClauseList(statement statementType, orderByClauses []orderByClause, out *queryData) error { func serializeOrderByClauseList(statement statementType, orderByClauses []OrderByClause, out *queryData) error {
for i, value := range orderByClauses { for i, value := range orderByClauses {
if i > 0 { if i > 0 {
@ -61,7 +61,7 @@ func serializeClauseList(statement statementType, clauses []clause, out *queryDa
return nil return nil
} }
func serializeExpressionList(statement statementType, expressions []expression, separator string, out *queryData) error { func serializeExpressionList(statement statementType, expressions []Expression, separator string, out *queryData) error {
for i, value := range expressions { for i, value := range expressions {
if i > 0 { if i > 0 {
@ -86,7 +86,7 @@ func serializeProjectionList(statement statementType, projections []projection,
} }
if col == nil { if col == nil {
return errors.New("projection expression is nil.") return errors.New("projection Expression is nil.")
} }
if err := col.serializeForProjection(statement, out); err != nil { if err := col.serializeForProjection(statement, out); err != nil {
@ -113,8 +113,8 @@ func serializeColumnList(statement statementType, columns []column, out *queryDa
return nil return nil
} }
//func stringExpressionListToExpressionList(stringExpressions []StringExpression) []expression{ //func stringExpressionListToExpressionList(stringExpressions []StringExpression) []Expression{
// var ret []expression // var ret []Expression
// //
// for _, strExp := range stringExpressions { // for _, strExp := range stringExpressions {
// ret = append(ret, strExp) // ret = append(ret, strExp)

View file

@ -57,6 +57,8 @@ func TestExpressionOperators(t *testing.T) {
NULLIF(AllTypes.Text, String("(none)")), NULLIF(AllTypes.Text, String("(none)")),
GREATEST(AllTypes.Numeric, AllTypes.NumericPtr), GREATEST(AllTypes.Numeric, AllTypes.NumericPtr),
LEAST(AllTypes.Numeric, AllTypes.NumericPtr), LEAST(AllTypes.Numeric, AllTypes.NumericPtr),
RAW("current_database()"),
) )
fmt.Println(query.DebugSql()) fmt.Println(query.DebugSql())