Order by sql serialization simplified.

This commit is contained in:
zer0sub 2019-05-08 12:49:36 +02:00
parent f016a93d78
commit d9bbec3795
7 changed files with 32 additions and 39 deletions

View file

@ -14,7 +14,7 @@ func NewAlias(expression expression, alias string) *Alias {
func (a *Alias) serializeForProjection(out *queryData) error {
err := a.expression.serialize(out)
err := a.expression.serializeForProjection(out)
if err != nil {
return err

View file

@ -15,7 +15,6 @@ type queryData struct {
args []interface{}
statementType int
clauseType int
}
const (
@ -26,43 +25,29 @@ const (
set_statement
)
const (
projection_clause = iota
where_clause
order_by_clause
group_by_clause
having_clause
)
func (q *queryData) WriteProjection(projections []projection) error {
q.clauseType = projection_clause
return serializeProjectionList(projections, q)
}
func (q *queryData) WriteWhere(where expression) error {
q.clauseType = where_clause
q.WriteString(" WHERE ")
return where.serialize(q)
}
func (q *queryData) WriteGroupBy(groupBy []groupByClause) error {
q.clauseType = group_by_clause
q.WriteString(" GROUP BY ")
return serializeGroupByClauseList(groupBy, q)
}
func (q *queryData) WriteOrderBy(orderBy []orderByClause) error {
q.clauseType = order_by_clause
q.WriteString(" ORDER BY ")
return serializeOrderByClauseList(orderBy, q)
}
func (q *queryData) WriteHaving(having expression) error {
q.clauseType = having_clause
q.WriteString(" HAVING ")
return having.serialize(q)
}
func (q *queryData) Write(data []byte) {

View file

@ -77,20 +77,33 @@ func (c *baseColumn) DefaultAlias() projection {
return c.AS(c.tableName + "." + c.name)
}
func (c baseColumn) serialize(out *queryData) error {
setOrderBy := out.statementType == set_statement && out.clauseType == order_by_clause
if setOrderBy {
func (c *baseColumn) serializeAsOrderBy(out *queryData) error {
if out.statementType == set_statement {
// set statement (UNION, EXCEPT ...) can reference only select projections in order by clause
out.WriteString(`"`)
}
if c.tableName != "" {
out.WriteString(c.tableName)
out.WriteString(".")
}
wrapColumnName := strings.Contains(c.name, ".") && !setOrderBy
out.WriteString(c.name)
out.WriteString(`"`)
return nil
}
return c.serialize(out)
}
func (c baseColumn) serialize(out *queryData) error {
if c.tableName != "" {
out.WriteString(c.tableName)
out.WriteString(".")
}
wrapColumnName := strings.Contains(c.name, ".")
if wrapColumnName {
out.WriteString(`"`)
@ -102,9 +115,5 @@ func (c baseColumn) serialize(out *queryData) error {
out.WriteString(`"`)
}
if setOrderBy {
out.WriteString(`"`)
}
return nil
}

View file

@ -9,6 +9,7 @@ type expression interface {
clause
projection
groupByClause
orderByClause
IN(subQuery selectStatement) boolExpression
NOT_IN(subQuery selectStatement) boolExpression
@ -60,6 +61,10 @@ func (e *expressionInterfaceImpl) serializeForProjection(out *queryData) error {
return e.parent.serialize(out)
}
func (e *expressionInterfaceImpl) serializeAsOrderBy(out *queryData) error {
return e.parent.serialize(out)
}
// Representation of binary operations (e.g. comparisons, arithmetic)
type binaryExpression struct {
lhs, rhs expression

View file

@ -3,28 +3,20 @@ package sqlbuilder
import "github.com/dropbox/godropbox/errors"
type orderByClause interface {
clause
isOrderByClauseType()
}
type isOrderByClause struct {
}
func (o *isOrderByClause) isOrderByClauseType() {
serializeAsOrderBy(out *queryData) error
}
type orderByClauseImpl struct {
isOrderByClause
expression expression
ascent bool
}
func (o *orderByClauseImpl) serialize(out *queryData) error {
func (o *orderByClauseImpl) serializeAsOrderBy(out *queryData) error {
if o.expression == nil {
return errors.Newf("nil orderBy by clause.")
}
if err := o.expression.serialize(out); err != nil {
if err := o.expression.serializeAsOrderBy(out); err != nil {
return err
}

View file

@ -14,7 +14,7 @@ func serializeOrderByClauseList(orderByClauses []orderByClause, out *queryData)
out.WriteString(", ")
}
err := value.serialize(out)
err := value.serializeAsOrderBy(out)
if err != nil {
return err

View file

@ -13,7 +13,9 @@ import (
func TestSelect_ScanToStruct(t *testing.T) {
actor := model.Actor{}
query := Actor.SELECT(Actor.AllColumns).ORDER_BY(Actor.ActorID.ASC())
query := Actor.
SELECT(Actor.AllColumns).
ORDER_BY(Actor.ActorID.ASC())
queryStr, args, err := query.Sql()