refactor: update OrderBy clause to use Exprs instead of Columns

This commit is contained in:
Or Ben Chitrit 2025-02-19 20:54:19 +02:00
parent 9f273777f5
commit ed88c5d9c6
4 changed files with 44 additions and 34 deletions

View File

@ -318,12 +318,12 @@ func (db *DB) Order(value interface{}) (tx *DB) {
tx.Statement.AddClause(v) tx.Statement.AddClause(v)
case clause.OrderByColumn: case clause.OrderByColumn:
tx.Statement.AddClause(clause.OrderBy{ tx.Statement.AddClause(clause.OrderBy{
Columns: []clause.OrderByColumn{v}, Exprs: []clause.Expression{v},
}) })
case string: case string:
if v != "" { if v != "" {
tx.Statement.AddClause(clause.OrderBy{ tx.Statement.AddClause(clause.OrderBy{
Columns: []clause.OrderByColumn{{ Exprs: []clause.Expression{clause.OrderByColumn{
Column: clause.Column{Name: v, Raw: true}, Column: clause.Column{Name: v, Raw: true},
}}, }},
}) })
@ -448,9 +448,10 @@ func (db *DB) Assign(attrs ...interface{}) (tx *DB) {
// Unscoped allows queries to include records marked as deleted, // Unscoped allows queries to include records marked as deleted,
// overriding the soft deletion behavior. // overriding the soft deletion behavior.
// Example: // Example:
// var users []User //
// db.Unscoped().Find(&users) // var users []User
// // Retrieves all users, including deleted ones. // db.Unscoped().Find(&users)
// // Retrieves all users, including deleted ones.
func (db *DB) Unscoped() (tx *DB) { func (db *DB) Unscoped() (tx *DB) {
tx = db.getInstance() tx = db.getInstance()
tx.Statement.Unscoped = true tx.Statement.Unscoped = true

View File

@ -45,7 +45,7 @@ func BenchmarkComplexSelect(b *testing.B) {
}}, }},
clause.GroupBy{Columns: []clause.Column{{Name: "role"}}, Having: []clause.Expression{clause.Eq{"role", "admin"}}}, clause.GroupBy{Columns: []clause.Column{{Name: "role"}}, Having: []clause.Expression{clause.Eq{"role", "admin"}}},
clause.Limit{Limit: &limit10, Offset: 20}, clause.Limit{Limit: &limit10, Offset: 20},
clause.OrderBy{Columns: []clause.OrderByColumn{{Column: clause.PrimaryColumn, Desc: true}}}, clause.OrderBy{Exprs: []clause.Expression{clause.OrderByColumn{Column: clause.PrimaryColumn, Desc: true}}},
} }
for _, clause := range clauses { for _, clause := range clauses {

View File

@ -6,48 +6,45 @@ type OrderByColumn struct {
Reorder bool Reorder bool
} }
type OrderBy struct { func (column OrderByColumn) Build(builder Builder) {
Columns []OrderByColumn builder.WriteQuoted(column.Column)
Expression Expression if column.Desc {
builder.WriteString(" DESC")
}
}
type OrderBy struct {
Exprs []Expression
} }
// Name where clause name
func (orderBy OrderBy) Name() string { func (orderBy OrderBy) Name() string {
return "ORDER BY" return "ORDER BY"
} }
// Build build where clause // Build build where clause
func (orderBy OrderBy) Build(builder Builder) { func (orderBy OrderBy) Build(builder Builder) {
if orderBy.Expression != nil { for idx, expression := range orderBy.Exprs {
orderBy.Expression.Build(builder) if idx > 0 {
} else { builder.WriteByte(',')
for idx, column := range orderBy.Columns {
if idx > 0 {
builder.WriteByte(',')
}
builder.WriteQuoted(column.Column)
if column.Desc {
builder.WriteString(" DESC")
}
} }
expression.Build(builder)
} }
} }
// MergeClause merge order by clauses // MergeClause merge order by clauses
func (orderBy OrderBy) MergeClause(clause *Clause) { func (orderBy OrderBy) MergeClause(clause *Clause) {
if v, ok := clause.Expression.(OrderBy); ok { if v, ok := clause.Expression.(OrderBy); ok {
for i := len(orderBy.Columns) - 1; i >= 0; i-- { for i := len(orderBy.Exprs) - 1; i >= 0; i-- {
if orderBy.Columns[i].Reorder { if asColumn, ok := orderBy.Exprs[i].(OrderByColumn); ok && asColumn.Reorder {
orderBy.Columns = orderBy.Columns[i:] orderBy.Exprs = orderBy.Exprs[i:]
clause.Expression = orderBy clause.Expression = orderBy
return return
} }
} }
copiedColumns := make([]OrderByColumn, len(v.Columns)) copiedColumns := make([]Expression, len(v.Exprs))
copy(copiedColumns, v.Columns) copy(copiedColumns, v.Exprs)
orderBy.Columns = append(copiedColumns, orderBy.Columns...) orderBy.Exprs = append(copiedColumns, orderBy.Exprs...)
} }
clause.Expression = orderBy clause.Expression = orderBy

View File

@ -15,16 +15,16 @@ func TestOrderBy(t *testing.T) {
}{ }{
{ {
[]clause.Interface{clause.Select{}, clause.From{}, clause.OrderBy{ []clause.Interface{clause.Select{}, clause.From{}, clause.OrderBy{
Columns: []clause.OrderByColumn{{Column: clause.PrimaryColumn, Desc: true}}, Exprs: []clause.Expression{clause.OrderByColumn{Column: clause.PrimaryColumn, Desc: true}},
}}, }},
"SELECT * FROM `users` ORDER BY `users`.`id` DESC", nil, "SELECT * FROM `users` ORDER BY `users`.`id` DESC", nil,
}, },
{ {
[]clause.Interface{ []clause.Interface{
clause.Select{}, clause.From{}, clause.OrderBy{ clause.Select{}, clause.From{}, clause.OrderBy{
Columns: []clause.OrderByColumn{{Column: clause.PrimaryColumn, Desc: true}}, Exprs: []clause.Expression{clause.OrderByColumn{Column: clause.PrimaryColumn, Desc: true}},
}, clause.OrderBy{ }, clause.OrderBy{
Columns: []clause.OrderByColumn{{Column: clause.Column{Name: "name"}}}, Exprs: []clause.Expression{clause.OrderByColumn{Column: clause.Column{Name: "name"}}},
}, },
}, },
"SELECT * FROM `users` ORDER BY `users`.`id` DESC,`name`", nil, "SELECT * FROM `users` ORDER BY `users`.`id` DESC,`name`", nil,
@ -32,9 +32,9 @@ func TestOrderBy(t *testing.T) {
{ {
[]clause.Interface{ []clause.Interface{
clause.Select{}, clause.From{}, clause.OrderBy{ clause.Select{}, clause.From{}, clause.OrderBy{
Columns: []clause.OrderByColumn{{Column: clause.PrimaryColumn, Desc: true}}, Exprs: []clause.Expression{clause.OrderByColumn{Column: clause.PrimaryColumn, Desc: true}},
}, clause.OrderBy{ }, clause.OrderBy{
Columns: []clause.OrderByColumn{{Column: clause.Column{Name: "name"}, Reorder: true}}, Exprs: []clause.Expression{clause.OrderByColumn{Column: clause.Column{Name: "name"}, Reorder: true}},
}, },
}, },
"SELECT * FROM `users` ORDER BY `name`", nil, "SELECT * FROM `users` ORDER BY `name`", nil,
@ -42,12 +42,24 @@ func TestOrderBy(t *testing.T) {
{ {
[]clause.Interface{ []clause.Interface{
clause.Select{}, clause.From{}, clause.OrderBy{ clause.Select{}, clause.From{}, clause.OrderBy{
Expression: clause.Expr{SQL: "FIELD(id, ?)", Vars: []interface{}{[]int{1, 2, 3}}, WithoutParentheses: true}, Exprs: []clause.Expression{clause.Expr{SQL: "FIELD(id, ?)", Vars: []interface{}{[]int{1, 2, 3}}, WithoutParentheses: true}},
}, },
}, },
"SELECT * FROM `users` ORDER BY FIELD(id, ?,?,?)", "SELECT * FROM `users` ORDER BY FIELD(id, ?,?,?)",
[]interface{}{1, 2, 3}, []interface{}{1, 2, 3},
}, },
{
[]clause.Interface{
clause.Select{}, clause.From{}, clause.OrderBy{
Exprs: []clause.Expression{
clause.Expr{SQL: "FIELD(id, ?)", Vars: []interface{}{[]int{1, 2, 3}}, WithoutParentheses: true},
clause.OrderByColumn{Column: clause.PrimaryColumn, Desc: true},
},
},
},
"SELECT * FROM `users` ORDER BY FIELD(id, ?,?,?),`users`.`id` DESC",
[]interface{}{1, 2, 3},
},
} }
for idx, result := range results { for idx, result := range results {