jet/expression.go

194 lines
4.6 KiB
Go
Raw Normal View History

2019-06-21 13:56:57 +02:00
package jet
import (
2019-06-05 17:15:20 +02:00
"errors"
)
2019-06-27 19:55:21 +02:00
// Common expression interface
2019-06-04 12:10:23 +02:00
type Expression interface {
2019-05-07 19:06:21 +02:00
clause
projection
groupByClause
2019-06-04 12:10:23 +02:00
OrderByClause
2019-06-27 19:55:21 +02:00
// Test expression whether it is a NULL value.
IS_NULL() BoolExpression
2019-06-27 19:55:21 +02:00
// Test expression whether it is a non-NULL value.
IS_NOT_NULL() BoolExpression
2019-05-29 14:03:38 +02:00
2019-06-27 19:55:21 +02:00
// Check if this expressions matches any in expressions list
2019-06-04 12:10:23 +02:00
IN(expressions ...Expression) BoolExpression
2019-06-27 19:55:21 +02:00
// Check if this expressions is different of all expressions in expressions list
2019-06-04 12:10:23 +02:00
NOT_IN(expressions ...Expression) BoolExpression
2019-06-27 19:55:21 +02:00
// The temporary alias name to assign to the expression
2019-05-07 19:06:21 +02:00
AS(alias string) projection
2019-05-29 14:03:38 +02:00
2019-06-27 19:55:21 +02:00
// Expression will be used to sort query result in ascending order
2019-06-04 12:10:23 +02:00
ASC() OrderByClause
2019-06-27 19:55:21 +02:00
// Expression will be used to sort query result in ascending order
2019-06-04 12:10:23 +02:00
DESC() OrderByClause
}
2019-03-31 09:17:28 +02:00
type expressionInterfaceImpl struct {
2019-06-04 12:10:23 +02:00
parent Expression
}
func (e *expressionInterfaceImpl) from(subQuery ExpressionTable) projection {
return e.parent
}
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")
}
2019-06-04 12:10:23 +02:00
func (e *expressionInterfaceImpl) IN(expressions ...Expression) BoolExpression {
return newBinaryBoolExpression(e.parent, WRAP(expressions...), "IN")
}
2019-06-04 12:10:23 +02:00
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 {
return newAlias(e.parent, alias)
}
2019-06-04 12:10:23 +02:00
func (e *expressionInterfaceImpl) ASC() OrderByClause {
2019-06-21 13:56:57 +02:00
return newOrderByClause(e.parent, true)
}
2019-06-04 12:10:23 +02:00
func (e *expressionInterfaceImpl) DESC() OrderByClause {
2019-06-21 13:56:57 +02:00
return newOrderByClause(e.parent, false)
}
func (e *expressionInterfaceImpl) serializeForGroupBy(statement statementType, out *queryData) error {
2019-06-27 19:55:21 +02:00
return e.parent.serialize(statement, out, noWrap)
2019-05-07 19:06:21 +02:00
}
func (e *expressionInterfaceImpl) serializeForProjection(statement statementType, out *queryData) error {
2019-06-27 19:55:21 +02:00
return e.parent.serialize(statement, out, noWrap)
}
2019-06-11 12:47:35 +02:00
func (e *expressionInterfaceImpl) serializeForOrderBy(statement statementType, out *queryData) error {
2019-06-27 19:55:21 +02:00
return e.parent.serialize(statement, out, noWrap)
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-06-04 12:10:23 +02:00
lhs, rhs Expression
operator string
}
2019-06-04 12:10:23 +02:00
func newBinaryExpression(lhs, rhs Expression, operator string) binaryOpExpression {
2019-05-29 14:03:38 +02:00
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")
2019-05-13 12:33:11 +02:00
}
if c.lhs == nil {
return errors.New("nil lhs")
}
2019-05-01 17:25:10 +02:00
if c.rhs == nil {
return errors.New("nil rhs")
2019-05-01 17:25:10 +02:00
}
2019-06-27 19:55:21 +02:00
wrap := !contains(options, noWrap)
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
}
2019-06-17 12:05:52 +02:00
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-06-04 12:10:23 +02:00
// A prefix operator Expression
2019-05-29 14:03:38 +02:00
type prefixOpExpression struct {
2019-06-04 12:10:23 +02:00
expression Expression
operator string
}
2019-06-04 12:10:23 +02:00
func newPrefixExpression(expression Expression, operator string) prefixOpExpression {
2019-05-29 14:03:38 +02:00
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 {
2019-06-04 12:10:23 +02:00
return errors.New("Prefix Expression is nil.")
2019-05-13 12:33:11 +02:00
}
out.writeString(p.operator + " ")
2019-03-31 09:17:28 +02:00
if p.expression == nil {
2019-06-05 17:15:20 +02:00
return errors.New("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
2019-06-04 12:10:23 +02:00
// A postifx operator Expression
2019-05-29 14:03:38 +02:00
type postfixOpExpression struct {
2019-06-04 12:10:23 +02:00
expression Expression
2019-05-29 14:03:38 +02:00
operator string
}
2019-06-04 12:10:23 +02:00
func newPostfixOpExpression(expression Expression, operator string) postfixOpExpression {
2019-05-29 14:03:38 +02:00
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 {
2019-06-04 12:10:23 +02:00
return errors.New("Postifx operator Expression is nil.")
2019-05-29 14:03:38 +02:00
}
if p.expression == nil {
2019-06-05 17:15:20 +02:00
return errors.New("nil prefix Expression.")
2019-05-29 14:03:38 +02:00
}
if err := p.expression.serialize(statement, out); err != nil {
return err
}
out.writeString(p.operator)
return nil
}