diamond-orm/utils.go

134 lines
3.0 KiB
Go

package orm
import (
"fmt"
sb "github.com/henvic/pgq"
"reflect"
"regexp"
"strings"
)
var pascalRegex = regexp.MustCompile(`(?P<lowercase>[a-z])(?P<uppercase>[A-Z])`)
var nonWordRegex = regexp.MustCompile(`[^a-zA-Z0-9_]`)
func pascalToSnakeCase(str string) string {
step1 := pascalRegex.ReplaceAllString(str, `${lowercase}_${uppercase}`)
step2 := nonWordRegex.ReplaceAllString(step1, "_")
return strings.ToLower(step2)
}
func canConvertTo[T any](thisType reflect.Type) bool {
return thisType.ConvertibleTo(reflect.TypeFor[T]()) ||
thisType.ConvertibleTo(reflect.TypeFor[*T]()) ||
strings.TrimPrefix(thisType.Name(), "*") == strings.TrimPrefix(reflect.TypeFor[T]().Name(), "*")
}
func parseTags(t string) map[string]string {
tags := strings.Split(t, ";")
m := make(map[string]string)
for _, tag := range tags {
field := strings.Split(tag, ":")
if len(field) < 2 {
m[strings.ToLower(field[0])] = "t"
} else {
m[strings.ToLower(field[0])] = field[1]
}
}
return m
}
func capitalizeFirst(str string) string {
firstChar := strings.ToUpper(string([]byte{str[0]}))
return firstChar + string(str[1:])
}
func serialToRegular(str string) string {
return strings.ReplaceAll(strings.ToLower(str), "serial", "int")
}
func isZero(v reflect.Value) bool {
switch v.Kind() {
case reflect.String:
return v.String() == ""
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return v.Int() == 0
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
return v.Uint() == 0
case reflect.Bool:
return !v.Bool()
case reflect.Ptr, reflect.Interface:
return v.IsNil()
}
return v.IsZero()
}
func checkInsertable(v reflect.Value) {
}
func reflectSet(f reflect.Value, v any) {
if !f.CanSet() || v == nil {
return
}
switch f.Kind() {
case reflect.Int, reflect.Int64:
switch val := v.(type) {
case int64:
f.SetInt(val)
case int32:
f.SetInt(int64(val))
case int:
f.SetInt(int64(val))
case uint64:
f.SetInt(int64(val))
}
case reflect.String:
if s, ok := v.(string); ok {
f.SetString(s)
}
}
}
func logTrunc(length int, v []any) []any {
if length < 5 {
length = 5
}
trunced := make([]any, 0)
for _, it := range v {
if str, ok := it.(string); ok {
ntrunc := str[:min(length, len(str))]
if len(ntrunc) < len(str) {
ntrunc += "..."
}
trunced = append(trunced, ntrunc)
} else {
trunced = append(trunced, it)
}
}
return trunced
}
func isSliceOfStructs(rv reflect.Value) bool {
return rv.Kind() == reflect.Slice && rv.Type().Elem().Kind() == reflect.Struct
}
// MakePlaceholders - generates a string with `count`
// occurences of a placeholder (`?`), delimited by a
// comma and a space
func MakePlaceholders(count int) string {
if count < 1 {
return ""
}
var ph []string
for range count {
ph = append(ph, "?")
}
return strings.Join(ph, ", ")
}
func wrapQueryIn(s sb.SelectBuilder, idName string) sb.SelectBuilder {
return s.Prefix(
fmt.Sprintf("%s in (",
idName)).Suffix(")")
}