fix incident view
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2025-03-24 17:03:16 +11:00
parent 49e60f7843
commit 252bf0a1c8
9 changed files with 612 additions and 10 deletions

View File

@@ -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)
}
}
}