v0.0.399 added sq.NewAutoDBTypeConverter
All checks were successful
Build Docker and Deploy / Run goext test-suite (push) Successful in 1m25s
All checks were successful
Build Docker and Deploy / Run goext test-suite (push) Successful in 1m25s
This commit is contained in:
parent
9abe28c490
commit
9e5b8c5277
@ -30,7 +30,7 @@ Potentially needs `export GOPRIVATE="gogs.mikescher.com"`
|
|||||||
| confext | Mike | Parses environment configuration into structs |
|
| confext | Mike | Parses environment configuration into structs |
|
||||||
| cmdext | Mike | Runner for external commands/processes |
|
| cmdext | Mike | Runner for external commands/processes |
|
||||||
| | | |
|
| | | |
|
||||||
| sq | Mike | Utility functions for sql based databases |
|
| sq | Mike | Utility functions for sql based databases (primarily sqlite) |
|
||||||
| tst | Mike | Utility functions for unit tests |
|
| tst | Mike | Utility functions for unit tests |
|
||||||
| | | |
|
| | | |
|
||||||
| rfctime | Mike | Classes for time seriallization, with different marshallign method for mongo and json |
|
| rfctime | Mike | Classes for time seriallization, with different marshallign method for mongo and json |
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
package goext
|
package goext
|
||||||
|
|
||||||
const GoextVersion = "0.0.398"
|
const GoextVersion = "0.0.399"
|
||||||
|
|
||||||
const GoextVersionTimestamp = "2024-03-09T13:36:06+0100"
|
const GoextVersionTimestamp = "2024-03-09T14:16:35+0100"
|
||||||
|
183
sq/converter.go
183
sq/converter.go
@ -1,17 +1,10 @@
|
|||||||
package sq
|
package sq
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"gogs.mikescher.com/BlackForestBytes/goext/exerr"
|
|
||||||
"gogs.mikescher.com/BlackForestBytes/goext/langext"
|
"gogs.mikescher.com/BlackForestBytes/goext/langext"
|
||||||
"gogs.mikescher.com/BlackForestBytes/goext/rfctime"
|
|
||||||
"gogs.mikescher.com/BlackForestBytes/goext/timeext"
|
|
||||||
"reflect"
|
"reflect"
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type DBTypeConverter interface {
|
type DBTypeConverter interface {
|
||||||
@ -21,169 +14,16 @@ type DBTypeConverter interface {
|
|||||||
DBToModel(v any) (any, error)
|
DBToModel(v any) (any, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
var ConverterBoolToBit = NewDBTypeConverter[bool, int64](func(v bool) (int64, error) {
|
type DBDataConstraint interface {
|
||||||
return langext.Conditional(v, int64(1), int64(0)), nil
|
string | langext.NumberConstraint | []byte
|
||||||
}, func(v int64) (bool, error) {
|
|
||||||
if v == 0 {
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
if v == 1 {
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
return false, errors.New(fmt.Sprintf("invalid valud for boolean: '%d'", v))
|
|
||||||
})
|
|
||||||
|
|
||||||
var ConverterTimeToUnixMillis = NewDBTypeConverter[time.Time, int64](func(v time.Time) (int64, error) {
|
|
||||||
return v.UnixMilli(), nil
|
|
||||||
}, func(v int64) (time.Time, error) {
|
|
||||||
return time.UnixMilli(v), nil
|
|
||||||
})
|
|
||||||
|
|
||||||
var ConverterRFCUnixMilliTimeToUnixMillis = NewDBTypeConverter[rfctime.UnixMilliTime, int64](func(v rfctime.UnixMilliTime) (int64, error) {
|
|
||||||
return v.UnixMilli(), nil
|
|
||||||
}, func(v int64) (rfctime.UnixMilliTime, error) {
|
|
||||||
return rfctime.NewUnixMilli(time.UnixMilli(v)), nil
|
|
||||||
})
|
|
||||||
|
|
||||||
var ConverterRFCUnixNanoTimeToUnixNanos = NewDBTypeConverter[rfctime.UnixNanoTime, int64](func(v rfctime.UnixNanoTime) (int64, error) {
|
|
||||||
return v.UnixNano(), nil
|
|
||||||
}, func(v int64) (rfctime.UnixNanoTime, error) {
|
|
||||||
return rfctime.NewUnixNano(time.Unix(0, v)), nil
|
|
||||||
})
|
|
||||||
|
|
||||||
var ConverterRFCUnixTimeToUnixSeconds = NewDBTypeConverter[rfctime.UnixTime, int64](func(v rfctime.UnixTime) (int64, error) {
|
|
||||||
return v.Unix(), nil
|
|
||||||
}, func(v int64) (rfctime.UnixTime, error) {
|
|
||||||
return rfctime.NewUnix(time.Unix(v, 0)), nil
|
|
||||||
})
|
|
||||||
|
|
||||||
// ConverterRFC339TimeToString
|
|
||||||
// Does not really use RFC339 - but sqlite does not understand timezones and the `T` delimiter
|
|
||||||
var ConverterRFC339TimeToString = NewDBTypeConverter[rfctime.RFC3339Time, string](func(v rfctime.RFC3339Time) (string, error) {
|
|
||||||
return v.Time().In(time.UTC).Format("2006-01-02 15:04:05"), nil
|
|
||||||
}, func(v string) (rfctime.RFC3339Time, error) {
|
|
||||||
t, err := time.Parse("2006-01-02 15:04:05", v)
|
|
||||||
if err != nil {
|
|
||||||
return rfctime.RFC3339Time{}, err
|
|
||||||
}
|
|
||||||
return rfctime.NewRFC3339(t), nil
|
|
||||||
})
|
|
||||||
|
|
||||||
// ConverterRFC339NanoTimeToString
|
|
||||||
// Does not really use RFC339 - but sqlite does not understand timezones and the `T` delimiter
|
|
||||||
var ConverterRFC339NanoTimeToString = NewDBTypeConverter[rfctime.RFC3339NanoTime, string](func(v rfctime.RFC3339NanoTime) (string, error) {
|
|
||||||
return v.Time().In(time.UTC).Format("2006-01-02 15:04:05.999999999"), nil
|
|
||||||
}, func(v string) (rfctime.RFC3339NanoTime, error) {
|
|
||||||
t, err := time.ParseInLocation("2006-01-02 15:04:05.999999999", v, time.UTC)
|
|
||||||
if err != nil {
|
|
||||||
return rfctime.RFC3339NanoTime{}, err
|
|
||||||
}
|
|
||||||
return rfctime.NewRFC3339Nano(t), nil
|
|
||||||
})
|
|
||||||
|
|
||||||
var ConverterRFCDateToString = NewDBTypeConverter[rfctime.Date, string](func(v rfctime.Date) (string, error) {
|
|
||||||
return fmt.Sprintf("%04d-%02d-%02d", v.Year, v.Month, v.Day), nil
|
|
||||||
}, func(v string) (rfctime.Date, error) {
|
|
||||||
split := strings.Split(v, "-")
|
|
||||||
if len(split) != 3 {
|
|
||||||
return rfctime.Date{}, errors.New("invalid date format: " + v)
|
|
||||||
}
|
|
||||||
year, err := strconv.ParseInt(split[0], 10, 32)
|
|
||||||
if err != nil {
|
|
||||||
return rfctime.Date{}, errors.New("invalid date format: " + v + ": " + err.Error())
|
|
||||||
}
|
|
||||||
month, err := strconv.ParseInt(split[0], 10, 32)
|
|
||||||
if err != nil {
|
|
||||||
return rfctime.Date{}, errors.New("invalid date format: " + v + ": " + err.Error())
|
|
||||||
}
|
|
||||||
day, err := strconv.ParseInt(split[0], 10, 32)
|
|
||||||
if err != nil {
|
|
||||||
return rfctime.Date{}, errors.New("invalid date format: " + v + ": " + err.Error())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return rfctime.Date{Year: int(year), Month: int(month), Day: int(day)}, nil
|
type DatabaseConvertible[TModelData any, TDBData DBDataConstraint] interface {
|
||||||
})
|
MarshalToDB(v TModelData) (TDBData, error)
|
||||||
|
UnmarshalToModel(v TDBData) (TModelData, error)
|
||||||
var ConverterRFCTimeToString = NewDBTypeConverter[rfctime.Time, string](func(v rfctime.Time) (string, error) {
|
|
||||||
return v.SerializeShort(), nil
|
|
||||||
}, func(v string) (rfctime.Time, error) {
|
|
||||||
res := rfctime.Time{}
|
|
||||||
err := res.Deserialize(v)
|
|
||||||
if err != nil {
|
|
||||||
return rfctime.Time{}, err
|
|
||||||
}
|
|
||||||
return res, nil
|
|
||||||
})
|
|
||||||
|
|
||||||
var ConverterRFCSecondsF64ToString = NewDBTypeConverter[rfctime.SecondsF64, float64](func(v rfctime.SecondsF64) (float64, error) {
|
|
||||||
return v.Seconds(), nil
|
|
||||||
}, func(v float64) (rfctime.SecondsF64, error) {
|
|
||||||
return rfctime.NewSecondsF64(timeext.FromSeconds(v)), nil
|
|
||||||
})
|
|
||||||
|
|
||||||
var ConverterJsonObjToString = NewDBTypeConverter[JsonObj, string](func(v JsonObj) (string, error) {
|
|
||||||
mrsh, err := json.Marshal(v)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
return string(mrsh), nil
|
|
||||||
}, func(v string) (JsonObj, error) {
|
|
||||||
var mrsh JsonObj
|
|
||||||
if err := json.Unmarshal([]byte(v), &mrsh); err != nil {
|
|
||||||
return JsonObj{}, err
|
|
||||||
}
|
|
||||||
return mrsh, nil
|
|
||||||
})
|
|
||||||
|
|
||||||
var ConverterJsonArrToString = NewDBTypeConverter[JsonArr, string](func(v JsonArr) (string, error) {
|
|
||||||
mrsh, err := json.Marshal(v)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
return string(mrsh), nil
|
|
||||||
}, func(v string) (JsonArr, error) {
|
|
||||||
var mrsh JsonArr
|
|
||||||
if err := json.Unmarshal([]byte(v), &mrsh); err != nil {
|
|
||||||
return JsonArr{}, err
|
|
||||||
}
|
|
||||||
return mrsh, nil
|
|
||||||
})
|
|
||||||
|
|
||||||
var ConverterExErrCategoryToString = NewDBTypeConverter[exerr.ErrorCategory, string](func(v exerr.ErrorCategory) (string, error) {
|
|
||||||
return v.Category, nil
|
|
||||||
}, func(v string) (exerr.ErrorCategory, error) {
|
|
||||||
for _, cat := range exerr.AllCategories {
|
|
||||||
if cat.Category == v {
|
|
||||||
return cat, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return exerr.CatUser, errors.New("failed to convert '" + v + "' to exerr.ErrorCategory")
|
|
||||||
})
|
|
||||||
|
|
||||||
var ConverterExErrSeverityToString = NewDBTypeConverter[exerr.ErrorSeverity, string](func(v exerr.ErrorSeverity) (string, error) {
|
|
||||||
return v.Severity, nil
|
|
||||||
}, func(v string) (exerr.ErrorSeverity, error) {
|
|
||||||
for _, sev := range exerr.AllSeverities {
|
|
||||||
if sev.Severity == v {
|
|
||||||
return sev, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return exerr.SevErr, errors.New("failed to convert '" + v + "' to exerr.ErrorSeverity")
|
|
||||||
})
|
|
||||||
|
|
||||||
var ConverterExErrTypeToString = NewDBTypeConverter[exerr.ErrorType, string](func(v exerr.ErrorType) (string, error) {
|
|
||||||
return v.Key, nil
|
|
||||||
}, func(v string) (exerr.ErrorType, error) {
|
|
||||||
for _, etp := range exerr.ListRegisteredTypes() {
|
|
||||||
if etp.Key == v {
|
|
||||||
return etp, nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return exerr.NewType(v, nil), nil
|
type dbTypeConverterImpl[TModelData any, TDBData DBDataConstraint] struct {
|
||||||
})
|
|
||||||
|
|
||||||
type dbTypeConverterImpl[TModelData any, TDBData any] struct {
|
|
||||||
dbTypeString string
|
dbTypeString string
|
||||||
modelTypeString string
|
modelTypeString string
|
||||||
todb func(v TModelData) (TDBData, error)
|
todb func(v TModelData) (TDBData, error)
|
||||||
@ -212,7 +52,7 @@ func (t *dbTypeConverterImpl[TModelData, TDBData]) DBToModel(v any) (any, error)
|
|||||||
return nil, errors.New(fmt.Sprintf("Unexpected value in DBTypeConverter, expected '%s', found '%T'", t.dbTypeString, v))
|
return nil, errors.New(fmt.Sprintf("Unexpected value in DBTypeConverter, expected '%s', found '%T'", t.dbTypeString, v))
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDBTypeConverter[TModelData any, TDBData any](todb func(v TModelData) (TDBData, error), tomodel func(v TDBData) (TModelData, error)) DBTypeConverter {
|
func NewDBTypeConverter[TModelData any, TDBData DBDataConstraint](todb func(v TModelData) (TDBData, error), tomodel func(v TDBData) (TModelData, error)) DBTypeConverter {
|
||||||
return &dbTypeConverterImpl[TModelData, TDBData]{
|
return &dbTypeConverterImpl[TModelData, TDBData]{
|
||||||
dbTypeString: fmt.Sprintf("%T", *new(TDBData)),
|
dbTypeString: fmt.Sprintf("%T", *new(TDBData)),
|
||||||
modelTypeString: fmt.Sprintf("%T", *new(TModelData)),
|
modelTypeString: fmt.Sprintf("%T", *new(TModelData)),
|
||||||
@ -221,6 +61,15 @@ func NewDBTypeConverter[TModelData any, TDBData any](todb func(v TModelData) (TD
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewAutoDBTypeConverter[TDBData DBDataConstraint, TModelData DatabaseConvertible[TModelData, TDBData]](obj TModelData) DBTypeConverter {
|
||||||
|
return &dbTypeConverterImpl[TModelData, TDBData]{
|
||||||
|
dbTypeString: fmt.Sprintf("%T", *new(TDBData)),
|
||||||
|
modelTypeString: fmt.Sprintf("%T", *new(TModelData)),
|
||||||
|
todb: obj.MarshalToDB,
|
||||||
|
tomodel: obj.UnmarshalToModel,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func convertValueToDB(q Queryable, value any) (any, error) {
|
func convertValueToDB(q Queryable, value any) (any, error) {
|
||||||
modelTypeStr := fmt.Sprintf("%T", value)
|
modelTypeStr := fmt.Sprintf("%T", value)
|
||||||
|
|
||||||
|
161
sq/converterDefault.go
Normal file
161
sq/converterDefault.go
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
package sq
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"gogs.mikescher.com/BlackForestBytes/goext/exerr"
|
||||||
|
"gogs.mikescher.com/BlackForestBytes/goext/langext"
|
||||||
|
"gogs.mikescher.com/BlackForestBytes/goext/rfctime"
|
||||||
|
"gogs.mikescher.com/BlackForestBytes/goext/timeext"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ========================== COMMON DATATYPES ==========================
|
||||||
|
|
||||||
|
var ConverterBoolToBit = NewDBTypeConverter[bool, int64](func(v bool) (int64, error) {
|
||||||
|
return langext.Conditional(v, int64(1), int64(0)), nil
|
||||||
|
}, func(v int64) (bool, error) {
|
||||||
|
if v == 0 {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
if v == 1 {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
return false, errors.New(fmt.Sprintf("invalid valud for boolean: '%d'", v))
|
||||||
|
})
|
||||||
|
|
||||||
|
var ConverterTimeToUnixMillis = NewDBTypeConverter[time.Time, int64](func(v time.Time) (int64, error) {
|
||||||
|
return v.UnixMilli(), nil
|
||||||
|
}, func(v int64) (time.Time, error) {
|
||||||
|
return time.UnixMilli(v), nil
|
||||||
|
})
|
||||||
|
|
||||||
|
// ========================== RFCTIME ==========================
|
||||||
|
|
||||||
|
var ConverterRFCUnixMilliTimeToUnixMillis = NewDBTypeConverter[rfctime.UnixMilliTime, int64](func(v rfctime.UnixMilliTime) (int64, error) {
|
||||||
|
return v.UnixMilli(), nil
|
||||||
|
}, func(v int64) (rfctime.UnixMilliTime, error) {
|
||||||
|
return rfctime.NewUnixMilli(time.UnixMilli(v)), nil
|
||||||
|
})
|
||||||
|
|
||||||
|
var ConverterRFCUnixNanoTimeToUnixNanos = NewDBTypeConverter[rfctime.UnixNanoTime, int64](func(v rfctime.UnixNanoTime) (int64, error) {
|
||||||
|
return v.UnixNano(), nil
|
||||||
|
}, func(v int64) (rfctime.UnixNanoTime, error) {
|
||||||
|
return rfctime.NewUnixNano(time.Unix(0, v)), nil
|
||||||
|
})
|
||||||
|
|
||||||
|
var ConverterRFCUnixTimeToUnixSeconds = NewDBTypeConverter[rfctime.UnixTime, int64](func(v rfctime.UnixTime) (int64, error) {
|
||||||
|
return v.Unix(), nil
|
||||||
|
}, func(v int64) (rfctime.UnixTime, error) {
|
||||||
|
return rfctime.NewUnix(time.Unix(v, 0)), nil
|
||||||
|
})
|
||||||
|
|
||||||
|
// ConverterRFC339TimeToString
|
||||||
|
// Does not really use RFC339 - but sqlite does not understand timezones and the `T` delimiter
|
||||||
|
var ConverterRFC339TimeToString = NewDBTypeConverter[rfctime.RFC3339Time, string](func(v rfctime.RFC3339Time) (string, error) {
|
||||||
|
return v.Time().In(time.UTC).Format("2006-01-02 15:04:05"), nil
|
||||||
|
}, func(v string) (rfctime.RFC3339Time, error) {
|
||||||
|
t, err := time.Parse("2006-01-02 15:04:05", v)
|
||||||
|
if err != nil {
|
||||||
|
return rfctime.RFC3339Time{}, err
|
||||||
|
}
|
||||||
|
return rfctime.NewRFC3339(t), nil
|
||||||
|
})
|
||||||
|
|
||||||
|
// ConverterRFC339NanoTimeToString
|
||||||
|
// Does not really use RFC339 - but sqlite does not understand timezones and the `T` delimiter
|
||||||
|
var ConverterRFC339NanoTimeToString = NewDBTypeConverter[rfctime.RFC3339NanoTime, string](func(v rfctime.RFC3339NanoTime) (string, error) {
|
||||||
|
return v.Time().In(time.UTC).Format("2006-01-02 15:04:05.999999999"), nil
|
||||||
|
}, func(v string) (rfctime.RFC3339NanoTime, error) {
|
||||||
|
t, err := time.ParseInLocation("2006-01-02 15:04:05.999999999", v, time.UTC)
|
||||||
|
if err != nil {
|
||||||
|
return rfctime.RFC3339NanoTime{}, err
|
||||||
|
}
|
||||||
|
return rfctime.NewRFC3339Nano(t), nil
|
||||||
|
})
|
||||||
|
|
||||||
|
var ConverterRFCDateToString = NewDBTypeConverter[rfctime.Date, string](func(v rfctime.Date) (string, error) {
|
||||||
|
return fmt.Sprintf("%04d-%02d-%02d", v.Year, v.Month, v.Day), nil
|
||||||
|
}, func(v string) (rfctime.Date, error) {
|
||||||
|
split := strings.Split(v, "-")
|
||||||
|
if len(split) != 3 {
|
||||||
|
return rfctime.Date{}, errors.New("invalid date format: " + v)
|
||||||
|
}
|
||||||
|
year, err := strconv.ParseInt(split[0], 10, 32)
|
||||||
|
if err != nil {
|
||||||
|
return rfctime.Date{}, errors.New("invalid date format: " + v + ": " + err.Error())
|
||||||
|
}
|
||||||
|
month, err := strconv.ParseInt(split[0], 10, 32)
|
||||||
|
if err != nil {
|
||||||
|
return rfctime.Date{}, errors.New("invalid date format: " + v + ": " + err.Error())
|
||||||
|
}
|
||||||
|
day, err := strconv.ParseInt(split[0], 10, 32)
|
||||||
|
if err != nil {
|
||||||
|
return rfctime.Date{}, errors.New("invalid date format: " + v + ": " + err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
return rfctime.Date{Year: int(year), Month: int(month), Day: int(day)}, nil
|
||||||
|
})
|
||||||
|
|
||||||
|
var ConverterRFCTimeToString = NewDBTypeConverter[rfctime.Time, string](func(v rfctime.Time) (string, error) {
|
||||||
|
return v.SerializeShort(), nil
|
||||||
|
}, func(v string) (rfctime.Time, error) {
|
||||||
|
res := rfctime.Time{}
|
||||||
|
err := res.Deserialize(v)
|
||||||
|
if err != nil {
|
||||||
|
return rfctime.Time{}, err
|
||||||
|
}
|
||||||
|
return res, nil
|
||||||
|
})
|
||||||
|
|
||||||
|
var ConverterRFCSecondsF64ToString = NewDBTypeConverter[rfctime.SecondsF64, float64](func(v rfctime.SecondsF64) (float64, error) {
|
||||||
|
return v.Seconds(), nil
|
||||||
|
}, func(v float64) (rfctime.SecondsF64, error) {
|
||||||
|
return rfctime.NewSecondsF64(timeext.FromSeconds(v)), nil
|
||||||
|
})
|
||||||
|
|
||||||
|
// ========================== JSON ==========================
|
||||||
|
|
||||||
|
var ConverterJsonObjToString = NewAutoDBTypeConverter(JsonObj{})
|
||||||
|
|
||||||
|
var ConverterJsonArrToString = NewAutoDBTypeConverter(JsonArr{})
|
||||||
|
|
||||||
|
// Json[T] must be registered manually for each gen-type
|
||||||
|
|
||||||
|
// ========================== EXERR ==========================
|
||||||
|
|
||||||
|
var ConverterExErrCategoryToString = NewDBTypeConverter[exerr.ErrorCategory, string](func(v exerr.ErrorCategory) (string, error) {
|
||||||
|
return v.Category, nil
|
||||||
|
}, func(v string) (exerr.ErrorCategory, error) {
|
||||||
|
for _, cat := range exerr.AllCategories {
|
||||||
|
if cat.Category == v {
|
||||||
|
return cat, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return exerr.CatUser, errors.New("failed to convert '" + v + "' to exerr.ErrorCategory")
|
||||||
|
})
|
||||||
|
|
||||||
|
var ConverterExErrSeverityToString = NewDBTypeConverter[exerr.ErrorSeverity, string](func(v exerr.ErrorSeverity) (string, error) {
|
||||||
|
return v.Severity, nil
|
||||||
|
}, func(v string) (exerr.ErrorSeverity, error) {
|
||||||
|
for _, sev := range exerr.AllSeverities {
|
||||||
|
if sev.Severity == v {
|
||||||
|
return sev, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return exerr.SevErr, errors.New("failed to convert '" + v + "' to exerr.ErrorSeverity")
|
||||||
|
})
|
||||||
|
|
||||||
|
var ConverterExErrTypeToString = NewDBTypeConverter[exerr.ErrorType, string](func(v exerr.ErrorType) (string, error) {
|
||||||
|
return v.Key, nil
|
||||||
|
}, func(v string) (exerr.ErrorType, error) {
|
||||||
|
for _, etp := range exerr.ListRegisteredTypes() {
|
||||||
|
if etp.Key == v {
|
||||||
|
return etp, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return exerr.NewType(v, nil), nil
|
||||||
|
})
|
54
sq/json.go
54
sq/json.go
@ -1,5 +1,59 @@
|
|||||||
package sq
|
package sq
|
||||||
|
|
||||||
|
import "encoding/json"
|
||||||
|
|
||||||
type JsonObj map[string]any
|
type JsonObj map[string]any
|
||||||
|
|
||||||
|
func (j JsonObj) MarshalToDB(v JsonObj) (string, error) {
|
||||||
|
mrsh, err := json.Marshal(v)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return string(mrsh), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (j JsonObj) UnmarshalToModel(v string) (JsonObj, error) {
|
||||||
|
var mrsh JsonObj
|
||||||
|
if err := json.Unmarshal([]byte(v), &mrsh); err != nil {
|
||||||
|
return JsonObj{}, err
|
||||||
|
}
|
||||||
|
return mrsh, nil
|
||||||
|
}
|
||||||
|
|
||||||
type JsonArr []any
|
type JsonArr []any
|
||||||
|
|
||||||
|
func (j JsonArr) MarshalToDB(v JsonArr) (string, error) {
|
||||||
|
mrsh, err := json.Marshal(v)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return string(mrsh), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (j JsonArr) UnmarshalToModel(v string) (JsonArr, error) {
|
||||||
|
var mrsh JsonArr
|
||||||
|
if err := json.Unmarshal([]byte(v), &mrsh); err != nil {
|
||||||
|
return JsonArr{}, err
|
||||||
|
}
|
||||||
|
return mrsh, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type AutoJson[T any] struct {
|
||||||
|
Value T
|
||||||
|
}
|
||||||
|
|
||||||
|
func (j AutoJson[T]) MarshalToDB(v AutoJson[T]) (string, error) {
|
||||||
|
mrsh, err := json.Marshal(v.Value)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return string(mrsh), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (j AutoJson[T]) UnmarshalToModel(v string) (AutoJson[T], error) {
|
||||||
|
mrsh := *new(T)
|
||||||
|
if err := json.Unmarshal([]byte(v), &mrsh); err != nil {
|
||||||
|
return AutoJson[T]{}, err
|
||||||
|
}
|
||||||
|
return AutoJson[T]{Value: mrsh}, nil
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user