package utils
import (
"database/sql/driver"
"fmt"
"path/filepath"
"reflect"
"runtime"
"strconv"
"strings"
"unicode"
)
var gormSourceDir string
func init() {
_ , file , _ , _ := runtime .Caller (0 )
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 ) + "/"
}
func CallerFrame () runtime .Frame {
pcs := [13 ]uintptr {}
len := runtime .Callers (3 , pcs [:])
frames := runtime .CallersFrames (pcs [:len ])
for i := 0 ; i < len ; i ++ {
frame , _ := frames .Next ()
if (!strings .HasPrefix (frame .File , gormSourceDir ) ||
strings .HasSuffix (frame .File , "_test.go" )) && !strings .HasSuffix (frame .File , ".gen.go" ) {
return frame
}
}
return runtime .Frame {}
}
func FileWithLineNum () string {
frame := CallerFrame ()
if frame .PC != 0 {
return string (strconv .AppendInt (append ([]byte (frame .File ), ':' ), int64 (frame .Line ), 10 ))
}
return ""
}
func IsInvalidDBNameChar (c rune ) bool {
return !unicode .IsLetter (c ) && !unicode .IsNumber (c ) && c != '.' && c != '*' && c != '_' && c != '$' && c != '@'
}
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 = "__"
func NestedRelationName (prefix , name string ) string {
return prefix + nestedRelationSplit + name
}
func SplitNestedRelationName (name string ) []string {
return strings .Split (name , nestedRelationSplit )
}
func JoinNestedRelationNames (relationNames []string ) string {
return strings .Join (relationNames , nestedRelationSplit )
}
func RTrimSlice [T any ](v []T , trimLen int ) []T {
if trimLen >= len (v ) {
return v [:0 ]
}
if trimLen < 0 {
return v [:]
}
return v [:len (v )-trimLen ]
}
The pages are generated with Golds v0.8.2 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .