Merge pull request #4294 from jianzhiyao/frt/supports_for_4144
Frt/supports for issue 4144
This commit is contained in:
		
						commit
						0139564cf0
					
				| @ -4,4 +4,5 @@ | |||||||
| - Remove `duration` from prometheus labels. [4391](https://github.com/beego/beego/pull/4391) | - Remove `duration` from prometheus labels. [4391](https://github.com/beego/beego/pull/4391) | ||||||
| - Fix `unknown escape sequence` in generated code. [4385](https://github.com/beego/beego/pull/4385) | - Fix `unknown escape sequence` in generated code. [4385](https://github.com/beego/beego/pull/4385) | ||||||
| - Using fixed name `commentRouter.go` as generated file name. [4385](https://github.com/beego/beego/pull/4385) | - Using fixed name `commentRouter.go` as generated file name. [4385](https://github.com/beego/beego/pull/4385) | ||||||
| - Fix 4383: ORM Adapter produces panic when using orm.RegisterModelWithPrefix. [4386](https://github.com/beego/beego/pull/4386) | - Fix 4383: ORM Adapter produces panic when using orm.RegisterModelWithPrefix. [4386](https://github.com/beego/beego/pull/4386) | ||||||
|  | - Support 4144: Add new api for order by for supporting multiple way to query [4294](https://github.com/beego/beego/pull/4294) | ||||||
							
								
								
									
										6
									
								
								client/orm/clauses/const.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								client/orm/clauses/const.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,6 @@ | |||||||
|  | package clauses | ||||||
|  | 
 | ||||||
|  | const ( | ||||||
|  | 	ExprSep                = "__" | ||||||
|  | 	ExprDot                = "." | ||||||
|  | ) | ||||||
							
								
								
									
										103
									
								
								client/orm/clauses/order_clause/order.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								client/orm/clauses/order_clause/order.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,103 @@ | |||||||
|  | package order_clause | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"github.com/beego/beego/v2/client/orm/clauses" | ||||||
|  | 	"strings" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | type Sort int8 | ||||||
|  | 
 | ||||||
|  | const ( | ||||||
|  | 	None       Sort = 0 | ||||||
|  | 	Ascending  Sort = 1 | ||||||
|  | 	Descending Sort = 2 | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | type Option func(order *Order) | ||||||
|  | 
 | ||||||
|  | type Order struct { | ||||||
|  | 	column string | ||||||
|  | 	sort   Sort | ||||||
|  | 	isRaw  bool | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func Clause(options ...Option) *Order { | ||||||
|  | 	o := &Order{} | ||||||
|  | 	for _, option := range options { | ||||||
|  | 		option(o) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return o | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (o *Order) GetColumn() string { | ||||||
|  | 	return o.column | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (o *Order) GetSort() Sort { | ||||||
|  | 	return o.sort | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (o *Order) SortString() string { | ||||||
|  | 	switch o.GetSort() { | ||||||
|  | 	case Ascending: | ||||||
|  | 		return "ASC" | ||||||
|  | 	case Descending: | ||||||
|  | 		return "DESC" | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return `` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (o *Order) IsRaw() bool { | ||||||
|  | 	return o.isRaw | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func ParseOrder(expressions ...string) []*Order { | ||||||
|  | 	var orders []*Order | ||||||
|  | 	for _, expression := range expressions { | ||||||
|  | 		sort := Ascending | ||||||
|  | 		column := strings.ReplaceAll(expression, clauses.ExprSep, clauses.ExprDot) | ||||||
|  | 		if column[0] == '-' { | ||||||
|  | 			sort = Descending | ||||||
|  | 			column = column[1:] | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		orders = append(orders, &Order{ | ||||||
|  | 			column: column, | ||||||
|  | 			sort:   sort, | ||||||
|  | 		}) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return orders | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func Column(column string) Option { | ||||||
|  | 	return func(order *Order) { | ||||||
|  | 		order.column = strings.ReplaceAll(column, clauses.ExprSep, clauses.ExprDot) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func sort(sort Sort) Option { | ||||||
|  | 	return func(order *Order) { | ||||||
|  | 		order.sort = sort | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func SortAscending() Option { | ||||||
|  | 	return sort(Ascending) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func SortDescending() Option { | ||||||
|  | 	return sort(Descending) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func SortNone() Option { | ||||||
|  | 	return sort(None) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func Raw() Option { | ||||||
|  | 	return func(order *Order) { | ||||||
|  | 		order.isRaw = true | ||||||
|  | 	} | ||||||
|  | } | ||||||
							
								
								
									
										144
									
								
								client/orm/clauses/order_clause/order_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										144
									
								
								client/orm/clauses/order_clause/order_test.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,144 @@ | |||||||
|  | package order_clause | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"testing" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | func TestClause(t *testing.T) { | ||||||
|  | 	var ( | ||||||
|  | 		column = `a` | ||||||
|  | 	) | ||||||
|  | 
 | ||||||
|  | 	o := Clause( | ||||||
|  | 		Column(column), | ||||||
|  | 	) | ||||||
|  | 
 | ||||||
|  | 	if o.GetColumn() != column { | ||||||
|  | 		t.Error() | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func TestSortAscending(t *testing.T) { | ||||||
|  | 	o := Clause( | ||||||
|  | 		SortAscending(), | ||||||
|  | 	) | ||||||
|  | 
 | ||||||
|  | 	if o.GetSort() != Ascending { | ||||||
|  | 		t.Error() | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func TestSortDescending(t *testing.T) { | ||||||
|  | 	o := Clause( | ||||||
|  | 		SortDescending(), | ||||||
|  | 	) | ||||||
|  | 
 | ||||||
|  | 	if o.GetSort() != Descending { | ||||||
|  | 		t.Error() | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func TestSortNone(t *testing.T) { | ||||||
|  | 	o1 := Clause( | ||||||
|  | 		SortNone(), | ||||||
|  | 	) | ||||||
|  | 
 | ||||||
|  | 	if o1.GetSort() != None { | ||||||
|  | 		t.Error() | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	o2 := Clause() | ||||||
|  | 
 | ||||||
|  | 	if o2.GetSort() != None { | ||||||
|  | 		t.Error() | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func TestRaw(t *testing.T) { | ||||||
|  | 	o1 := Clause() | ||||||
|  | 
 | ||||||
|  | 	if o1.IsRaw() { | ||||||
|  | 		t.Error() | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	o2 := Clause( | ||||||
|  | 		Raw(), | ||||||
|  | 	) | ||||||
|  | 
 | ||||||
|  | 	if !o2.IsRaw() { | ||||||
|  | 		t.Error() | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func TestColumn(t *testing.T) { | ||||||
|  | 	o1 := Clause( | ||||||
|  | 		Column(`aaa`), | ||||||
|  | 	) | ||||||
|  | 
 | ||||||
|  | 	if o1.GetColumn() != `aaa` { | ||||||
|  | 		t.Error() | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func TestParseOrder(t *testing.T) { | ||||||
|  | 	orders := ParseOrder( | ||||||
|  | 		`-user__status`, | ||||||
|  | 		`status`, | ||||||
|  | 		`user__status`, | ||||||
|  | 	) | ||||||
|  | 
 | ||||||
|  | 	t.Log(orders) | ||||||
|  | 
 | ||||||
|  | 	if orders[0].GetSort() != Descending { | ||||||
|  | 		t.Error() | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if orders[0].GetColumn() != `user.status` { | ||||||
|  | 		t.Error() | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if orders[1].GetColumn() != `status` { | ||||||
|  | 		t.Error() | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if orders[1].GetSort() != Ascending { | ||||||
|  | 		t.Error() | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if orders[2].GetColumn() != `user.status` { | ||||||
|  | 		t.Error() | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func TestOrder_GetColumn(t *testing.T) { | ||||||
|  | 	o := Clause( | ||||||
|  | 		Column(`user__id`), | ||||||
|  | 	) | ||||||
|  | 	if o.GetColumn() != `user.id` { | ||||||
|  | 		t.Error() | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func TestOrder_GetSort(t *testing.T) { | ||||||
|  | 	o := Clause( | ||||||
|  | 		SortDescending(), | ||||||
|  | 	) | ||||||
|  | 	if o.GetSort() != Descending { | ||||||
|  | 		t.Error() | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func TestOrder_IsRaw(t *testing.T) { | ||||||
|  | 	o1 := Clause() | ||||||
|  | 	if o1.IsRaw() { | ||||||
|  | 		t.Error() | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	o2 := Clause( | ||||||
|  | 		Raw(), | ||||||
|  | 	) | ||||||
|  | 	if !o2.IsRaw() { | ||||||
|  | 		t.Error() | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @ -16,6 +16,8 @@ package orm | |||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"fmt" | 	"fmt" | ||||||
|  | 	"github.com/beego/beego/v2/client/orm/clauses" | ||||||
|  | 	"github.com/beego/beego/v2/client/orm/clauses/order_clause" | ||||||
| 	"strings" | 	"strings" | ||||||
| 	"time" | 	"time" | ||||||
| ) | ) | ||||||
| @ -421,7 +423,7 @@ func (t *dbTables) getGroupSQL(groups []string) (groupSQL string) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // generate order sql. | // generate order sql. | ||||||
| func (t *dbTables) getOrderSQL(orders []string) (orderSQL string) { | func (t *dbTables) getOrderSQL(orders []*order_clause.Order) (orderSQL string) { | ||||||
| 	if len(orders) == 0 { | 	if len(orders) == 0 { | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| @ -430,19 +432,25 @@ func (t *dbTables) getOrderSQL(orders []string) (orderSQL string) { | |||||||
| 
 | 
 | ||||||
| 	orderSqls := make([]string, 0, len(orders)) | 	orderSqls := make([]string, 0, len(orders)) | ||||||
| 	for _, order := range orders { | 	for _, order := range orders { | ||||||
| 		asc := "ASC" | 		column := order.GetColumn() | ||||||
| 		if order[0] == '-' { | 		clause := strings.Split(column, clauses.ExprDot) | ||||||
| 			asc = "DESC" |  | ||||||
| 			order = order[1:] |  | ||||||
| 		} |  | ||||||
| 		exprs := strings.Split(order, ExprSep) |  | ||||||
| 
 | 
 | ||||||
| 		index, _, fi, suc := t.parseExprs(t.mi, exprs) | 		if order.IsRaw() { | ||||||
| 		if !suc { | 			if len(clause) == 2 { | ||||||
| 			panic(fmt.Errorf("unknown field/column name `%s`", strings.Join(exprs, ExprSep))) | 				orderSqls = append(orderSqls, fmt.Sprintf("%s.%s%s%s %s", clause[0], Q, clause[1], Q, order.SortString())) | ||||||
| 		} | 			} else if len(clause) == 1 { | ||||||
|  | 				orderSqls = append(orderSqls, fmt.Sprintf("%s%s%s %s", Q, clause[0], Q, order.SortString())) | ||||||
|  | 			} else { | ||||||
|  | 				panic(fmt.Errorf("unknown field/column name `%s`", strings.Join(clause, ExprSep))) | ||||||
|  | 			} | ||||||
|  | 		} else { | ||||||
|  | 			index, _, fi, suc := t.parseExprs(t.mi, clause) | ||||||
|  | 			if !suc { | ||||||
|  | 				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)) | 			orderSqls = append(orderSqls, fmt.Sprintf("%s.%s%s%s %s", index, Q, fi.column, Q, order.SortString())) | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	orderSQL = fmt.Sprintf("ORDER BY %s ", strings.Join(orderSqls, ", ")) | 	orderSQL = fmt.Sprintf("ORDER BY %s ", strings.Join(orderSqls, ", ")) | ||||||
|  | |||||||
| @ -58,6 +58,7 @@ import ( | |||||||
| 	"database/sql" | 	"database/sql" | ||||||
| 	"errors" | 	"errors" | ||||||
| 	"fmt" | 	"fmt" | ||||||
|  | 	"github.com/beego/beego/v2/client/orm/clauses/order_clause" | ||||||
| 	"os" | 	"os" | ||||||
| 	"reflect" | 	"reflect" | ||||||
| 	"time" | 	"time" | ||||||
| @ -351,7 +352,7 @@ func (o *ormBase) LoadRelatedWithCtx(ctx context.Context, md interface{}, name s | |||||||
| 	qs.relDepth = relDepth | 	qs.relDepth = relDepth | ||||||
| 
 | 
 | ||||||
| 	if len(order) > 0 { | 	if len(order) > 0 { | ||||||
| 		qs.orders = []string{order} | 		qs.orders = order_clause.ParseOrder(order) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	find := ind.FieldByIndex(fi.fieldIndex) | 	find := ind.FieldByIndex(fi.fieldIndex) | ||||||
|  | |||||||
| @ -16,12 +16,13 @@ package orm | |||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"fmt" | 	"fmt" | ||||||
|  | 	"github.com/beego/beego/v2/client/orm/clauses" | ||||||
| 	"strings" | 	"strings" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // ExprSep define the expression separation | // ExprSep define the expression separation | ||||||
| const ( | const ( | ||||||
| 	ExprSep = "__" | 	ExprSep = clauses.ExprSep | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| type condValue struct { | type condValue struct { | ||||||
|  | |||||||
| @ -17,8 +17,8 @@ package orm | |||||||
| import ( | import ( | ||||||
| 	"context" | 	"context" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 
 |  | ||||||
| 	"github.com/beego/beego/v2/client/orm/hints" | 	"github.com/beego/beego/v2/client/orm/hints" | ||||||
|  | 	"github.com/beego/beego/v2/client/orm/clauses/order_clause" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| type colValue struct { | type colValue struct { | ||||||
| @ -71,7 +71,7 @@ type querySet struct { | |||||||
| 	limit      int64 | 	limit      int64 | ||||||
| 	offset     int64 | 	offset     int64 | ||||||
| 	groups     []string | 	groups     []string | ||||||
| 	orders     []string | 	orders     []*order_clause.Order | ||||||
| 	distinct   bool | 	distinct   bool | ||||||
| 	forUpdate  bool | 	forUpdate  bool | ||||||
| 	useIndex   int | 	useIndex   int | ||||||
| @ -140,8 +140,20 @@ func (o querySet) GroupBy(exprs ...string) QuerySeter { | |||||||
| 
 | 
 | ||||||
| // add ORDER expression. | // add ORDER expression. | ||||||
| // "column" means ASC, "-column" means DESC. | // "column" means ASC, "-column" means DESC. | ||||||
| func (o querySet) OrderBy(exprs ...string) QuerySeter { | func (o querySet) OrderBy(expressions ...string) QuerySeter { | ||||||
| 	o.orders = exprs | 	if len(expressions) <= 0 { | ||||||
|  | 		return &o | ||||||
|  | 	} | ||||||
|  | 	o.orders = order_clause.ParseOrder(expressions...) | ||||||
|  | 	return &o | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // add ORDER expression. | ||||||
|  | func (o querySet) OrderClauses(orders ...*order_clause.Order) QuerySeter { | ||||||
|  | 	if len(orders) <= 0 { | ||||||
|  | 		return &o | ||||||
|  | 	} | ||||||
|  | 	o.orders = orders | ||||||
| 	return &o | 	return &o | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -21,6 +21,7 @@ import ( | |||||||
| 	"context" | 	"context" | ||||||
| 	"database/sql" | 	"database/sql" | ||||||
| 	"fmt" | 	"fmt" | ||||||
|  | 	"github.com/beego/beego/v2/client/orm/clauses/order_clause" | ||||||
| 	"io/ioutil" | 	"io/ioutil" | ||||||
| 	"math" | 	"math" | ||||||
| 	"os" | 	"os" | ||||||
| @ -1146,6 +1147,26 @@ func TestOrderBy(t *testing.T) { | |||||||
| 	num, err = qs.OrderBy("-profile__age").Filter("user_name", "astaxie").Count() | 	num, err = qs.OrderBy("-profile__age").Filter("user_name", "astaxie").Count() | ||||||
| 	throwFail(t, err) | 	throwFail(t, err) | ||||||
| 	throwFail(t, AssertIs(num, 1)) | 	throwFail(t, AssertIs(num, 1)) | ||||||
|  | 
 | ||||||
|  | 	num, err = qs.OrderClauses( | ||||||
|  | 		order_clause.Clause( | ||||||
|  | 			order_clause.Column(`profile__age`), | ||||||
|  | 			order_clause.SortDescending(), | ||||||
|  | 		), | ||||||
|  | 	).Filter("user_name", "astaxie").Count() | ||||||
|  | 	throwFail(t, err) | ||||||
|  | 	throwFail(t, AssertIs(num, 1)) | ||||||
|  | 
 | ||||||
|  | 	if IsMysql { | ||||||
|  | 		num, err = qs.OrderClauses( | ||||||
|  | 			order_clause.Clause( | ||||||
|  | 				order_clause.Column(`rand()`), | ||||||
|  | 				order_clause.Raw(), | ||||||
|  | 			), | ||||||
|  | 		).Filter("user_name", "astaxie").Count() | ||||||
|  | 		throwFail(t, err) | ||||||
|  | 		throwFail(t, AssertIs(num, 1)) | ||||||
|  | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestAll(t *testing.T) { | func TestAll(t *testing.T) { | ||||||
| @ -1232,6 +1253,19 @@ func TestValues(t *testing.T) { | |||||||
| 		throwFail(t, AssertIs(maps[2]["Profile"], nil)) | 		throwFail(t, AssertIs(maps[2]["Profile"], nil)) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	num, err = qs.OrderClauses( | ||||||
|  | 		order_clause.Clause( | ||||||
|  | 			order_clause.Column("Id"), | ||||||
|  | 			order_clause.SortAscending(), | ||||||
|  | 		), | ||||||
|  | 	).Values(&maps) | ||||||
|  | 	throwFail(t, err) | ||||||
|  | 	throwFail(t, AssertIs(num, 3)) | ||||||
|  | 	if num == 3 { | ||||||
|  | 		throwFail(t, AssertIs(maps[0]["UserName"], "slene")) | ||||||
|  | 		throwFail(t, AssertIs(maps[2]["Profile"], nil)) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	num, err = qs.OrderBy("Id").Values(&maps, "UserName", "Profile__Age") | 	num, err = qs.OrderBy("Id").Values(&maps, "UserName", "Profile__Age") | ||||||
| 	throwFail(t, err) | 	throwFail(t, err) | ||||||
| 	throwFail(t, AssertIs(num, 3)) | 	throwFail(t, AssertIs(num, 3)) | ||||||
|  | |||||||
| @ -17,6 +17,7 @@ package orm | |||||||
| import ( | import ( | ||||||
| 	"context" | 	"context" | ||||||
| 	"database/sql" | 	"database/sql" | ||||||
|  | 	"github.com/beego/beego/v2/client/orm/clauses/order_clause" | ||||||
| 	"reflect" | 	"reflect" | ||||||
| 	"time" | 	"time" | ||||||
| 
 | 
 | ||||||
| @ -289,6 +290,28 @@ type QuerySeter interface { | |||||||
| 	// for example: | 	// for example: | ||||||
| 	//	qs.OrderBy("-status") | 	//	qs.OrderBy("-status") | ||||||
| 	OrderBy(exprs ...string) QuerySeter | 	OrderBy(exprs ...string) QuerySeter | ||||||
|  | 	// add ORDER expression by order clauses | ||||||
|  | 	// for example: | ||||||
|  | 	//	OrderClauses( | ||||||
|  | 	//		order_clause.Clause( | ||||||
|  | 	//			order.Column("Id"), | ||||||
|  | 	//			order.SortAscending(), | ||||||
|  | 	//		), | ||||||
|  | 	//		order_clause.Clause( | ||||||
|  | 	//			order.Column("status"), | ||||||
|  | 	//			order.SortDescending(), | ||||||
|  | 	//		), | ||||||
|  | 	//	) | ||||||
|  | 	//	OrderClauses(order_clause.Clause( | ||||||
|  | 	//		order_clause.Column(`user__status`), | ||||||
|  | 	//		order_clause.SortDescending(),//default None | ||||||
|  | 	//	)) | ||||||
|  | 	//	OrderClauses(order_clause.Clause( | ||||||
|  | 	//		order_clause.Column(`random()`), | ||||||
|  | 	//		order_clause.SortNone(),//default None | ||||||
|  | 	//		order_clause.Raw(),//default false.if true, do not check field is valid or not | ||||||
|  | 	//	)) | ||||||
|  | 	OrderClauses(orders ...*order_clause.Order) QuerySeter | ||||||
| 	// add FORCE INDEX expression. | 	// add FORCE INDEX expression. | ||||||
| 	// for example: | 	// for example: | ||||||
| 	//	qs.ForceIndex(`idx_name1`,`idx_name2`) | 	//	qs.ForceIndex(`idx_name1`,`idx_name2`) | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user