This commit is contained in:
@@ -2,6 +2,9 @@ package utils
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"log"
|
||||
"log/slog"
|
||||
"net"
|
||||
@@ -69,7 +72,7 @@ func SleepWithContext(ctx context.Context, d time.Duration) {
|
||||
}
|
||||
}
|
||||
|
||||
// Generic converter using reflection
|
||||
// Generic converter using reflection for all sqlc/sqlite types
|
||||
func ConvertStruct(src interface{}, dst interface{}) {
|
||||
srcVal := reflect.ValueOf(src)
|
||||
srcType := reflect.TypeOf(src)
|
||||
@@ -77,30 +80,97 @@ func ConvertStruct(src interface{}, dst interface{}) {
|
||||
|
||||
for i := 0; i < srcVal.NumField(); i++ {
|
||||
srcField := srcVal.Field(i)
|
||||
srcFieldType := srcField.Type()
|
||||
dstField := dstVal.FieldByName(srcType.Field(i).Name)
|
||||
|
||||
//slog.Info("Source field", "name", srcType.Field(i).Name)
|
||||
|
||||
if !dstField.IsValid() || !dstField.CanSet() {
|
||||
continue
|
||||
}
|
||||
|
||||
switch srcField.Type().Name() {
|
||||
case "NullString":
|
||||
switch srcFieldType {
|
||||
case reflect.TypeOf(sql.NullString{}):
|
||||
//slog.Info("Sourcefield is string")
|
||||
if srcField.FieldByName("Valid").Bool() {
|
||||
dstField.SetString(srcField.FieldByName("String").String())
|
||||
} else {
|
||||
dstField.SetString("")
|
||||
}
|
||||
case "NullTime":
|
||||
|
||||
case reflect.TypeOf(sql.NullInt64{}):
|
||||
//slog.Info("Sourcefield is int64")
|
||||
if srcField.FieldByName("Valid").Bool() {
|
||||
val := srcField.FieldByName("Int64").Int()
|
||||
if dstField.Kind() == reflect.String {
|
||||
dstField.SetString(fmt.Sprintf("%d", val))
|
||||
} else {
|
||||
dstField.SetInt(val)
|
||||
}
|
||||
} else {
|
||||
if dstField.Kind() == reflect.String {
|
||||
dstField.SetString("")
|
||||
} else {
|
||||
dstField.SetInt(0)
|
||||
}
|
||||
}
|
||||
|
||||
case reflect.TypeOf(sql.NullFloat64{}):
|
||||
if srcField.FieldByName("Valid").Bool() {
|
||||
val := srcField.FieldByName("Float64").Float()
|
||||
if dstField.Kind() == reflect.String {
|
||||
dstField.SetString(fmt.Sprintf("%f", val))
|
||||
} else {
|
||||
dstField.SetFloat(val)
|
||||
}
|
||||
} else {
|
||||
if dstField.Kind() == reflect.String {
|
||||
dstField.SetString("")
|
||||
} else {
|
||||
dstField.SetFloat(0)
|
||||
}
|
||||
}
|
||||
|
||||
case reflect.TypeOf(sql.NullBool{}):
|
||||
if srcField.FieldByName("Valid").Bool() {
|
||||
val := srcField.FieldByName("Bool").Bool()
|
||||
if dstField.Kind() == reflect.String {
|
||||
dstField.SetString(fmt.Sprintf("%t", val))
|
||||
} else {
|
||||
dstField.SetBool(val)
|
||||
}
|
||||
} else {
|
||||
if dstField.Kind() == reflect.String {
|
||||
dstField.SetString("")
|
||||
} else {
|
||||
dstField.SetBool(false)
|
||||
}
|
||||
}
|
||||
|
||||
case reflect.TypeOf(sql.NullTime{}):
|
||||
//slog.Info("Sourcefield is time")
|
||||
if srcField.FieldByName("Valid").Bool() {
|
||||
t := srcField.FieldByName("Time").Interface().(time.Time)
|
||||
dstField.SetString(t.Format("2006-01-02 15:04:05"))
|
||||
} else {
|
||||
slog.Info("value is not valid")
|
||||
dstField.SetString("")
|
||||
}
|
||||
|
||||
default:
|
||||
// Handle int64 -> int conversion
|
||||
if srcField.Kind() == reflect.Int64 && dstField.Kind() == reflect.Int {
|
||||
dstField.SetInt(srcField.Int())
|
||||
// Handle []byte (often from BLOB fields)
|
||||
if srcField.Kind() == reflect.Slice && srcField.Type().Elem().Kind() == reflect.Uint8 {
|
||||
if !srcField.IsNil() {
|
||||
encoded := base64.StdEncoding.EncodeToString(srcField.Bytes())
|
||||
dstField.SetString(encoded)
|
||||
} else {
|
||||
dstField.SetString("")
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback: copy if types are directly assignable
|
||||
if srcField.Type().AssignableTo(dstField.Type()) {
|
||||
dstField.Set(srcField)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user