Compare commits

...

3 Commits

Author SHA1 Message Date
70de8e8d04 v0.0.362
All checks were successful
Build Docker and Deploy / Run goext test-suite (push) Successful in 1m27s
2024-01-07 04:18:03 +01:00
d38fa60fbc v0.0.361 call exerrListener in ginext.Error
All checks were successful
Build Docker and Deploy / Run goext test-suite (push) Successful in 1m37s
2024-01-07 04:01:13 +01:00
5fba7e0e2f v0.0.360 bf
All checks were successful
Build Docker and Deploy / Run goext test-suite (push) Successful in 1m26s
2024-01-06 01:31:07 +01:00
9 changed files with 173 additions and 16 deletions

113
dataext/syncMap.go Normal file
View File

@@ -0,0 +1,113 @@
package dataext
import "sync"
type SyncMap[TKey comparable, TData any] struct {
data map[TKey]TData
lock sync.Mutex
}
func (s *SyncMap[TKey, TData]) Set(key TKey, data TData) {
s.lock.Lock()
defer s.lock.Unlock()
if s.data == nil {
s.data = make(map[TKey]TData)
}
s.data[key] = data
}
func (s *SyncMap[TKey, TData]) SetIfNotContains(key TKey, data TData) bool {
s.lock.Lock()
defer s.lock.Unlock()
if s.data == nil {
s.data = make(map[TKey]TData)
}
if _, existsInPreState := s.data[key]; existsInPreState {
return false
}
s.data[key] = data
return true
}
func (s *SyncMap[TKey, TData]) Get(key TKey) (TData, bool) {
s.lock.Lock()
defer s.lock.Unlock()
if s.data == nil {
s.data = make(map[TKey]TData)
}
if v, ok := s.data[key]; ok {
return v, true
} else {
return *new(TData), false
}
}
func (s *SyncMap[TKey, TData]) Delete(key TKey) bool {
s.lock.Lock()
defer s.lock.Unlock()
if s.data == nil {
s.data = make(map[TKey]TData)
}
_, ok := s.data[key]
delete(s.data, key)
return ok
}
func (s *SyncMap[TKey, TData]) Contains(key TKey) bool {
s.lock.Lock()
defer s.lock.Unlock()
if s.data == nil {
s.data = make(map[TKey]TData)
}
_, ok := s.data[key]
return ok
}
func (s *SyncMap[TKey, TData]) GetAllKeys() []TKey {
s.lock.Lock()
defer s.lock.Unlock()
if s.data == nil {
s.data = make(map[TKey]TData)
}
r := make([]TKey, 0, len(s.data))
for k := range s.data {
r = append(r, k)
}
return r
}
func (s *SyncMap[TKey, TData]) GetAllValues() []TData {
s.lock.Lock()
defer s.lock.Unlock()
if s.data == nil {
s.data = make(map[TKey]TData)
}
r := make([]TData, 0, len(s.data))
for _, v := range s.data {
r = append(r, v)
}
return r
}

View File

