Initial commit
This commit is contained in:
164
helper.go
Normal file
164
helper.go
Normal file
@@ -0,0 +1,164 @@
|
||||
package mgoapi
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"git.basehosts.de/gopackage/mgocrud"
|
||||
"github.com/gin-gonic/gin"
|
||||
mgo "gopkg.in/mgo.v2"
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
)
|
||||
|
||||
func modelTypeOf(m interface{}) reflect.Type {
|
||||
return reflect.TypeOf(
|
||||
reflect.ValueOf(m).Elem().Interface(),
|
||||
)
|
||||
}
|
||||
|
||||
func newModelOf(m interface{}) interface{} {
|
||||
return reflect.New(
|
||||
modelTypeOf(m),
|
||||
).Interface()
|
||||
}
|
||||
|
||||
func string2ObjectID(id string) (objectID *bson.ObjectId, err error) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
switch x := r.(type) {
|
||||
case string:
|
||||
err = errors.New(x)
|
||||
case error:
|
||||
err = x
|
||||
default:
|
||||
err = errors.New("Unknown panic in: string2ObjectID")
|
||||
}
|
||||
}
|
||||
}()
|
||||
oID := bson.ObjectIdHex(id)
|
||||
return &oID, err
|
||||
}
|
||||
|
||||
func getStructMeta(s reflect.Type, dontRecurse map[string]bool) []map[string]interface{} {
|
||||
if s.Kind() == reflect.Ptr {
|
||||
s = s.Elem()
|
||||
}
|
||||
|
||||
numField := s.NumField()
|
||||
meta := make([]map[string]interface{}, 0, numField+3)
|
||||
|
||||
for i := 0; i < numField; i++ {
|
||||
f := s.Field(i)
|
||||
jsonTag := strings.Split(f.Tag.Get("json"), ",")
|
||||
|
||||
if jsonTag[0] != "-" {
|
||||
_type := f.Type
|
||||
|
||||
kind := f.Type.Kind()
|
||||
if kind == reflect.Ptr {
|
||||
_type = _type.Elem()
|
||||
}
|
||||
|
||||
if f.Anonymous {
|
||||
// embed directly
|
||||
embed := getStructMeta(_type, dontRecurse)
|
||||
for _, e := range embed {
|
||||
meta = append(meta, e)
|
||||
}
|
||||
} else {
|
||||
fMeta := make(map[string]interface{})
|
||||
|
||||
fName := f.Name
|
||||
if jsonTag[0] != "" {
|
||||
fName = jsonTag[0]
|
||||
}
|
||||
fMeta["name"] = fName
|
||||
|
||||
fType := _type.Name()
|
||||
if fType == "" {
|
||||
fType = _type.String()
|
||||
}
|
||||
//fType = strings.Replace(fType, "*", "", -1)
|
||||
fType = regexp.MustCompile("\\*[a-zA-Z0-9]*\\.?").ReplaceAllString(fType, "")
|
||||
fMeta["type"] = fType
|
||||
kind = _type.Kind()
|
||||
fMeta["kind"] = kind.String()
|
||||
|
||||
if vT := f.Tag.Get("validator"); vT != "" {
|
||||
fMeta["validator"] = strings.Split(vT, ",")
|
||||
}
|
||||
/*
|
||||
|
||||
if vT := f.Tag.Get("class"); vT != "" {
|
||||
fMeta["class"] = strings.Split(vT, ",")
|
||||
}
|
||||
|
||||
if lT := f.Tag.Get("label"); lT != "" {
|
||||
fMeta["label"] = lT
|
||||
}
|
||||
*/
|
||||
if vM := f.Tag.Get("meta"); vM != "" {
|
||||
m := strings.Split(vM, ";")
|
||||
for _, mP := range m {
|
||||
p := strings.Split(mP, "=")
|
||||
if len(p) > 1 {
|
||||
pp := strings.Split(p[1], ",")
|
||||
if len(pp) == 1 {
|
||||
fMeta[p[0]] = pp[0]
|
||||
} else {
|
||||
fMeta[p[0]] = pp
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if kind == reflect.Struct && !dontRecurse[fType] {
|
||||
dontRecurse[fType] = true
|
||||
fMeta[kind.String()+"Of"] = getStructMeta(_type, dontRecurse)
|
||||
} else if kind == reflect.Slice && !dontRecurse[fType] {
|
||||
sliceEl := _type.Elem()
|
||||
if sliceEl.Kind() == reflect.Ptr {
|
||||
sliceEl = sliceEl.Elem()
|
||||
}
|
||||
if sliceEl.Kind() == reflect.Struct {
|
||||
dontRecurse[fType] = true
|
||||
fMeta[kind.String()+"Of"] = getStructMeta(sliceEl, dontRecurse)
|
||||
} else {
|
||||
fMeta[kind.String()+"Of"] = sliceEl.String()
|
||||
}
|
||||
}
|
||||
|
||||
meta = append(meta, fMeta)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return meta
|
||||
}
|
||||
|
||||
func getModelMeta(m mgocrud.ModelInterface) []map[string]interface{} {
|
||||
dontRecurse := map[string]bool{
|
||||
"Time": true,
|
||||
"ObjectId": true,
|
||||
}
|
||||
modelType := reflect.ValueOf(m).Elem().Type()
|
||||
|
||||
return getStructMeta(modelType, dontRecurse)
|
||||
}
|
||||
|
||||
func getDocument(c *gin.Context, db *mgo.Database, m mgocrud.ModelInterface, selector bson.M) (mgocrud.ModelInterface, error) {
|
||||
objectID, err := string2ObjectID(c.Param("id"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
newM := newModelOf(m).(mgocrud.ModelInterface)
|
||||
newM.SetID(objectID)
|
||||
err = mgocrud.ReadDocument(db, newM, selector)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return newM, nil
|
||||
}
|
||||
Reference in New Issue
Block a user