84 lines
2.3 KiB
Go
84 lines
2.3 KiB
Go
package exporter
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"strings"
|
|
)
|
|
|
|
type BuildRequest struct {
|
|
MainTable string
|
|
Fields []string
|
|
Filters map[string]interface{}
|
|
}
|
|
|
|
func BuildSQL(req BuildRequest, whitelist map[string]bool) (string, []interface{}, error) {
|
|
if req.MainTable != "order" {
|
|
return "", nil, errors.New("unsupported main table")
|
|
}
|
|
cols := []string{}
|
|
for _, f := range req.Fields {
|
|
if !whitelist["order."+f] {
|
|
return "", nil, errors.New("field not allowed")
|
|
}
|
|
if f == "key" || req.MainTable == "order" {
|
|
cols = append(cols, "`order`."+escape(f))
|
|
}
|
|
}
|
|
if len(cols) == 0 {
|
|
return "", nil, errors.New("no fields")
|
|
}
|
|
sb := strings.Builder{}
|
|
sb.WriteString("SELECT ")
|
|
sb.WriteString(strings.Join(cols, ","))
|
|
sb.WriteString(" FROM `order`")
|
|
args := []interface{}{}
|
|
where := []string{}
|
|
if v, ok := req.Filters["creator_in"]; ok {
|
|
ids := []interface{}{}
|
|
switch t := v.(type) {
|
|
case []interface{}:
|
|
ids = t
|
|
case []int:
|
|
for _, x := range t {
|
|
ids = append(ids, x)
|
|
}
|
|
case []string:
|
|
for _, x := range t {
|
|
ids = append(ids, x)
|
|
}
|
|
}
|
|
if len(ids) == 0 {
|
|
return "", nil, errors.New("creator_in required")
|
|
}
|
|
ph := strings.Repeat("?,", len(ids))
|
|
ph = strings.TrimSuffix(ph, ",")
|
|
where = append(where, "`order`.creator IN ("+ph+")")
|
|
args = append(args, ids...)
|
|
} else {
|
|
return "", nil, errors.New("creator_in required")
|
|
}
|
|
if v, ok := req.Filters["create_time_between"]; ok {
|
|
var arr []interface{}
|
|
b, _ := json.Marshal(v)
|
|
json.Unmarshal(b, &arr)
|
|
if len(arr) != 2 {
|
|
return "", nil, errors.New("create_time_between requires 2 values")
|
|
}
|
|
where = append(where, "`order`.create_time BETWEEN ? AND ?")
|
|
args = append(args, arr[0], arr[1])
|
|
}
|
|
if len(where) > 0 {
|
|
sb.WriteString(" WHERE ")
|
|
sb.WriteString(strings.Join(where, " AND "))
|
|
}
|
|
return sb.String(), args, nil
|
|
}
|
|
|
|
func escape(s string) string {
|
|
if s == "key" {
|
|
return "`key`"
|
|
}
|
|
return s
|
|
}
|