@@ -420,7 +420,7 @@ func (b *Builder) Build() error {
b.errorData.ShortLog(stackSkipLogger.Error()) b.errorData.ShortLog(stackSkipLogger.Error())
} }
b.CallListener(MethodBuild) b.errorData.CallListener(MethodBuild)
return b.errorData return b.errorData
} }
@@ -442,7 +442,7 @@ func (b *Builder) Output(ctx context.Context, g *gin.Context) {
b.errorData.Log(stackSkipLogger.Warn()) b.errorData.Log(stackSkipLogger.Warn())
} }
b.CallListener(MethodOutput) b.errorData.CallListener(MethodOutput)
} }
// Print prints the error // Print prints the error
@@ -454,7 +454,7 @@ func (b *Builder) Print() {
b.errorData.ShortLog(stackSkipLogger.Warn()) b.errorData.ShortLog(stackSkipLogger.Warn())
} }
b.CallListener(MethodPrint) b.errorData.CallListener(MethodPrint)
} }
func (b *Builder) Format(level LogPrintLevel) string { func (b *Builder) Format(level LogPrintLevel) string {
@@ -467,7 +467,7 @@ func (b *Builder) Fatal() {
b.errorData.Severity = SevFatal b.errorData.Severity = SevFatal
b.errorData.Log(stackSkipLogger.WithLevel(zerolog.FatalLevel)) b.errorData.Log(stackSkipLogger.WithLevel(zerolog.FatalLevel))
b.CallListener(MethodFatal) b.errorData.CallListener(MethodFatal)
os.Exit(1) os.Exit(1)
} }

View File

@@ -71,15 +71,18 @@ var (
// other values come from the downstream application that uses goext // other values come from the downstream application that uses goext
) )
var registeredTypes = dataext.SyncSet[string]{} var registeredTypes = dataext.SyncMap[string, ErrorType]{}
func NewType(key string, defStatusCode *int) ErrorType { func NewType(key string, defStatusCode *int) ErrorType {
insertOkay := registeredTypes.Add(key) et := ErrorType{key, defStatusCode}
if !insertOkay {
panic("Cannot register same ErrType ('" + key + "') more than once")
}
return ErrorType{key, defStatusCode} registeredTypes.Set(key, et)
return et
}
func ListRegisteredTypes() []ErrorType {
return registeredTypes.GetAllValues()
} }
type LogPrintLevel string type LogPrintLevel string

View File

@@ -25,13 +25,11 @@ func RegisterListener(l Listener) {
listener = append(listener, l) listener = append(listener, l)
} }
func (b *Builder) CallListener(m Method) { func (ee *ExErr) CallListener(m Method) {
valErr := b.errorData
listenerLock.Lock() listenerLock.Lock()
defer listenerLock.Unlock() defer listenerLock.Unlock()
for _, v := range listener { for _, v := range listener {
v(m, valErr) v(m, ee)
} }
} }

View File

@@ -328,6 +328,8 @@ type jsonAPIErrResponse struct {
func (j jsonAPIErrResponse) Write(g *gin.Context) { func (j jsonAPIErrResponse) Write(g *gin.Context) {
j.err.Output(g) j.err.Output(g)
j.err.CallListener(exerr.MethodOutput)
} }
func (j jsonAPIErrResponse) WithHeader(k string, v string) HTTPResponse { func (j jsonAPIErrResponse) WithHeader(k string, v string) HTTPResponse {

View File

@@ -1,5 +1,5 @@
package goext package goext
const GoextVersion = "0.0.359" const GoextVersion = "0.0.362"
const GoextVersionTimestamp = "2024-01-05T16:55:53+0100" const GoextVersionTimestamp = "2024-01-07T04:18:03+0100"

View File

@@ -12,5 +12,8 @@ func CalcPaginationTotalPages(totalItems int, limit int) int {
if totalItems == 0 { if totalItems == 0 {
return 0 return 0
} }
if limit == 0 {
return 0
}
return 1 + (totalItems-1)/limit return 1 + (totalItems-1)/limit
} }

View File

@@ -4,6 +4,7 @@ import (
"encoding/json" "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/rfctime"
"reflect" "reflect"
@@ -105,6 +106,40 @@ var ConverterJsonArrToString = NewDBTypeConverter[JsonArr, string](func(v JsonAr
return mrsh, nil 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 any] struct { type dbTypeConverterImpl[TModelData any, TDBData any] struct {
dbTypeString string dbTypeString string
modelTypeString string modelTypeString string

View File

@@ -150,4 +150,7 @@ func (db *database) RegisterDefaultConverter() {
db.RegisterConverter(ConverterRFC339NanoTimeToString) db.RegisterConverter(ConverterRFC339NanoTimeToString)
db.RegisterConverter(ConverterJsonObjToString) db.RegisterConverter(ConverterJsonObjToString)
db.RegisterConverter(ConverterJsonArrToString) db.RegisterConverter(ConverterJsonArrToString)
db.RegisterConverter(ConverterExErrCategoryToString)
db.RegisterConverter(ConverterExErrSeverityToString)
db.RegisterConverter(ConverterExErrTypeToString)
} }