gorm/utils_private.go

133 lines
3.3 KiB
Go
Raw Normal View History

2014-07-25 12:51:54 +04:00
package gorm
import (
2016-01-15 10:53:53 +03:00
"database/sql/driver"
2014-07-25 12:51:54 +04:00
"fmt"
"reflect"
"regexp"
"runtime"
"strings"
2014-07-25 12:51:54 +04:00
)
func fileWithLineNum() string {
2014-09-02 15:03:01 +04:00
for i := 2; i < 15; i++ {
2014-07-25 12:51:54 +04:00
_, file, line, ok := runtime.Caller(i)
if ok && (!regexp.MustCompile(`jinzhu/gorm/.*.go`).MatchString(file) || regexp.MustCompile(`jinzhu/gorm/.*test.go`).MatchString(file)) {
2015-02-17 17:55:14 +03:00
return fmt.Sprintf("%v:%v", file, line)
2014-07-25 12:51:54 +04:00
}
}
return ""
}
func isBlank(value reflect.Value) bool {
return reflect.DeepEqual(value.Interface(), reflect.Zero(value.Type()).Interface())
}
func toSearchableMap(attrs ...interface{}) (result interface{}) {
if len(attrs) > 1 {
if str, ok := attrs[0].(string); ok {
result = map[string]interface{}{str: attrs[1]}
}
} else if len(attrs) == 1 {
if attr, ok := attrs[0].(map[string]interface{}); ok {
result = attr
}
if attr, ok := attrs[0].(interface{}); ok {
result = attr
}
}
return
}
func convertInterfaceToMap(values interface{}) map[string]interface{} {
attrs := map[string]interface{}{}
switch value := values.(type) {
case map[string]interface{}:
for k, v := range value {
2015-02-18 05:19:34 +03:00
attrs[ToDBName(k)] = v
2014-07-25 12:51:54 +04:00
}
case []interface{}:
for _, v := range value {
for key, value := range convertInterfaceToMap(v) {
attrs[key] = value
}
}
case interface{}:
reflectValue := reflect.ValueOf(values)
switch reflectValue.Kind() {
case reflect.Map:
for _, key := range reflectValue.MapKeys() {
2015-02-18 05:19:34 +03:00
attrs[ToDBName(key.Interface().(string))] = reflectValue.MapIndex(key).Interface()
2014-07-25 12:51:54 +04:00
}
default:
scope := Scope{Value: values}
for _, field := range scope.Fields() {
if !field.IsBlank && !field.IsIgnored {
2014-09-02 15:03:01 +04:00
attrs[field.DBName] = field.Field.Interface()
2014-07-25 12:51:54 +04:00
}
}
}
}
return attrs
}
2015-08-16 10:35:58 +03:00
2016-01-15 10:53:53 +03:00
func equalAsString(a interface{}, b interface{}) bool {
return toString(a) == toString(b)
}
func toString(str interface{}) string {
if values, ok := str.([]interface{}); ok {
var results []string
for _, value := range values {
results = append(results, toString(value))
}
return strings.Join(results, "_")
} else if bytes, ok := str.([]byte); ok {
return string(bytes)
2016-01-16 06:37:16 +03:00
} else if reflectValue := reflect.Indirect(reflect.ValueOf(str)); reflectValue.IsValid() {
return fmt.Sprintf("%v", reflectValue.Interface())
}
2016-01-16 06:37:16 +03:00
return ""
2015-08-16 10:35:58 +03:00
}
2016-01-15 10:53:53 +03:00
func makeSlice(elemType reflect.Type) interface{} {
if elemType.Kind() == reflect.Slice {
elemType = elemType.Elem()
}
sliceType := reflect.SliceOf(elemType)
slice := reflect.New(sliceType)
slice.Elem().Set(reflect.MakeSlice(sliceType, 0, 0))
return slice.Interface()
}
2015-08-16 10:35:58 +03:00
func strInSlice(a string, list []string) bool {
for _, b := range list {
if b == a {
return true
}
}
return false
}
2016-01-15 10:53:53 +03:00
// getValueFromFields return given fields's value
func getValueFromFields(value reflect.Value, fieldNames []string) (results []interface{}) {
// If value is a nil pointer, Indirect returns a zero Value!
// Therefor we need to check for a zero value,
// as FieldByName could panic
if indirectValue := reflect.Indirect(value); indirectValue.IsValid() {
for _, fieldName := range fieldNames {
if fieldValue := indirectValue.FieldByName(fieldName); fieldValue.IsValid() {
result := fieldValue.Interface()
if r, ok := result.(driver.Valuer); ok {
result, _ = r.Value()
}
results = append(results, result)
}
}
}
return
}