|
|
|
package builderx
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"reflect"
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
"github.com/go-xorm/builder"
|
|
|
|
)
|
|
|
|
|
|
|
|
const dbTag = "db"
|
|
|
|
|
|
|
|
// NewEq wraps builder.Eq.
|
|
|
|
func NewEq(in interface{}) builder.Eq {
|
|
|
|
return builder.Eq(ToMap(in))
|
|
|
|
}
|
|
|
|
|
|
|
|
// NewGt wraps builder.Gt.
|
|
|
|
func NewGt(in interface{}) builder.Gt {
|
|
|
|
return builder.Gt(ToMap(in))
|
|
|
|
}
|
|
|
|
|
|
|
|
// ToMap converts interface into map.
|
|
|
|
func ToMap(in interface{}) map[string]interface{} {
|
|
|
|
out := make(map[string]interface{})
|
|
|
|
v := reflect.ValueOf(in)
|
|
|
|
if v.Kind() == reflect.Ptr {
|
|
|
|
v = v.Elem()
|
|
|
|
}
|
|
|
|
|
|
|
|
// we only accept structs
|
|
|
|
if v.Kind() != reflect.Struct {
|
|
|
|
panic(fmt.Errorf("ToMap only accepts structs; got %T", v))
|
|
|
|
}
|
|
|
|
|
|
|
|
typ := v.Type()
|
|
|
|
for i := 0; i < v.NumField(); i++ {
|
|
|
|
// gets us a StructField
|
|
|
|
fi := typ.Field(i)
|
|
|
|
if tagv := fi.Tag.Get(dbTag); tagv != "" {
|
|
|
|
// set key of map to value in struct field
|
|
|
|
val := v.Field(i)
|
|
|
|
zero := reflect.Zero(val.Type()).Interface()
|
|
|
|
current := val.Interface()
|
|
|
|
|
|
|
|
if reflect.DeepEqual(current, zero) {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
out[tagv] = current
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return out
|
|
|
|
}
|
|
|
|
|
|
|
|
// FieldNames returns field names from given in.
|
|
|
|
// deprecated: use RawFieldNames instead automatically while model generating after goctl version v1.1.0
|
|
|
|
func FieldNames(in interface{}) []string {
|
|
|
|
out := make([]string, 0)
|
|
|
|
v := reflect.ValueOf(in)
|
|
|
|
if v.Kind() == reflect.Ptr {
|
|
|
|
v = v.Elem()
|
|
|
|
}
|
|
|
|
|
|
|
|
// we only accept structs
|
|
|
|
if v.Kind() != reflect.Struct {
|
|
|
|
panic(fmt.Errorf("ToMap only accepts structs; got %T", v))
|
|
|
|
}
|
|
|
|
|
|
|
|
typ := v.Type()
|
|
|
|
for i := 0; i < v.NumField(); i++ {
|
|
|
|
// gets us a StructField
|
|
|
|
fi := typ.Field(i)
|
|
|
|
if tagv := fi.Tag.Get(dbTag); tagv != "" {
|
|
|
|
out = append(out, tagv)
|
|
|
|
} else {
|
|
|
|
out = append(out, fi.Name)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return out
|
|
|
|
}
|
|
|
|
|
|
|
|
// RawFieldNames converts golang struct field into slice string.
|
|
|
|
func RawFieldNames(in interface{}, postgresSql ...bool) []string {
|
|
|
|
out := make([]string, 0)
|
|
|
|
v := reflect.ValueOf(in)
|
|
|
|
if v.Kind() == reflect.Ptr {
|
|
|
|
v = v.Elem()
|
|
|
|
}
|
|
|
|
|
|
|
|
var pg bool
|
|
|
|
if len(postgresSql) > 0 {
|
|
|
|
pg = postgresSql[0]
|
|
|
|
}
|
|
|
|
|
|
|
|
// we only accept structs
|
|
|
|
if v.Kind() != reflect.Struct {
|
|
|
|
panic(fmt.Errorf("ToMap only accepts structs; got %T", v))
|
|
|
|
}
|
|
|
|
|
|
|
|
typ := v.Type()
|
|
|
|
for i := 0; i < v.NumField(); i++ {
|
|
|
|
// gets us a StructField
|
|
|
|
fi := typ.Field(i)
|
|
|
|
if tagv := fi.Tag.Get(dbTag); tagv != "" {
|
|
|
|
if pg {
|
|
|
|
out = append(out, tagv)
|
|
|
|
} else {
|
|
|
|
out = append(out, fmt.Sprintf("`%s`", tagv))
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if pg {
|
|
|
|
out = append(out, fi.Name)
|
|
|
|
} else {
|
|
|
|
out = append(out, fmt.Sprintf("`%s`", fi.Name))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return out
|
|
|
|
}
|
|
|
|
|
|
|
|
// PostgreSqlJoin concatenates the given elements into a string.
|
|
|
|
func PostgreSqlJoin(elems []string) string {
|
|
|
|
b := new(strings.Builder)
|
|
|
|
for index, e := range elems {
|
|
|
|
b.WriteString(fmt.Sprintf("%s = $%d, ", e, index+2))
|
|
|
|
}
|
|
|
|
|
|
|
|
if b.Len() == 0 {
|
|
|
|
return b.String()
|
|
|
|
}
|
|
|
|
|
|
|
|
return b.String()[0 : b.Len()-2]
|
|
|
|
}
|