forked from mirror/gorm
Support Expression for OrderBy clause
This commit is contained in:
parent
57b033e2dd
commit
c915471169
|
@ -21,6 +21,7 @@ type NegationExpressionBuilder interface {
|
|||
type Expr struct {
|
||||
SQL string
|
||||
Vars []interface{}
|
||||
WithoutParentheses bool
|
||||
}
|
||||
|
||||
// Build build raw expression
|
||||
|
@ -32,7 +33,7 @@ func (expr Expr) Build(builder Builder) {
|
|||
|
||||
for _, v := range []byte(expr.SQL) {
|
||||
if v == '?' && len(expr.Vars) > idx {
|
||||
if afterParenthesis {
|
||||
if afterParenthesis || expr.WithoutParentheses {
|
||||
if _, ok := expr.Vars[idx].(driver.Valuer); ok {
|
||||
builder.AddVar(builder, expr.Vars[idx])
|
||||
} else {
|
||||
|
|
|
@ -8,6 +8,7 @@ type OrderByColumn struct {
|
|||
|
||||
type OrderBy struct {
|
||||
Columns []OrderByColumn
|
||||
Expression Expression
|
||||
}
|
||||
|
||||
// Name where clause name
|
||||
|
@ -17,6 +18,9 @@ func (orderBy OrderBy) Name() string {
|
|||
|
||||
// Build build where clause
|
||||
func (orderBy OrderBy) Build(builder Builder) {
|
||||
if orderBy.Expression != nil {
|
||||
orderBy.Expression.Build(builder)
|
||||
} else {
|
||||
for idx, column := range orderBy.Columns {
|
||||
if idx > 0 {
|
||||
builder.WriteByte(',')
|
||||
|
@ -28,6 +32,7 @@ func (orderBy OrderBy) Build(builder Builder) {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MergeClause merge order by clauses
|
||||
func (orderBy OrderBy) MergeClause(clause *Clause) {
|
||||
|
|
|
@ -39,6 +39,14 @@ func TestOrderBy(t *testing.T) {
|
|||
},
|
||||
"SELECT * FROM `users` ORDER BY `name`", nil,
|
||||
},
|
||||
{
|
||||
[]clause.Interface{
|
||||
clause.Select{}, clause.From{}, clause.OrderBy{
|
||||
Expression: clause.Expr{SQL: "FIELD(id, ?)", Vars: []interface{}{[]int{1, 2, 3}}, WithoutParentheses: true},
|
||||
},
|
||||
},
|
||||
"SELECT * FROM `users` ORDER BY FIELD(id, ?,?,?)", []interface{}{1, 2, 3},
|
||||
},
|
||||
}
|
||||
|
||||
for idx, result := range results {
|
||||
|
|
|
@ -12,6 +12,7 @@ import (
|
|||
"time"
|
||||
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/clause"
|
||||
. "gorm.io/gorm/utils/tests"
|
||||
)
|
||||
|
||||
|
@ -659,6 +660,15 @@ func TestOrder(t *testing.T) {
|
|||
if !regexp.MustCompile("SELECT \\* FROM .*users.* ORDER BY age desc,name").MatchString(result.Statement.SQL.String()) {
|
||||
t.Fatalf("Build Order condition, but got %v", result.Statement.SQL.String())
|
||||
}
|
||||
|
||||
stmt := dryDB.Clauses(clause.OrderBy{
|
||||
Expression: clause.Expr{SQL: "FIELD(id,?)", Vars: []interface{}{[]int{1, 2, 3}}, WithoutParentheses: true},
|
||||
}).Find(&User{}).Statement
|
||||
|
||||
explainedSQL := dryDB.Dialector.Explain(stmt.SQL.String(), stmt.Vars...)
|
||||
if !regexp.MustCompile("SELECT \\* FROM .*users.* ORDER BY FIELD\\(id,1,2,3\\)").MatchString(explainedSQL) {
|
||||
t.Fatalf("Build Order condition, but got %v", explainedSQL)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLimit(t *testing.T) {
|
||||
|
|
Loading…
Reference in New Issue