improve write order by (#2301)
Reviewed-on: https://gitea.com/xorm/xorm/pulls/2301
This commit is contained in:
parent
96ed5584e3
commit
9988dac44d
|
@ -14,8 +14,8 @@ import (
|
||||||
"xorm.io/xorm/schemas"
|
"xorm.io/xorm/schemas"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (statement *Statement) writeDeleteOrder(w builder.Writer) error {
|
func (statement *Statement) writeDeleteOrder(w *builder.BytesWriter) error {
|
||||||
if err := statement.WriteOrderBy(w); err != nil {
|
if err := statement.writeOrderBys(w); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,85 +6,91 @@ package statements
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"xorm.io/builder"
|
"xorm.io/builder"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type orderBy struct {
|
||||||
|
orderStr interface{}
|
||||||
|
orderArgs []interface{}
|
||||||
|
direction string // ASC, DESC or "", "" means raw orderStr
|
||||||
|
}
|
||||||
|
|
||||||
func (statement *Statement) HasOrderBy() bool {
|
func (statement *Statement) HasOrderBy() bool {
|
||||||
return statement.orderStr != ""
|
return len(statement.orderBy) > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// ResetOrderBy reset ordery conditions
|
// ResetOrderBy reset ordery conditions
|
||||||
func (statement *Statement) ResetOrderBy() {
|
func (statement *Statement) ResetOrderBy() {
|
||||||
statement.orderStr = ""
|
statement.orderBy = []orderBy{}
|
||||||
statement.orderArgs = nil
|
}
|
||||||
|
|
||||||
|
func (statement *Statement) writeOrderBy(w *builder.BytesWriter, orderBy orderBy) error {
|
||||||
|
switch t := orderBy.orderStr.(type) {
|
||||||
|
case (*builder.Expression):
|
||||||
|
if _, err := fmt.Fprint(w.Builder, statement.dialect.Quoter().Replace(t.Content())); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
w.Append(t.Args()...)
|
||||||
|
return nil
|
||||||
|
case string:
|
||||||
|
if orderBy.direction == "" {
|
||||||
|
if _, err := fmt.Fprint(w.Builder, statement.dialect.Quoter().Replace(t)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
w.Append(orderBy.orderArgs...)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if err := statement.dialect.Quoter().QuoteTo(w.Builder, t); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err := fmt.Fprint(w, " ", orderBy.direction)
|
||||||
|
return err
|
||||||
|
default:
|
||||||
|
return ErrUnSupportedSQLType
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteOrderBy write order by to writer
|
// WriteOrderBy write order by to writer
|
||||||
func (statement *Statement) WriteOrderBy(w builder.Writer) error {
|
func (statement *Statement) writeOrderBys(w *builder.BytesWriter) error {
|
||||||
if len(statement.orderStr) > 0 {
|
if len(statement.orderBy) == 0 {
|
||||||
if _, err := fmt.Fprint(w, " ORDER BY ", statement.orderStr); err != nil {
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := fmt.Fprint(w, " ORDER BY "); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
w.Append(statement.orderArgs...)
|
for i, ob := range statement.orderBy {
|
||||||
|
if err := statement.writeOrderBy(w, ob); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if i < len(statement.orderBy)-1 {
|
||||||
|
if _, err := fmt.Fprint(w, ", "); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// OrderBy generate "Order By order" statement
|
// OrderBy generate "Order By order" statement
|
||||||
func (statement *Statement) OrderBy(order interface{}, args ...interface{}) *Statement {
|
func (statement *Statement) OrderBy(order interface{}, args ...interface{}) *Statement {
|
||||||
if len(statement.orderStr) > 0 {
|
statement.orderBy = append(statement.orderBy, orderBy{order, args, ""})
|
||||||
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...)
|
|
||||||
}
|
|
||||||
return statement
|
return statement
|
||||||
}
|
}
|
||||||
|
|
||||||
// Desc generate `ORDER BY xx DESC`
|
// Desc generate `ORDER BY xx DESC`
|
||||||
func (statement *Statement) Desc(colNames ...string) *Statement {
|
func (statement *Statement) Desc(colNames ...string) *Statement {
|
||||||
var buf strings.Builder
|
for _, colName := range colNames {
|
||||||
if len(statement.orderStr) > 0 {
|
statement.orderBy = append(statement.orderBy, orderBy{colName, nil, "DESC"})
|
||||||
fmt.Fprint(&buf, statement.orderStr, ", ")
|
|
||||||
}
|
}
|
||||||
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
|
return statement
|
||||||
}
|
}
|
||||||
|
|
||||||
// Asc provide asc order by query condition, the input parameters are columns.
|
// Asc provide asc order by query condition, the input parameters are columns.
|
||||||
func (statement *Statement) Asc(colNames ...string) *Statement {
|
func (statement *Statement) Asc(colNames ...string) *Statement {
|
||||||
var buf strings.Builder
|
for _, colName := range colNames {
|
||||||
if len(statement.orderStr) > 0 {
|
statement.orderBy = append(statement.orderBy, orderBy{colName, nil, "ASC"})
|
||||||
fmt.Fprint(&buf, statement.orderStr, ", ")
|
|
||||||
}
|
}
|
||||||
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
|
return statement
|
||||||
}
|
}
|
||||||
|
|
|
@ -320,7 +320,7 @@ func (statement *Statement) writeMssqlPaginationCond(w *builder.BytesWriter) err
|
||||||
if err := statement.writeWhere(subWriter); err != nil {
|
if err := statement.writeWhere(subWriter); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := statement.WriteOrderBy(subWriter); err != nil {
|
if err := statement.writeOrderBys(subWriter); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := statement.writeGroupBy(subWriter); err != nil {
|
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 {
|
if err := statement.writeHaving(buf); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := statement.WriteOrderBy(buf); err != nil {
|
if err := statement.writeOrderBys(buf); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,8 +50,7 @@ type Statement struct {
|
||||||
Start int
|
Start int
|
||||||
LimitN *int
|
LimitN *int
|
||||||
idParam schemas.PK
|
idParam schemas.PK
|
||||||
orderStr string
|
orderBy []orderBy
|
||||||
orderArgs []interface{}
|
|
||||||
joins []join
|
joins []join
|
||||||
GroupByStr string
|
GroupByStr string
|
||||||
HavingStr string
|
HavingStr string
|
||||||
|
@ -163,15 +162,15 @@ func (statement *Statement) Reset() {
|
||||||
|
|
||||||
// SQL adds raw sql statement
|
// SQL adds raw sql statement
|
||||||
func (statement *Statement) SQL(query interface{}, args ...interface{}) *Statement {
|
func (statement *Statement) SQL(query interface{}, args ...interface{}) *Statement {
|
||||||
switch query.(type) {
|
switch t := query.(type) {
|
||||||
case (*builder.Builder):
|
case (*builder.Builder):
|
||||||
var err error
|
var err error
|
||||||
statement.RawSQL, statement.RawParams, err = query.(*builder.Builder).ToSQL()
|
statement.RawSQL, statement.RawParams, err = t.ToSQL()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
statement.LastError = err
|
statement.LastError = err
|
||||||
}
|
}
|
||||||
case string:
|
case string:
|
||||||
statement.RawSQL = query.(string)
|
statement.RawSQL = t
|
||||||
statement.RawParams = args
|
statement.RawParams = args
|
||||||
default:
|
default:
|
||||||
statement.LastError = ErrUnSupportedSQLType
|
statement.LastError = ErrUnSupportedSQLType
|
||||||
|
|
|
@ -319,7 +319,7 @@ func (statement *Statement) WriteUpdate(updateWriter *builder.BytesWriter, cond
|
||||||
if err := cond.WriteTo(statement.QuoteReplacer(whereWriter)); err != nil {
|
if err := cond.WriteTo(statement.QuoteReplacer(whereWriter)); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := statement.WriteOrderBy(whereWriter); err != nil {
|
if err := statement.writeOrderBys(whereWriter); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue