jet/sqlbuilder/expression.go

234 lines
5.5 KiB
Go
Raw Normal View History

package sqlbuilder
import (
"github.com/dropbox/godropbox/errors"
)
2019-03-31 09:17:28 +02:00
// An expression
2019-05-07 19:06:21 +02:00
type expression interface {
clause
projection
groupByClause
2019-05-08 12:49:36 +02:00
orderByClause
IS_NULL() BoolExpression
IS_NOT_NULL() BoolExpression
2019-05-29 14:03:38 +02:00
IN(expressions ...expression) BoolExpression
NOT_IN(expressions ...expression) BoolExpression
2019-05-07 19:06:21 +02:00
AS(alias string) projection
2019-05-29 14:03:38 +02:00
2019-05-07 19:06:21 +02:00
ASC() orderByClause
DESC() orderByClause
2019-06-03 17:05:29 +02:00
CAST_TO(dbType string) expression
CAST_TO_BOOL() BoolExpression
CAST_TO_INTEGER() IntegerExpression
CAST_TO_DOUBLE() FloatExpression
CAST_TO_TEXT() StringExpression
CAST_TO_DATE() DateExpression
CAST_TO_TIME() TimeExpression
CAST_TO_TIMEZ() TimezExpression
CAST_TO_TIMESTAMP() TimestampExpression
CAST_TO_TIMESTAMPZ() TimestampzExpression
}
2019-03-31 09:17:28 +02:00
type expressionInterfaceImpl struct {
2019-05-07 19:06:21 +02:00
parent expression
}
func (e *expressionInterfaceImpl) IS_NULL() BoolExpression {
2019-05-29 14:03:38 +02:00
return newPostifxBoolExpression(e.parent, "IS NULL")
}
func (e *expressionInterfaceImpl) IS_NOT_NULL() BoolExpression {
2019-05-29 14:03:38 +02:00
return newPostifxBoolExpression(e.parent, "IS NOT NULL")
}
func (e *expressionInterfaceImpl) IN(expressions ...expression) BoolExpression {
return newBinaryBoolExpression(e.parent, WRAP(expressions...), "IN")
}
func (e *expressionInterfaceImpl) NOT_IN(expressions ...expression) BoolExpression {
return newBinaryBoolExpression(e.parent, WRAP(expressions...), "NOT IN")
}
2019-05-07 19:06:21 +02:00
func (e *expressionInterfaceImpl) AS(alias string) projection {
2019-03-31 09:17:28 +02:00
return NewAlias(e.parent, alias)
}
2019-05-07 19:06:21 +02:00
func (e *expressionInterfaceImpl) ASC() orderByClause {
return &orderByClauseImpl{expression: e.parent, ascent: true}
}
2019-05-07 19:06:21 +02:00
func (e *expressionInterfaceImpl) DESC() orderByClause {
return &orderByClauseImpl{expression: e.parent, ascent: false}
}
2019-06-03 17:05:29 +02:00
func (e *expressionInterfaceImpl) CAST_TO(dbType string) expression {
return newCast(e.parent, dbType)
}
func (e *expressionInterfaceImpl) CAST_TO_BOOL() BoolExpression {
return newBoolCast(e.parent)
}
func (e *expressionInterfaceImpl) CAST_TO_INTEGER() IntegerExpression {
return newIntegerCast(e.parent)
}
func (e *expressionInterfaceImpl) CAST_TO_DOUBLE() FloatExpression {
return newDoubleCast(e.parent)
}
func (e *expressionInterfaceImpl) CAST_TO_TEXT() StringExpression {
return newTextCast(e.parent)
}
func (e *expressionInterfaceImpl) CAST_TO_DATE() DateExpression {
return newDateCast(e.parent)
}
func (e *expressionInterfaceImpl) CAST_TO_TIME() TimeExpression {
return newTimeCast(e.parent)
}
func (e *expressionInterfaceImpl) CAST_TO_TIMEZ() TimezExpression {
return newTimezCast(e.parent)
}
func (e *expressionInterfaceImpl) CAST_TO_TIMESTAMP() TimestampExpression {
return newTimestampCast(e.parent)
}
func (e *expressionInterfaceImpl) CAST_TO_TIMESTAMPZ() TimestampzExpression {
return newTimestampzCast(e.parent)
}
func (e *expressionInterfaceImpl) serializeForGroupBy(statement statementType, out *queryData) error {
return e.parent.serialize(statement, out, NO_WRAP)
2019-05-07 19:06:21 +02:00
}
func (e *expressionInterfaceImpl) serializeForProjection(statement statementType, out *queryData) error {
return e.parent.serialize(statement, out, NO_WRAP)
}
func (e *expressionInterfaceImpl) serializeAsOrderBy(statement statementType, out *queryData) error {
return e.parent.serialize(statement, out, NO_WRAP)
2019-05-08 12:49:36 +02:00
}
2019-03-31 09:17:28 +02:00
// Representation of binary operations (e.g. comparisons, arithmetic)
2019-05-29 14:03:38 +02:00
type binaryOpExpression struct {
2019-05-07 19:06:21 +02:00
lhs, rhs expression
operator string
}
2019-05-29 14:03:38 +02:00
func newBinaryExpression(lhs, rhs expression, operator string, parent ...expression) binaryOpExpression {
binaryExpression := binaryOpExpression{
2019-03-31 09:17:28 +02:00
lhs: lhs,
rhs: rhs,
operator: operator,
}
2019-03-31 14:07:58 +02:00
return binaryExpression
}
func (c *binaryOpExpression) serialize(statement statementType, out *queryData, options ...serializeOption) error {
2019-05-13 12:33:11 +02:00
if c == nil {
return errors.New("Binary expression is nil.")
}
if c.lhs == nil {
return errors.Newf("nil lhs.")
}
2019-05-01 17:25:10 +02:00
if c.rhs == nil {
return errors.Newf("nil rhs.")
}
wrap := !contains(options, NO_WRAP)
2019-05-01 17:25:10 +02:00
2019-05-01 18:23:19 +02:00
if wrap {
out.writeString("(")
2019-05-01 17:25:10 +02:00
}
if err := c.lhs.serialize(statement, out); err != nil {
return err
}
out.writeString(" " + c.operator + " ")
if err := c.rhs.serialize(statement, out); err != nil {
return err
}
2019-05-01 18:23:19 +02:00
if wrap {
out.writeString(")")
2019-05-01 17:25:10 +02:00
}
return nil
}
2019-05-29 14:03:38 +02:00
// A prefix operator expression
type prefixOpExpression struct {
2019-05-07 19:06:21 +02:00
expression expression
operator string
}
2019-05-29 14:03:38 +02:00
func newPrefixExpression(expression expression, operator string) prefixOpExpression {
prefixExpression := prefixOpExpression{
2019-03-31 09:17:28 +02:00
expression: expression,
operator: operator,
}
2019-03-31 14:07:58 +02:00
return prefixExpression
}
func (p *prefixOpExpression) serialize(statement statementType, out *queryData, options ...serializeOption) error {
2019-05-13 12:33:11 +02:00
if p == nil {
return errors.New("Prefix expression is nil.")
}
out.writeString(p.operator + " ")
2019-03-31 09:17:28 +02:00
if p.expression == nil {
return errors.Newf("nil prefix expression.")
}
if err := p.expression.serialize(statement, out); err != nil {
return err
}
2019-03-31 09:17:28 +02:00
return nil
}
2019-05-29 14:03:38 +02:00
// A postifx operator expression
type postfixOpExpression struct {
expression expression
operator string
}
func newPostfixOpExpression(expression expression, operator string) postfixOpExpression {
postfixOpExpression := postfixOpExpression{
expression: expression,
operator: operator,
}
return postfixOpExpression
}
func (p *postfixOpExpression) serialize(statement statementType, out *queryData, options ...serializeOption) error {
2019-05-29 14:03:38 +02:00
if p == nil {
return errors.New("Postifx operator expression is nil.")
}
if p.expression == nil {
return errors.Newf("nil prefix expression.")
}
if err := p.expression.serialize(statement, out); err != nil {
return err
}
out.writeString(p.operator)
return nil
}