package orm import ( "reflect" "strings" ) // fieldType is the type we expect type fieldType uint8 // Relation or Column defines type of mapping const ( Relation fieldType = iota << 1 // fieldType = (fieldType)(reflect.Struct) Column ) // field holds necessary data on specific field type field struct { sf reflect.StructField t reflect.Type v reflect.Value ft fieldType } func (f *field) Make() reflect.Value { o := reflect.New(f.MakeType()).Elem() switch f.MakeType().Kind() { case reflect.Map: o.Set(reflect.MakeMap(o.Type())) } return o } func (f *field) MakeType() reflect.Type { return f.sf.Type } // getFieldName returns the field name within the struct, // e.g struct { fieldName fieldType }{} func (f *field) getFieldName() string { return f.sf.Name } // getFieldType returns the field type within the struct, // e.g struct { fieldName fieldType }{} func (f *field) getFieldType() string { return f.t.Name() } // getType returns the type; Relation or Column func (f *field) getType() fieldType { return f.ft //(fieldType)(f.t.Kind()) } // getKind returns the actual reflect.Kind func (f *field) getKind() reflect.Kind { return f.t.Kind() } // getTag returns tags on this field, can be // db:"siglevalue" (bool type?) or db:"key:value" func (f *field) getTag(key string) (string, bool) { if tag := f.sf.Tag.Get(Prefix); len(tag) != 0 { tags := strings.Split(tag, ";") for _, tag := range tags { kv := strings.Split(tag, ":") kv[0] = strings.Trim(kv[0], " ") if len(kv) == 1 && kv[0] == key { return kv[0], true } if len(kv) == 2 && kv[0] == key { kv[1] = strings.Trim(kv[1], " ") return kv[1], true } } } return "", false } // hasTags checks if it has all keys func (f *field) hasTags(keys ...string) bool { match := 0 for _, key := range keys { if f.hasTag(key) { match += 1 } } return len(keys) == match } // hasTags checks if it has key func (f *field) hasTag(key string) bool { if _, ok := f.getTag(key); ok { return true } return false }