rest/condition.go

152 lines
4.3 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package rest
import (
"context"
"encoding/json"
"net/http"
"strings"
"git.nobla.cn/golang/kos/util/arrays"
"git.nobla.cn/golang/rest/types"
)
func findCondition(schema *types.Schema, conditions []*types.Condition) *types.Condition {
for _, cond := range conditions {
if cond.Column == schema.Column {
return cond
}
}
return nil
}
func BuildConditions(ctx context.Context, r *http.Request, query *Query, schemas []*types.Schema) (err error) {
var (
ok bool
skip bool
formValue string
activeQuery ActiveQuery
)
if activeQuery, ok = query.Model().(ActiveQuery); ok {
if err = activeQuery.BeforeQuery(ctx, query); err != nil {
return
}
}
if arrays.Exists(r.Method, []string{http.MethodPut, http.MethodPost}) {
conditions := make([]*types.Condition, 0)
if err = json.NewDecoder(r.Body).Decode(&conditions); err != nil {
return
}
for _, row := range schemas {
if row.Native == 0 {
continue
}
cond := findCondition(row, conditions)
if cond == nil {
continue
}
switch row.Format {
case types.FormatInteger, types.FormatFloat, types.FormatTimestamp, types.FormatDatetime, types.FormatDate, types.FormatTime:
switch cond.Expr {
case types.OperatorBetween:
if len(cond.Values) == 2 {
query.AndFilterWhere(newCondition(row.Column, cond.Values[0]).WithExpr(">="))
query.AndFilterWhere(newCondition(row.Column, cond.Values[1]).WithExpr("<="))
}
case types.OperatorGreaterThan:
query.AndFilterWhere(newCondition(row.Column, cond.Value).WithExpr(">"))
case types.OperatorGreaterEqual:
query.AndFilterWhere(newCondition(row.Column, cond.Value).WithExpr(">="))
case types.OperatorLessThan:
query.AndFilterWhere(newCondition(row.Column, cond.Value).WithExpr("<"))
case types.OperatorLessEqual:
query.AndFilterWhere(newCondition(row.Column, cond.Value).WithExpr("<="))
default:
query.AndFilterWhere(newCondition(row.Column, cond.Value))
}
default:
switch cond.Expr {
case types.OperatorLike:
query.AndFilterWhere(newCondition(row.Column, cond.Value).WithExpr("LIKE"))
default:
query.AndFilterWhere(newCondition(row.Column, cond.Value))
}
}
}
} else {
qs := r.URL.Query()
for _, row := range schemas {
skip = false
if skip {
continue
}
if row.Native == 0 {
continue
}
//如果是多选的话直接使用IN操作
columnName := row.Column + "[]"
if qs.Has(columnName) && len(qs[columnName]) > 1 {
query.AndFilterWhere(newConditionWithOperator("IN", row.Column, qs[columnName]))
continue
}
formValue = qs.Get(row.Column)
switch row.Format {
case types.FormatString, types.FormatText:
if row.Attribute.Match == types.MatchExactly {
query.AndFilterWhere(newCondition(row.Column, formValue))
} else {
query.AndFilterWhere(newCondition(row.Column, formValue).WithExpr("LIKE"))
}
case types.FormatTime, types.FormatDate, types.FormatDatetime, types.FormatTimestamp:
var sep string
seps := []byte{',', '/'}
for _, s := range seps {
if strings.IndexByte(formValue, s) > -1 {
sep = string(s)
}
}
if ss := strings.Split(formValue, sep); len(ss) == 2 {
query.AndFilterWhere(
newCondition(row.Column, strings.TrimSpace(ss[0])).WithExpr(">="),
newCondition(row.Column, strings.TrimSpace(ss[1])).WithExpr("<="),
)
} else {
query.AndFilterWhere(newCondition(row.Column, formValue))
}
case types.FormatInteger, types.FormatFloat:
query.AndFilterWhere(newCondition(row.Column, formValue))
default:
if row.Type == types.TypeString {
if row.Attribute.Match == types.MatchExactly {
query.AndFilterWhere(newCondition(row.Column, formValue))
} else {
query.AndFilterWhere(newCondition(row.Column, formValue).WithExpr("LIKE"))
}
} else {
query.AndFilterWhere(newCondition(row.Column, formValue))
}
}
}
}
sortPar := r.FormValue("sort")
if sortPar != "" {
sorts := strings.Split(sortPar, ",")
for _, s := range sorts {
if s[0] == '-' {
query.OrderBy(s[1:], "DESC")
} else {
if s[0] == '+' {
query.OrderBy(s[1:], "ASC")
} else {
query.OrderBy(s, "ASC")
}
}
}
}
if activeQuery, ok = query.Model().(ActiveQuery); ok {
if err = activeQuery.AfterQuery(ctx, query); err != nil {
return
}
}
return
}