From 9bd2934e42b930157ec085108a90e0294264bab0 Mon Sep 17 00:00:00 2001 From: Anker Jam Date: Sun, 25 Oct 2020 21:07:03 +0800 Subject: [PATCH] add order clause --- client/orm/db_tables.go | 13 ++++---- client/orm/orm.go | 3 +- client/orm/orm_queryset.go | 11 ++++--- client/orm/structs/order_phrase.go | 48 ++++++++++++++++++++++++++++++ 4 files changed, 64 insertions(+), 11 deletions(-) create mode 100644 client/orm/structs/order_phrase.go diff --git a/client/orm/db_tables.go b/client/orm/db_tables.go index 5fd472d1..c67af052 100644 --- a/client/orm/db_tables.go +++ b/client/orm/db_tables.go @@ -16,6 +16,7 @@ package orm import ( "fmt" + "github.com/astaxie/beego/client/orm/structs" "strings" "time" ) @@ -421,7 +422,7 @@ func (t *dbTables) getGroupSQL(groups []string) (groupSQL string) { } // generate order sql. -func (t *dbTables) getOrderSQL(orders []string) (orderSQL string) { +func (t *dbTables) getOrderSQL(orders []*structs.OrderClause) (orderSQL string) { if len(orders) == 0 { return } @@ -430,16 +431,16 @@ func (t *dbTables) getOrderSQL(orders []string) (orderSQL string) { orderSqls := make([]string, 0, len(orders)) for _, order := range orders { + column := order.Column asc := "ASC" - if order[0] == '-' { + if order.Sort == structs.DESCENDING { asc = "DESC" - order = order[1:] } - exprs := strings.Split(order, ExprSep) + clause := strings.Split(column, ExprSep) - index, _, fi, suc := t.parseExprs(t.mi, exprs) + index, _, fi, suc := t.parseExprs(t.mi, clause) if !suc { - panic(fmt.Errorf("unknown field/column name `%s`", strings.Join(exprs, ExprSep))) + panic(fmt.Errorf("unknown field/column name `%s`", strings.Join(clause, ExprSep))) } orderSqls = append(orderSqls, fmt.Sprintf("%s.%s%s%s %s", index, Q, fi.column, Q, asc)) diff --git a/client/orm/orm.go b/client/orm/orm.go index a83faeb2..52a99572 100644 --- a/client/orm/orm.go +++ b/client/orm/orm.go @@ -58,6 +58,7 @@ import ( "database/sql" "errors" "fmt" + "github.com/astaxie/beego/client/orm/structs" "os" "reflect" "time" @@ -351,7 +352,7 @@ func (o *ormBase) LoadRelatedWithCtx(ctx context.Context, md interface{}, name s qs.relDepth = relDepth if len(order) > 0 { - qs.orders = []string{order} + qs.orders = structs.ParseOrderClause(order) } find := ind.FieldByIndex(fi.fieldIndex) diff --git a/client/orm/orm_queryset.go b/client/orm/orm_queryset.go index ed223e24..480dc561 100644 --- a/client/orm/orm_queryset.go +++ b/client/orm/orm_queryset.go @@ -17,8 +17,8 @@ package orm import ( "context" "fmt" - "github.com/astaxie/beego/client/orm/hints" + "github.com/astaxie/beego/client/orm/structs" ) type colValue struct { @@ -71,7 +71,7 @@ type querySet struct { limit int64 offset int64 groups []string - orders []string + orders []*structs.OrderClause distinct bool forUpdate bool useIndex int @@ -139,8 +139,11 @@ func (o querySet) GroupBy(exprs ...string) QuerySeter { // add ORDER expression. // "column" means ASC, "-column" means DESC. -func (o querySet) OrderBy(exprs ...string) QuerySeter { - o.orders = exprs +func (o querySet) OrderBy(expressions ...string) QuerySeter { + if len(expressions) <= 0 { + return &o + } + o.orders = structs.ParseOrderClause(expressions...) return &o } diff --git a/client/orm/structs/order_phrase.go b/client/orm/structs/order_phrase.go new file mode 100644 index 00000000..30faf429 --- /dev/null +++ b/client/orm/structs/order_phrase.go @@ -0,0 +1,48 @@ +package structs + +import "fmt" + +type Sort int8 + +const ( + ASCENDING Sort = 1 + DESCENDING Sort = 2 +) + +type OrderClause struct { + Column string + Sort Sort +} + +var _ fmt.Stringer = new(OrderClause) + +func (o *OrderClause) String() string { + sort := `` + if o.Sort == ASCENDING { + sort = `ASC` + } else if o.Sort == DESCENDING { + sort = `DESC` + } else { + return fmt.Sprintf("%s", o.Column) + } + return fmt.Sprintf("%s %s", o.Column, sort) +} + +func ParseOrderClause(expressions ...string) []*OrderClause { + var orders []*OrderClause + for _, expression := range expressions { + sort := ASCENDING + column := expression + if expression[0] == '-' { + sort = DESCENDING + column = expression[1:] + } + + orders = append(orders, &OrderClause{ + Column: column, + Sort: sort, + }) + } + + return orders +}