233 lines
5.5 KiB
Go
233 lines
5.5 KiB
Go
package sqlbuilder
|
|
|
|
import (
|
|
"errors"
|
|
)
|
|
|
|
// An Expression
|
|
type Expression interface {
|
|
clause
|
|
projection
|
|
groupByClause
|
|
OrderByClause
|
|
|
|
IS_NULL() BoolExpression
|
|
IS_NOT_NULL() BoolExpression
|
|
|
|
IN(expressions ...Expression) BoolExpression
|
|
NOT_IN(expressions ...Expression) BoolExpression
|
|
|
|
AS(alias string) projection
|
|
|
|
ASC() OrderByClause
|
|
DESC() OrderByClause
|
|
|
|
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
|
|
}
|
|
|
|
type expressionInterfaceImpl struct {
|
|
parent Expression
|
|
}
|
|
|
|
func (e *expressionInterfaceImpl) IS_NULL() BoolExpression {
|
|
return newPostifxBoolExpression(e.parent, "IS NULL")
|
|
}
|
|
|
|
func (e *expressionInterfaceImpl) IS_NOT_NULL() BoolExpression {
|
|
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")
|
|
}
|
|
|
|
func (e *expressionInterfaceImpl) AS(alias string) projection {
|
|
return NewAlias(e.parent, alias)
|
|
}
|
|
|
|
func (e *expressionInterfaceImpl) ASC() OrderByClause {
|
|
return &orderByClauseImpl{expression: e.parent, ascent: true}
|
|
}
|
|
|
|
func (e *expressionInterfaceImpl) DESC() OrderByClause {
|
|
return &orderByClauseImpl{expression: e.parent, ascent: false}
|
|
}
|
|
|
|
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)
|
|
}
|
|
|
|
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)
|
|
}
|
|
|
|
// Representation of binary operations (e.g. comparisons, arithmetic)
|
|
type binaryOpExpression struct {
|
|
lhs, rhs Expression
|
|
operator string
|
|
}
|
|
|
|
func newBinaryExpression(lhs, rhs Expression, operator string) binaryOpExpression {
|
|
binaryExpression := binaryOpExpression{
|
|
lhs: lhs,
|
|
rhs: rhs,
|
|
operator: operator,
|
|
}
|
|
|
|
return binaryExpression
|
|
}
|
|
|
|
func (c *binaryOpExpression) serialize(statement statementType, out *queryData, options ...serializeOption) error {
|
|
if c == nil {
|
|
return errors.New("Binary Expression is nil.")
|
|
}
|
|
if c.lhs == nil {
|
|
return errors.New("nil lhs.")
|
|
}
|
|
if c.rhs == nil {
|
|
return errors.New("nil rhs.")
|
|
}
|
|
|
|
wrap := !contains(options, NO_WRAP)
|
|
|
|
if wrap {
|
|
out.writeString("(")
|
|
}
|
|
|
|
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
|
|
}
|
|
|
|
if wrap {
|
|
out.writeString(")")
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// A prefix operator Expression
|
|
type prefixOpExpression struct {
|
|
expression Expression
|
|
operator string
|
|
}
|
|
|
|
func newPrefixExpression(expression Expression, operator string) prefixOpExpression {
|
|
prefixExpression := prefixOpExpression{
|
|
expression: expression,
|
|
operator: operator,
|
|
}
|
|
|
|
return prefixExpression
|
|
}
|
|
|
|
func (p *prefixOpExpression) serialize(statement statementType, out *queryData, options ...serializeOption) error {
|
|
if p == nil {
|
|
return errors.New("Prefix Expression is nil.")
|
|
}
|
|
|
|
out.writeString(p.operator + " ")
|
|
|
|
if p.expression == nil {
|
|
return errors.New("nil prefix Expression.")
|
|
}
|
|
if err := p.expression.serialize(statement, out); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// 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 {
|
|
if p == nil {
|
|
return errors.New("Postifx operator Expression is nil.")
|
|
}
|
|
|
|
if p.expression == nil {
|
|
return errors.New("nil prefix Expression.")
|
|
}
|
|
if err := p.expression.serialize(statement, out); err != nil {
|
|
return err
|
|
}
|
|
|
|
out.writeString(p.operator)
|
|
|
|
return nil
|
|
}
|