2019-03-02 12:34:08 +01:00
|
|
|
package sqlbuilder
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"github.com/dropbox/godropbox/errors"
|
|
|
|
|
)
|
|
|
|
|
|
2019-03-31 09:17:28 +02:00
|
|
|
// An expression
|
|
|
|
|
type Expression interface {
|
|
|
|
|
Clause
|
2019-04-03 11:03:07 +02:00
|
|
|
Projection
|
2019-03-02 12:34:08 +01:00
|
|
|
|
2019-04-03 11:03:07 +02:00
|
|
|
As(alias string) Projection
|
2019-03-31 09:17:28 +02:00
|
|
|
IsDistinct(expression Expression) BoolExpression
|
2019-03-31 14:07:58 +02:00
|
|
|
IsNull() BoolExpression
|
2019-04-03 11:03:07 +02:00
|
|
|
Asc() OrderByClause
|
|
|
|
|
Desc() OrderByClause
|
2019-03-02 12:34:08 +01:00
|
|
|
}
|
|
|
|
|
|
2019-03-31 09:17:28 +02:00
|
|
|
type expressionInterfaceImpl struct {
|
|
|
|
|
parent Expression
|
2019-03-02 12:34:08 +01:00
|
|
|
}
|
|
|
|
|
|
2019-04-03 11:03:07 +02:00
|
|
|
func (e *expressionInterfaceImpl) As(alias string) Projection {
|
2019-03-31 09:17:28 +02:00
|
|
|
return NewAlias(e.parent, alias)
|
2019-03-02 12:34:08 +01:00
|
|
|
}
|
|
|
|
|
|
2019-03-31 09:17:28 +02:00
|
|
|
func (e *expressionInterfaceImpl) IsDistinct(expression Expression) BoolExpression {
|
2019-03-02 12:34:08 +01:00
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-31 14:07:58 +02:00
|
|
|
func (e *expressionInterfaceImpl) IsNull() BoolExpression {
|
2019-03-02 12:34:08 +01:00
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2019-04-03 11:03:07 +02:00
|
|
|
func (e *expressionInterfaceImpl) Asc() OrderByClause {
|
|
|
|
|
return &orderByClause{expression: e.parent, ascent: true}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (e *expressionInterfaceImpl) Desc() OrderByClause {
|
|
|
|
|
return &orderByClause{expression: e.parent, ascent: false}
|
|
|
|
|
}
|
|
|
|
|
|
2019-04-29 14:39:48 +02:00
|
|
|
func (e *expressionInterfaceImpl) SerializeForProjection(out *queryData) error {
|
|
|
|
|
return e.parent.Serialize(out, FOR_PROJECTION)
|
2019-04-03 11:03:07 +02:00
|
|
|
}
|
|
|
|
|
|
2019-03-31 09:17:28 +02:00
|
|
|
// Representation of binary operations (e.g. comparisons, arithmetic)
|
|
|
|
|
type binaryExpression struct {
|
|
|
|
|
lhs, rhs Expression
|
|
|
|
|
operator []byte
|
2019-03-02 12:34:08 +01:00
|
|
|
}
|
|
|
|
|
|
2019-03-31 14:07:58 +02:00
|
|
|
func newBinaryExpression(lhs, rhs Expression, operator []byte, parent ...Expression) binaryExpression {
|
2019-03-31 09:17:28 +02:00
|
|
|
binaryExpression := binaryExpression{
|
|
|
|
|
lhs: lhs,
|
|
|
|
|
rhs: rhs,
|
|
|
|
|
operator: operator,
|
2019-03-02 12:34:08 +01:00
|
|
|
}
|
|
|
|
|
|
2019-03-31 14:07:58 +02:00
|
|
|
return binaryExpression
|
2019-03-02 12:34:08 +01:00
|
|
|
}
|
|
|
|
|
|
2019-04-29 14:39:48 +02:00
|
|
|
func (c *binaryExpression) Serialize(out *queryData, options ...serializeOption) error {
|
2019-03-02 12:34:08 +01:00
|
|
|
if c.lhs == nil {
|
2019-04-29 14:39:48 +02:00
|
|
|
return errors.Newf("nil lhs.")
|
2019-03-02 12:34:08 +01:00
|
|
|
}
|
2019-04-29 14:39:48 +02:00
|
|
|
if err := c.lhs.Serialize(out); err != nil {
|
|
|
|
|
return err
|
2019-03-02 12:34:08 +01:00
|
|
|
}
|
|
|
|
|
|
2019-04-29 14:39:48 +02:00
|
|
|
out.Write(c.operator)
|
2019-03-02 12:34:08 +01:00
|
|
|
|
|
|
|
|
if c.rhs == nil {
|
2019-04-29 14:39:48 +02:00
|
|
|
return errors.Newf("nil rhs.")
|
2019-03-02 12:34:08 +01:00
|
|
|
}
|
2019-04-29 14:39:48 +02:00
|
|
|
if err := c.rhs.Serialize(out); err != nil {
|
|
|
|
|
return err
|
2019-03-02 12:34:08 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-31 09:17:28 +02:00
|
|
|
// A not expression which negates a expression value
|
|
|
|
|
type prefixExpression struct {
|
|
|
|
|
expression Expression
|
|
|
|
|
operator []byte
|
2019-03-02 12:34:08 +01:00
|
|
|
}
|
|
|
|
|
|
2019-03-31 14:07:58 +02:00
|
|
|
func newPrefixExpression(expression Expression, operator []byte) prefixExpression {
|
2019-03-31 09:17:28 +02:00
|
|
|
prefixExpression := prefixExpression{
|
|
|
|
|
expression: expression,
|
|
|
|
|
operator: operator,
|
2019-03-02 12:34:08 +01:00
|
|
|
}
|
|
|
|
|
|
2019-03-31 14:07:58 +02:00
|
|
|
return prefixExpression
|
2019-03-02 12:34:08 +01:00
|
|
|
}
|
|
|
|
|
|
2019-04-29 14:39:48 +02:00
|
|
|
func (p *prefixExpression) Serialize(out *queryData, options ...serializeOption) error {
|
|
|
|
|
out.Write(p.operator)
|
2019-03-02 12:34:08 +01:00
|
|
|
|
2019-03-31 09:17:28 +02:00
|
|
|
if p.expression == nil {
|
2019-04-29 14:39:48 +02:00
|
|
|
return errors.Newf("nil prefix expression.")
|
2019-03-02 12:34:08 +01:00
|
|
|
}
|
2019-04-29 14:39:48 +02:00
|
|
|
if err := p.expression.Serialize(out); err != nil {
|
|
|
|
|
return err
|
2019-03-02 12:34:08 +01:00
|
|
|
}
|
|
|
|
|
|
2019-03-31 09:17:28 +02:00
|
|
|
return nil
|
2019-03-02 12:34:08 +01:00
|
|
|
}
|
|
|
|
|
|
2019-04-29 14:39:48 +02:00
|
|
|
//
|
|
|
|
|
//// Representation of n-ary conjunctions (AND/OR)
|
|
|
|
|
//type conjunctExpression struct {
|
|
|
|
|
// expressions []Expression
|
|
|
|
|
// conjunction []byte
|
|
|
|
|
//}
|
|
|
|
|
//
|
|
|
|
|
//func (conj *conjunctExpression) Serialize(out *queryData, options ...serializeOption) error {
|
|
|
|
|
// if len(conj.expressions) == 0 {
|
|
|
|
|
// return errors.New("Empty conjunction.")
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// //clauses := make([]Clause, len(conj.expressions), len(conj.expressions))
|
|
|
|
|
// //for i, expr := range conj.expressions {
|
|
|
|
|
// // clauses[i] = expr
|
|
|
|
|
// //}
|
|
|
|
|
//
|
|
|
|
|
// useParentheses := len(conj.expressions) > 1
|
|
|
|
|
// if useParentheses {
|
|
|
|
|
// out.WriteByte('(')
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// if err := serializeExpressionList(conj.expressions, string(conj.conjunction), out); err != nil {
|
|
|
|
|
// return err
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// if useParentheses {
|
|
|
|
|
// out.WriteByte(')')
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// return nil
|
|
|
|
|
//}
|
2019-03-02 12:34:08 +01:00
|
|
|
|
2019-03-31 09:17:28 +02:00
|
|
|
//--------------------------------------------------------------
|
2019-03-02 12:34:08 +01:00
|
|
|
|
2019-03-31 14:07:58 +02:00
|
|
|
//------------------------------------------------------//
|
2019-04-03 11:03:07 +02:00
|
|
|
//// Dummy type for select *
|
|
|
|
|
//type ColumnList []Column
|
|
|
|
|
//
|
2019-04-29 14:39:48 +02:00
|
|
|
//func (cl ColumnList) Serialize(out *bytes.Buffer, options ...serializeOption) error {
|
2019-04-03 11:03:07 +02:00
|
|
|
// for i, column := range cl {
|
2019-04-29 14:39:48 +02:00
|
|
|
// err := column.Serialize(out)
|
2019-04-03 11:03:07 +02:00
|
|
|
//
|
|
|
|
|
// if err != nil {
|
|
|
|
|
// return err
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// if i != len(cl)-1 {
|
|
|
|
|
// out.WriteString(", ")
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// return nil
|
|
|
|
|
//}
|
|
|
|
|
//
|
|
|
|
|
//func (e ColumnList) As(alias string) Clause {
|
|
|
|
|
// panic("Invalid usage")
|
|
|
|
|
//}
|
|
|
|
|
//
|
|
|
|
|
//func (e ColumnList) IsDistinct(expression Expression) BoolExpression {
|
|
|
|
|
// panic("Invalid usage")
|
|
|
|
|
//}
|
|
|
|
|
//
|
|
|
|
|
//func (e ColumnList) IsNull(expression Expression) BoolExpression {
|
|
|
|
|
// panic("Invalid usage")
|
|
|
|
|
//}
|