diff --git a/internal/statements/delete.go b/internal/statements/delete.go index fccebbed..ee3770e0 100644 --- a/internal/statements/delete.go +++ b/internal/statements/delete.go @@ -15,7 +15,7 @@ import ( ) func (statement *Statement) writeDeleteOrder(w builder.Writer) error { - if err := statement.WriteOrderBy(w); err != nil { + if err := statement.writeOrderBys(w); err != nil { return err } diff --git a/internal/statements/order_by.go b/internal/statements/order_by.go index b7eeeb87..237f4a3d 100644 --- a/internal/statements/order_by.go +++ b/internal/statements/order_by.go @@ -6,85 +6,78 @@ package statements import ( "fmt" - "strings" "xorm.io/builder" ) func (statement *Statement) HasOrderBy() bool { - return statement.orderStr != "" + return len(statement.orderBy) > 0 } // ResetOrderBy reset ordery conditions func (statement *Statement) ResetOrderBy() { - statement.orderStr = "" - statement.orderArgs = nil + statement.orderBy = []orderBy{} +} + +func (statement *Statement) writeOrderBy(w builder.Writer, orderBy orderBy) error { + switch t := orderBy.orderStr.(type) { + case (*builder.Expression): + if _, err := fmt.Fprint(w, statement.ReplaceQuote(t.Content())); err != nil { + return err + } + w.Append(t.Args()...) + return nil + case string: + if _, err := fmt.Fprint(w, t); err != nil { + return err + } + w.Append(orderBy.orderArgs...) + return nil + default: + return ErrUnSupportedSQLType + } } // WriteOrderBy write order by to writer -func (statement *Statement) WriteOrderBy(w builder.Writer) error { - if len(statement.orderStr) > 0 { - if _, err := fmt.Fprint(w, " ORDER BY ", statement.orderStr); err != nil { +func (statement *Statement) writeOrderBys(w builder.Writer) error { + if len(statement.orderBy) == 0 { + return nil + } + + if _, err := fmt.Fprint(w, " ORDER BY "); err != nil { + return err + } + for i, ob := range statement.orderBy { + if err := statement.writeOrderBy(w, ob); err != nil { return err } - w.Append(statement.orderArgs...) + if i < len(statement.orderBy)-1 { + if _, err := fmt.Fprint(w, ", "); err != nil { + return err + } + } } return nil } // OrderBy generate "Order By order" statement func (statement *Statement) OrderBy(order interface{}, args ...interface{}) *Statement { - if len(statement.orderStr) > 0 { - statement.orderStr += ", " - } - var rawOrder string - switch t := order.(type) { - case (*builder.Expression): - rawOrder = t.Content() - args = t.Args() - case string: - rawOrder = t - default: - statement.LastError = ErrUnSupportedSQLType - return statement - } - statement.orderStr += statement.ReplaceQuote(rawOrder) - if len(args) > 0 { - statement.orderArgs = append(statement.orderArgs, args...) - } + statement.orderBy = append(statement.orderBy, orderBy{order, args}) return statement } // Desc generate `ORDER BY xx DESC` func (statement *Statement) Desc(colNames ...string) *Statement { - var buf strings.Builder - if len(statement.orderStr) > 0 { - fmt.Fprint(&buf, statement.orderStr, ", ") + for _, colName := range colNames { + statement.orderBy = append(statement.orderBy, orderBy{colName + " DESC", nil}) } - for i, col := range colNames { - if i > 0 { - fmt.Fprint(&buf, ", ") - } - _ = statement.dialect.Quoter().QuoteTo(&buf, col) - fmt.Fprint(&buf, " DESC") - } - statement.orderStr = buf.String() return statement } // Asc provide asc order by query condition, the input parameters are columns. func (statement *Statement) Asc(colNames ...string) *Statement { - var buf strings.Builder - if len(statement.orderStr) > 0 { - fmt.Fprint(&buf, statement.orderStr, ", ") + for _, colName := range colNames { + statement.orderBy = append(statement.orderBy, orderBy{colName + " ASC", nil}) } - for i, col := range colNames { - if i > 0 { - fmt.Fprint(&buf, ", ") - } - _ = statement.dialect.Quoter().QuoteTo(&buf, col) - fmt.Fprint(&buf, " ASC") - } - statement.orderStr = buf.String() return statement } diff --git a/internal/statements/query.go b/internal/statements/query.go index 2e38f0fe..63e079e7 100644 --- a/internal/statements/query.go +++ b/internal/statements/query.go @@ -320,7 +320,7 @@ func (statement *Statement) writeMssqlPaginationCond(w *builder.BytesWriter) err if err := statement.writeWhere(subWriter); err != nil { return err } - if err := statement.WriteOrderBy(subWriter); err != nil { + if err := statement.writeOrderBys(subWriter); err != nil { return err } if err := statement.writeGroupBy(subWriter); err != nil { @@ -375,7 +375,7 @@ func (statement *Statement) writeSelect(buf *builder.BytesWriter, columnStr stri if err := statement.writeHaving(buf); err != nil { return err } - if err := statement.WriteOrderBy(buf); err != nil { + if err := statement.writeOrderBys(buf); err != nil { return err } diff --git a/internal/statements/statement.go b/internal/statements/statement.go index afc38a2e..4d0d3761 100644 --- a/internal/statements/statement.go +++ b/internal/statements/statement.go @@ -41,6 +41,11 @@ type join struct { args []interface{} } +type orderBy struct { + orderStr interface{} + orderArgs []interface{} +} + // Statement save all the sql info for executing SQL type Statement struct { RefTable *schemas.Table @@ -50,8 +55,7 @@ type Statement struct { Start int LimitN *int idParam schemas.PK - orderStr string - orderArgs []interface{} + orderBy []orderBy joins []join GroupByStr string HavingStr string diff --git a/internal/statements/update.go b/internal/statements/update.go index 16ab5676..f0914b0b 100644 --- a/internal/statements/update.go +++ b/internal/statements/update.go @@ -319,7 +319,7 @@ func (statement *Statement) WriteUpdate(updateWriter *builder.BytesWriter, cond if err := cond.WriteTo(statement.QuoteReplacer(whereWriter)); err != nil { return err } - if err := statement.WriteOrderBy(whereWriter); err != nil { + if err := statement.writeOrderBys(whereWriter); err != nil { return err }