145 lines
4.1 KiB
Go
145 lines
4.1 KiB
Go
|
package rest
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"encoding/json"
|
||
|
"git.nobla.cn/golang/kos/util/arrays"
|
||
|
"git.nobla.cn/golang/rest/types"
|
||
|
"net/http"
|
||
|
"strings"
|
||
|
)
|
||
|
|
||
|
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
|
||
|
}
|
||
|
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
|
||
|
}
|