Order by sql serialization simplified.
This commit is contained in:
parent
f016a93d78
commit
d9bbec3795
7 changed files with 32 additions and 39 deletions
|
|
@ -14,7 +14,7 @@ func NewAlias(expression expression, alias string) *Alias {
|
||||||
|
|
||||||
func (a *Alias) serializeForProjection(out *queryData) error {
|
func (a *Alias) serializeForProjection(out *queryData) error {
|
||||||
|
|
||||||
err := a.expression.serialize(out)
|
err := a.expression.serializeForProjection(out)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,6 @@ type queryData struct {
|
||||||
args []interface{}
|
args []interface{}
|
||||||
|
|
||||||
statementType int
|
statementType int
|
||||||
clauseType int
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
@ -26,43 +25,29 @@ const (
|
||||||
set_statement
|
set_statement
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
|
||||||
projection_clause = iota
|
|
||||||
where_clause
|
|
||||||
order_by_clause
|
|
||||||
group_by_clause
|
|
||||||
having_clause
|
|
||||||
)
|
|
||||||
|
|
||||||
func (q *queryData) WriteProjection(projections []projection) error {
|
func (q *queryData) WriteProjection(projections []projection) error {
|
||||||
q.clauseType = projection_clause
|
|
||||||
return serializeProjectionList(projections, q)
|
return serializeProjectionList(projections, q)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *queryData) WriteWhere(where expression) error {
|
func (q *queryData) WriteWhere(where expression) error {
|
||||||
q.clauseType = where_clause
|
|
||||||
q.WriteString(" WHERE ")
|
q.WriteString(" WHERE ")
|
||||||
return where.serialize(q)
|
return where.serialize(q)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *queryData) WriteGroupBy(groupBy []groupByClause) error {
|
func (q *queryData) WriteGroupBy(groupBy []groupByClause) error {
|
||||||
q.clauseType = group_by_clause
|
|
||||||
q.WriteString(" GROUP BY ")
|
q.WriteString(" GROUP BY ")
|
||||||
|
|
||||||
return serializeGroupByClauseList(groupBy, q)
|
return serializeGroupByClauseList(groupBy, q)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *queryData) WriteOrderBy(orderBy []orderByClause) error {
|
func (q *queryData) WriteOrderBy(orderBy []orderByClause) error {
|
||||||
q.clauseType = order_by_clause
|
|
||||||
q.WriteString(" ORDER BY ")
|
q.WriteString(" ORDER BY ")
|
||||||
return serializeOrderByClauseList(orderBy, q)
|
return serializeOrderByClauseList(orderBy, q)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *queryData) WriteHaving(having expression) error {
|
func (q *queryData) WriteHaving(having expression) error {
|
||||||
q.clauseType = having_clause
|
|
||||||
q.WriteString(" HAVING ")
|
q.WriteString(" HAVING ")
|
||||||
return having.serialize(q)
|
return having.serialize(q)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *queryData) Write(data []byte) {
|
func (q *queryData) Write(data []byte) {
|
||||||
|
|
|
||||||
|
|
@ -77,20 +77,33 @@ func (c *baseColumn) DefaultAlias() projection {
|
||||||
return c.AS(c.tableName + "." + c.name)
|
return c.AS(c.tableName + "." + c.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c baseColumn) serialize(out *queryData) error {
|
func (c *baseColumn) serializeAsOrderBy(out *queryData) error {
|
||||||
|
if out.statementType == set_statement {
|
||||||
setOrderBy := out.statementType == set_statement && out.clauseType == order_by_clause
|
// set statement (UNION, EXCEPT ...) can reference only select projections in order by clause
|
||||||
|
|
||||||
if setOrderBy {
|
|
||||||
out.WriteString(`"`)
|
out.WriteString(`"`)
|
||||||
}
|
|
||||||
|
|
||||||
if c.tableName != "" {
|
if c.tableName != "" {
|
||||||
out.WriteString(c.tableName)
|
out.WriteString(c.tableName)
|
||||||
out.WriteString(".")
|
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 {
|
if wrapColumnName {
|
||||||
out.WriteString(`"`)
|
out.WriteString(`"`)
|
||||||
|
|
@ -102,9 +115,5 @@ func (c baseColumn) serialize(out *queryData) error {
|
||||||
out.WriteString(`"`)
|
out.WriteString(`"`)
|
||||||
}
|
}
|
||||||
|
|
||||||
if setOrderBy {
|
|
||||||
out.WriteString(`"`)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ type expression interface {
|
||||||
clause
|
clause
|
||||||
projection
|
projection
|
||||||
groupByClause
|
groupByClause
|
||||||
|
orderByClause
|
||||||
|
|
||||||
IN(subQuery selectStatement) boolExpression
|
IN(subQuery selectStatement) boolExpression
|
||||||
NOT_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)
|
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)
|
// Representation of binary operations (e.g. comparisons, arithmetic)
|
||||||
type binaryExpression struct {
|
type binaryExpression struct {
|
||||||
lhs, rhs expression
|
lhs, rhs expression
|
||||||
|
|
|
||||||
|
|
@ -3,28 +3,20 @@ package sqlbuilder
|
||||||
import "github.com/dropbox/godropbox/errors"
|
import "github.com/dropbox/godropbox/errors"
|
||||||
|
|
||||||
type orderByClause interface {
|
type orderByClause interface {
|
||||||
clause
|
serializeAsOrderBy(out *queryData) error
|
||||||
isOrderByClauseType()
|
|
||||||
}
|
|
||||||
|
|
||||||
type isOrderByClause struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *isOrderByClause) isOrderByClauseType() {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type orderByClauseImpl struct {
|
type orderByClauseImpl struct {
|
||||||
isOrderByClause
|
|
||||||
expression expression
|
expression expression
|
||||||
ascent bool
|
ascent bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *orderByClauseImpl) serialize(out *queryData) error {
|
func (o *orderByClauseImpl) serializeAsOrderBy(out *queryData) error {
|
||||||
if o.expression == nil {
|
if o.expression == nil {
|
||||||
return errors.Newf("nil orderBy by clause.")
|
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
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ func serializeOrderByClauseList(orderByClauses []orderByClause, out *queryData)
|
||||||
out.WriteString(", ")
|
out.WriteString(", ")
|
||||||
}
|
}
|
||||||
|
|
||||||
err := value.serialize(out)
|
err := value.serializeAsOrderBy(out)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,9 @@ import (
|
||||||
|
|
||||||
func TestSelect_ScanToStruct(t *testing.T) {
|
func TestSelect_ScanToStruct(t *testing.T) {
|
||||||
actor := model.Actor{}
|
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()
|
queryStr, args, err := query.Sql()
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue