169 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			169 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package utils
 | |
| 
 | |
| import (
 | |
| 	"database/sql/driver"
 | |
| 	"fmt"
 | |
| 	"path/filepath"
 | |
| 	"reflect"
 | |
| 	"runtime"
 | |
| 	"strconv"
 | |
| 	"strings"
 | |
| 	"unicode"
 | |
| )
 | |
| 
 | |
| var gormSourceDir string
 | |
| 
 | |
| func init() {
 | |
| 	_, file, _, _ := runtime.Caller(0)
 | |
| 	// compatible solution to get gorm source directory with various operating systems
 | |
| 	gormSourceDir = sourceDir(file)
 | |
| }
 | |
| 
 | |
| func sourceDir(file string) string {
 | |
| 	dir := filepath.Dir(file)
 | |
| 	dir = filepath.Dir(dir)
 | |
| 
 | |
| 	s := filepath.Dir(dir)
 | |
| 	if filepath.Base(s) != "gorm.io" {
 | |
| 		s = dir
 | |
| 	}
 | |
| 	return filepath.ToSlash(s) + "/"
 | |
| }
 | |
| 
 | |
| // FileWithLineNum return the file name and line number of the current file
 | |
| func FileWithLineNum() string {
 | |
| 	pcs := [13]uintptr{}
 | |
| 	// the third caller usually from gorm internal
 | |
| 	len := runtime.Callers(3, pcs[:])
 | |
| 	frames := runtime.CallersFrames(pcs[:len])
 | |
| 	for i := 0; i < len; i++ {
 | |
| 		// second return value is "more", not "ok"
 | |
| 		frame, _ := frames.Next()
 | |
| 		if (!strings.HasPrefix(frame.File, gormSourceDir) ||
 | |
| 			strings.HasSuffix(frame.File, "_test.go")) && !strings.HasSuffix(frame.File, ".gen.go") {
 | |
| 			return string(strconv.AppendInt(append([]byte(frame.File), ':'), int64(frame.Line), 10))
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return ""
 | |
| }
 | |
| 
 | |
| func IsValidDBNameChar(c rune) bool {
 | |
| 	return !unicode.IsLetter(c) && !unicode.IsNumber(c) && c != '.' && c != '*' && c != '_' && c != '$' && c != '@'
 | |
| }
 | |
| 
 | |
| // CheckTruth check string true or not
 | |
| func CheckTruth(vals ...string) bool {
 | |
| 	for _, val := range vals {
 | |
| 		if val != "" && !strings.EqualFold(val, "false") {
 | |
| 			return true
 | |
| 		}
 | |
| 	}
 | |
| 	return false
 | |
| }
 | |
| 
 | |
| func ToStringKey(values ...interface{}) string {
 | |
| 	results := make([]string, len(values))
 | |
| 
 | |
| 	for idx, value := range values {
 | |
| 		if valuer, ok := value.(driver.Valuer); ok {
 | |
| 			value, _ = valuer.Value()
 | |
| 		}
 | |
| 
 | |
| 		switch v := value.(type) {
 | |
| 		case string:
 | |
| 			results[idx] = v
 | |
| 		case []byte:
 | |
| 			results[idx] = string(v)
 | |
| 		case uint:
 | |
| 			results[idx] = strconv.FormatUint(uint64(v), 10)
 | |
| 		default:
 | |
| 			results[idx] = "nil"
 | |
| 			vv := reflect.ValueOf(v)
 | |
| 			if vv.IsValid() && !vv.IsZero() {
 | |
| 				results[idx] = fmt.Sprint(reflect.Indirect(vv).Interface())
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return strings.Join(results, "_")
 | |
| }
 | |
| 
 | |
| func Contains(elems []string, elem string) bool {
 | |
| 	for _, e := range elems {
 | |
| 		if elem == e {
 | |
| 			return true
 | |
| 		}
 | |
| 	}
 | |
| 	return false
 | |
| }
 | |
| 
 | |
| func AssertEqual(x, y interface{}) bool {
 | |
| 	if reflect.DeepEqual(x, y) {
 | |
| 		return true
 | |
| 	}
 | |
| 	if x == nil || y == nil {
 | |
| 		return false
 | |
| 	}
 | |
| 
 | |
| 	xval := reflect.ValueOf(x)
 | |
| 	yval := reflect.ValueOf(y)
 | |
| 	if xval.Kind() == reflect.Ptr && xval.IsNil() ||
 | |
| 		yval.Kind() == reflect.Ptr && yval.IsNil() {
 | |
| 		return false
 | |
| 	}
 | |
| 
 | |
| 	if valuer, ok := x.(driver.Valuer); ok {
 | |
| 		x, _ = valuer.Value()
 | |
| 	}
 | |
| 	if valuer, ok := y.(driver.Valuer); ok {
 | |
| 		y, _ = valuer.Value()
 | |
| 	}
 | |
| 	return reflect.DeepEqual(x, y)
 | |
| }
 | |
| 
 | |
| func ToString(value interface{}) string {
 | |
| 	switch v := value.(type) {
 | |
| 	case string:
 | |
| 		return v
 | |
| 	case int:
 | |
| 		return strconv.FormatInt(int64(v), 10)
 | |
| 	case int8:
 | |
| 		return strconv.FormatInt(int64(v), 10)
 | |
| 	case int16:
 | |
| 		return strconv.FormatInt(int64(v), 10)
 | |
| 	case int32:
 | |
| 		return strconv.FormatInt(int64(v), 10)
 | |
| 	case int64:
 | |
| 		return strconv.FormatInt(v, 10)
 | |
| 	case uint:
 | |
| 		return strconv.FormatUint(uint64(v), 10)
 | |
| 	case uint8:
 | |
| 		return strconv.FormatUint(uint64(v), 10)
 | |
| 	case uint16:
 | |
| 		return strconv.FormatUint(uint64(v), 10)
 | |
| 	case uint32:
 | |
| 		return strconv.FormatUint(uint64(v), 10)
 | |
| 	case uint64:
 | |
| 		return strconv.FormatUint(v, 10)
 | |
| 	}
 | |
| 	return ""
 | |
| }
 | |
| 
 | |
| const nestedRelationSplit = "__"
 | |
| 
 | |
| // NestedRelationName nested relationships like `Manager__Company`
 | |
| func NestedRelationName(prefix, name string) string {
 | |
| 	return prefix + nestedRelationSplit + name
 | |
| }
 | |
| 
 | |
| // SplitNestedRelationName Split nested relationships to `[]string{"Manager","Company"}`
 | |
| func SplitNestedRelationName(name string) []string {
 | |
| 	return strings.Split(name, nestedRelationSplit)
 | |
| }
 | |
| 
 | |
| // JoinNestedRelationNames nested relationships like `Manager__Company`
 | |
| func JoinNestedRelationNames(relationNames []string) string {
 | |
| 	return strings.Join(relationNames, nestedRelationSplit)
 | |
| }
 |