package orm import ( "fmt" sb "github.com/henvic/pgq" "reflect" "regexp" "strings" ) var pascalRegex = regexp.MustCompile(`(?P[a-z])(?P[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(")") }