Fix multi-order in a better way
First and Last do not order if query is already ordered (inspired by ActiveRecord)
This commit is contained in:
parent
f930ed782b
commit
4878e0917e
12
main.go
12
main.go
@ -294,8 +294,10 @@ func (s *DB) Assign(attrs ...interface{}) *DB {
|
|||||||
func (s *DB) First(out interface{}, where ...interface{}) *DB {
|
func (s *DB) First(out interface{}, where ...interface{}) *DB {
|
||||||
newScope := s.NewScope(out)
|
newScope := s.NewScope(out)
|
||||||
newScope.Search.Limit(1)
|
newScope.Search.Limit(1)
|
||||||
return newScope.Set("gorm:order_by_primary_key", "ASC").
|
if len(newScope.Search.orders) == 0 {
|
||||||
inlineCondition(where...).callCallbacks(s.parent.callbacks.queries).db
|
newScope.Set("gorm:order_by_primary_key", "ASC")
|
||||||
|
}
|
||||||
|
return newScope.inlineCondition(where...).callCallbacks(s.parent.callbacks.queries).db
|
||||||
}
|
}
|
||||||
|
|
||||||
// Take return a record that match given conditions, the order will depend on the database implementation
|
// Take return a record that match given conditions, the order will depend on the database implementation
|
||||||
@ -309,8 +311,10 @@ func (s *DB) Take(out interface{}, where ...interface{}) *DB {
|
|||||||
func (s *DB) Last(out interface{}, where ...interface{}) *DB {
|
func (s *DB) Last(out interface{}, where ...interface{}) *DB {
|
||||||
newScope := s.NewScope(out)
|
newScope := s.NewScope(out)
|
||||||
newScope.Search.Limit(1)
|
newScope.Search.Limit(1)
|
||||||
return newScope.Set("gorm:order_by_primary_key", "DESC").
|
if len(newScope.Search.orders) == 0 {
|
||||||
inlineCondition(where...).callCallbacks(s.parent.callbacks.queries).db
|
newScope.Set("gorm:order_by_primary_key", "DESC")
|
||||||
|
}
|
||||||
|
return newScope.inlineCondition(where...).callCallbacks(s.parent.callbacks.queries).db
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find find records that match given conditions
|
// Find find records that match given conditions
|
||||||
|
|||||||
18
scope.go
18
scope.go
@ -800,27 +800,9 @@ func (scope *Scope) orderSQL() string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// We have to make sure, that one column is not used multiple times in the order by clause.
|
|
||||||
// This would lead to an error on MSSQL.
|
|
||||||
// Therefore we create a map with just the column names and while creating the order by clause we may skip
|
|
||||||
// one or more columns
|
|
||||||
orderByColumnMap := make(map[string]bool, len(scope.Search.orders))
|
|
||||||
|
|
||||||
var orders []string
|
var orders []string
|
||||||
for _, order := range scope.Search.orders {
|
for _, order := range scope.Search.orders {
|
||||||
if str, ok := order.(string); ok {
|
if str, ok := order.(string); ok {
|
||||||
columnName := str
|
|
||||||
columnNameLC := strings.ToLower(columnName)
|
|
||||||
if strings.HasSuffix(columnNameLC, " asc") {
|
|
||||||
columnName = columnName[0 : len(columnName)-4]
|
|
||||||
} else if strings.HasSuffix(columnNameLC, " desc") {
|
|
||||||
columnName = columnName[0 : len(columnName)-5]
|
|
||||||
}
|
|
||||||
if _, ok := orderByColumnMap[columnName]; ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
orderByColumnMap[columnName] = true
|
|
||||||
|
|
||||||
orders = append(orders, scope.quoteIfPossible(str))
|
orders = append(orders, scope.quoteIfPossible(str))
|
||||||
} else if expr, ok := order.(*expr); ok {
|
} else if expr, ok := order.(*expr); ok {
|
||||||
exp := expr.expr
|
exp := expr.expr
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user