Compare commits
	
		
			15 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 303bd04649 | |||
| 7bda674939 | |||
| 126d4fbd0b | |||
| fed8bccaab | |||
| 47b6a6b508 | |||
| 764ce79a71 | |||
| b876c64ba2 | |||
| 8d52b41f57 | |||
| f47e2a33fe | |||
| 9321938dad | |||
| 3828d601a2 | |||
| 2e713c808d | |||
| 6602f86b43 | |||
| 24d9f0fdc7 | |||
| 8446b2da22 | 
| @@ -441,9 +441,9 @@ func (b *Builder) Output(ctx context.Context, g *gin.Context) { | |||||||
|  |  | ||||||
| 	b.errorData.Output(g) | 	b.errorData.Output(g) | ||||||
|  |  | ||||||
| 	if b.errorData.Severity == SevErr || b.errorData.Severity == SevFatal { | 	if (b.errorData.Severity == SevErr || b.errorData.Severity == SevFatal) && (pkgconfig.ZeroLogErrGinOutput || pkgconfig.ZeroLogAllGinOutput) { | ||||||
| 		b.errorData.Log(stackSkipLogger.Error()) | 		b.errorData.Log(stackSkipLogger.Error()) | ||||||
| 	} else if b.errorData.Severity == SevWarn { | 	} else if (b.errorData.Severity == SevWarn) && (pkgconfig.ZeroLogAllGinOutput) { | ||||||
| 		b.errorData.Log(stackSkipLogger.Warn()) | 		b.errorData.Log(stackSkipLogger.Warn()) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|   | |||||||
| @@ -181,7 +181,7 @@ func getReflectedMetaValues(value interface{}, remainingDepth int) map[string]Me | |||||||
|  |  | ||||||
| 	jsonval, err := json.Marshal(value) | 	jsonval, err := json.Marshal(value) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		panic(err) // gets recovered later up | 		return map[string]MetaValue{"": {DataType: MDTString, Value: fmt.Sprintf("Failed to Marshal %T:\n%+v", value, value)}} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return map[string]MetaValue{"": {DataType: MDTString, Value: string(jsonval)}} | 	return map[string]MetaValue{"": {DataType: MDTString, Value: string(jsonval)}} | ||||||
|   | |||||||
| @@ -14,6 +14,8 @@ type ErrorPackageConfig struct { | |||||||
| 	ExtendGinOutput        func(err *ExErr, json map[string]any)            // (Optionally) extend the gin output with more fields | 	ExtendGinOutput        func(err *ExErr, json map[string]any)            // (Optionally) extend the gin output with more fields | ||||||
| 	ExtendGinDataOutput    func(err *ExErr, depth int, json map[string]any) // (Optionally) extend the gin `__data` output with more fields | 	ExtendGinDataOutput    func(err *ExErr, depth int, json map[string]any) // (Optionally) extend the gin `__data` output with more fields | ||||||
| 	DisableErrorWrapping   bool                                             // Disables the exerr.Wrap()...Build() function - will always return the original error | 	DisableErrorWrapping   bool                                             // Disables the exerr.Wrap()...Build() function - will always return the original error | ||||||
|  | 	ZeroLogErrGinOutput    bool                                             // autom print zerolog logs on ginext.Error() / .Output(gin)  (for SevErr and SevFatal) | ||||||
|  | 	ZeroLogAllGinOutput    bool                                             // autom print zerolog logs on ginext.Error() / .Output(gin)  (for all Severities) | ||||||
| } | } | ||||||
|  |  | ||||||
| type ErrorPackageConfigInit struct { | type ErrorPackageConfigInit struct { | ||||||
| @@ -25,6 +27,8 @@ type ErrorPackageConfigInit struct { | |||||||
| 	ExtendGinOutput        func(err *ExErr, json map[string]any) | 	ExtendGinOutput        func(err *ExErr, json map[string]any) | ||||||
| 	ExtendGinDataOutput    func(err *ExErr, depth int, json map[string]any) | 	ExtendGinDataOutput    func(err *ExErr, depth int, json map[string]any) | ||||||
| 	DisableErrorWrapping   *bool | 	DisableErrorWrapping   *bool | ||||||
|  | 	ZeroLogErrGinOutput    *bool | ||||||
|  | 	ZeroLogAllGinOutput    *bool | ||||||
| } | } | ||||||
|  |  | ||||||
| var initialized = false | var initialized = false | ||||||
| @@ -38,6 +42,8 @@ var pkgconfig = ErrorPackageConfig{ | |||||||
| 	ExtendGinOutput:        func(err *ExErr, json map[string]any) {}, | 	ExtendGinOutput:        func(err *ExErr, json map[string]any) {}, | ||||||
| 	ExtendGinDataOutput:    func(err *ExErr, depth int, json map[string]any) {}, | 	ExtendGinDataOutput:    func(err *ExErr, depth int, json map[string]any) {}, | ||||||
| 	DisableErrorWrapping:   false, | 	DisableErrorWrapping:   false, | ||||||
|  | 	ZeroLogErrGinOutput:    true, | ||||||
|  | 	ZeroLogAllGinOutput:    false, | ||||||
| } | } | ||||||
|  |  | ||||||
| // Init initializes the exerr packages | // Init initializes the exerr packages | ||||||
| @@ -67,6 +73,8 @@ func Init(cfg ErrorPackageConfigInit) { | |||||||
| 		ExtendGinOutput:        ego, | 		ExtendGinOutput:        ego, | ||||||
| 		ExtendGinDataOutput:    egdo, | 		ExtendGinDataOutput:    egdo, | ||||||
| 		DisableErrorWrapping:   langext.Coalesce(cfg.DisableErrorWrapping, pkgconfig.DisableErrorWrapping), | 		DisableErrorWrapping:   langext.Coalesce(cfg.DisableErrorWrapping, pkgconfig.DisableErrorWrapping), | ||||||
|  | 		ZeroLogAllGinOutput:    langext.Coalesce(cfg.ZeroLogAllGinOutput, pkgconfig.ZeroLogAllGinOutput), | ||||||
|  | 		ZeroLogErrGinOutput:    langext.Coalesce(cfg.ZeroLogErrGinOutput, pkgconfig.ZeroLogErrGinOutput), | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	initialized = true | 	initialized = true | ||||||
|   | |||||||
| @@ -15,10 +15,10 @@ func (ee *ExErr) toJson(depth int, applyExtendListener bool, outputMeta bool) la | |||||||
| 		ginJson["id"] = ee.UniqueID | 		ginJson["id"] = ee.UniqueID | ||||||
| 	} | 	} | ||||||
| 	if ee.Category != CatWrap { | 	if ee.Category != CatWrap { | ||||||
| 		ginJson["category"] = ee.Category | 		ginJson["category"] = ee.Category.Category | ||||||
| 	} | 	} | ||||||
| 	if ee.Type != TypeWrap { | 	if ee.Type != TypeWrap { | ||||||
| 		ginJson["type"] = ee.Type | 		ginJson["type"] = ee.Type.Key | ||||||
| 	} | 	} | ||||||
| 	if ee.StatusCode != nil { | 	if ee.StatusCode != nil { | ||||||
| 		ginJson["statuscode"] = ee.StatusCode | 		ginJson["statuscode"] = ee.StatusCode | ||||||
| @@ -30,7 +30,7 @@ func (ee *ExErr) toJson(depth int, applyExtendListener bool, outputMeta bool) la | |||||||
| 		ginJson["caller"] = ee.Caller | 		ginJson["caller"] = ee.Caller | ||||||
| 	} | 	} | ||||||
| 	if ee.Severity != SevErr { | 	if ee.Severity != SevErr { | ||||||
| 		ginJson["severity"] = ee.Severity | 		ginJson["severity"] = ee.Severity.Severity | ||||||
| 	} | 	} | ||||||
| 	if ee.Timestamp != (time.Time{}) { | 	if ee.Timestamp != (time.Time{}) { | ||||||
| 		ginJson["time"] = ee.Timestamp.Format(time.RFC3339) | 		ginJson["time"] = ee.Timestamp.Format(time.RFC3339) | ||||||
|   | |||||||
| @@ -19,6 +19,7 @@ type GinWrapper struct { | |||||||
| 	engine          *gin.Engine | 	engine          *gin.Engine | ||||||
| 	suppressGinLogs bool | 	suppressGinLogs bool | ||||||
|  |  | ||||||
|  | 	opt                   Options | ||||||
| 	allowCors             bool | 	allowCors             bool | ||||||
| 	ginDebug              bool | 	ginDebug              bool | ||||||
| 	bufferBody            bool | 	bufferBody            bool | ||||||
| @@ -37,13 +38,15 @@ type ginRouteSpec struct { | |||||||
| } | } | ||||||
|  |  | ||||||
| type Options struct { | type Options struct { | ||||||
| 	AllowCors             *bool                                     // Add cors handler to allow all CORS requests on the default http methods | 	AllowCors                *bool                                     // Add cors handler to allow all CORS requests on the default http methods | ||||||
| 	GinDebug              *bool                                     // Set gin.debug to true (adds more logs) | 	GinDebug                 *bool                                     // Set gin.debug to true (adds more logs) | ||||||
| 	SuppressGinLogs       *bool                                     // Suppress our custom gin logs (even if GinDebug == true) | 	SuppressGinLogs          *bool                                     // Suppress our custom gin logs (even if GinDebug == true) | ||||||
| 	BufferBody            *bool                                     // Buffers the input body stream, this way the ginext error handler can later include the whole request body | 	BufferBody               *bool                                     // Buffers the input body stream, this way the ginext error handler can later include the whole request body | ||||||
| 	Timeout               *time.Duration                            // The default handler timeout | 	Timeout                  *time.Duration                            // The default handler timeout | ||||||
| 	ListenerBeforeRequest []func(g *gin.Context)                    // Register listener that are called before the handler method | 	ListenerBeforeRequest    []func(g *gin.Context)                    // Register listener that are called before the handler method | ||||||
| 	ListenerAfterRequest  []func(g *gin.Context, resp HTTPResponse) // Register listener that are called after the handler method | 	ListenerAfterRequest     []func(g *gin.Context, resp HTTPResponse) // Register listener that are called after the handler method | ||||||
|  | 	DebugTrimHandlerPrefixes []string                                  // Trim these prefixes from the handler names in the debug print | ||||||
|  | 	DebugReplaceHandlerNames map[string]string                         // Replace handler names in debug output | ||||||
| } | } | ||||||
|  |  | ||||||
| // NewEngine creates a new (wrapped) ginEngine | // NewEngine creates a new (wrapped) ginEngine | ||||||
| @@ -52,6 +55,7 @@ func NewEngine(opt Options) *GinWrapper { | |||||||
|  |  | ||||||
| 	wrapper := &GinWrapper{ | 	wrapper := &GinWrapper{ | ||||||
| 		engine:                engine, | 		engine:                engine, | ||||||
|  | 		opt:                   opt, | ||||||
| 		suppressGinLogs:       langext.Coalesce(opt.SuppressGinLogs, false), | 		suppressGinLogs:       langext.Coalesce(opt.SuppressGinLogs, false), | ||||||
| 		allowCors:             langext.Coalesce(opt.AllowCors, false), | 		allowCors:             langext.Coalesce(opt.AllowCors, false), | ||||||
| 		ginDebug:              langext.Coalesce(opt.GinDebug, true), | 		ginDebug:              langext.Coalesce(opt.GinDebug, true), | ||||||
| @@ -185,6 +189,18 @@ func (w *GinWrapper) cleanMiddlewareName(fname string) string { | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	for _, pfx := range w.opt.DebugTrimHandlerPrefixes { | ||||||
|  | 		if strings.HasPrefix(fname, pfx) { | ||||||
|  | 			fname = fname[len(pfx):] | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	for k, v := range langext.ForceMap(w.opt.DebugReplaceHandlerNames) { | ||||||
|  | 		if strings.EqualFold(fname, k) { | ||||||
|  | 			fname = v | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	return fname | 	return fname | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,6 +1,7 @@ | |||||||
| package ginext | package ginext | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
|  | 	"context" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"github.com/gin-gonic/gin" | 	"github.com/gin-gonic/gin" | ||||||
| 	"gogs.mikescher.com/BlackForestBytes/goext/exerr" | 	"gogs.mikescher.com/BlackForestBytes/goext/exerr" | ||||||
| @@ -410,7 +411,8 @@ func (j jsonAPIErrResponse) Write(g *gin.Context) { | |||||||
| 	for _, v := range j.cookies { | 	for _, v := range j.cookies { | ||||||
| 		g.SetCookie(v.name, v.value, v.maxAge, v.path, v.domain, v.secure, v.httpOnly) | 		g.SetCookie(v.name, v.value, v.maxAge, v.path, v.domain, v.secure, v.httpOnly) | ||||||
| 	} | 	} | ||||||
| 	j.err.Output(g) |  | ||||||
|  | 	exerr.Get(j.err).Output(context.Background(), g) | ||||||
|  |  | ||||||
| 	j.err.CallListener(exerr.MethodOutput) | 	j.err.CallListener(exerr.MethodOutput) | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										15
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								go.mod
									
									
									
									
									
								
							| @@ -5,19 +5,22 @@ go 1.22 | |||||||
| require ( | require ( | ||||||
| 	github.com/gin-gonic/gin v1.9.1 | 	github.com/gin-gonic/gin v1.9.1 | ||||||
| 	github.com/glebarez/go-sqlite v1.22.0 // only needed for tests -.- | 	github.com/glebarez/go-sqlite v1.22.0 // only needed for tests -.- | ||||||
| 	github.com/jmoiron/sqlx v1.3.5 | 	github.com/jmoiron/sqlx v1.4.0 | ||||||
| 	github.com/rs/xid v1.5.0 | 	github.com/rs/xid v1.5.0 | ||||||
| 	github.com/rs/zerolog v1.32.0 | 	github.com/rs/zerolog v1.32.0 | ||||||
| 	go.mongodb.org/mongo-driver v1.14.0 | 	go.mongodb.org/mongo-driver v1.15.0 | ||||||
| 	golang.org/x/crypto v0.22.0 | 	golang.org/x/crypto v0.22.0 | ||||||
| 	golang.org/x/sys v0.19.0 | 	golang.org/x/sys v0.19.0 | ||||||
| 	golang.org/x/term v0.19.0 | 	golang.org/x/term v0.19.0 | ||||||
| ) | ) | ||||||
|  |  | ||||||
| require ( | require ( | ||||||
| 	github.com/bytedance/sonic v1.11.3 // indirect | 	github.com/bytedance/sonic v1.11.6 // indirect | ||||||
|  | 	github.com/bytedance/sonic/loader v0.1.1 // indirect | ||||||
| 	github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect | 	github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect | ||||||
| 	github.com/chenzhuoyu/iasm v0.9.1 // indirect | 	github.com/chenzhuoyu/iasm v0.9.1 // indirect | ||||||
|  | 	github.com/cloudwego/base64x v0.1.4 // indirect | ||||||
|  | 	github.com/cloudwego/iasm v0.2.0 // indirect | ||||||
| 	github.com/dustin/go-humanize v1.0.1 // indirect | 	github.com/dustin/go-humanize v1.0.1 // indirect | ||||||
| 	github.com/gabriel-vasile/mimetype v1.4.3 // indirect | 	github.com/gabriel-vasile/mimetype v1.4.3 // indirect | ||||||
| 	github.com/gin-contrib/sse v0.1.0 // indirect | 	github.com/gin-contrib/sse v0.1.0 // indirect | ||||||
| @@ -28,7 +31,7 @@ require ( | |||||||
| 	github.com/golang/snappy v0.0.4 // indirect | 	github.com/golang/snappy v0.0.4 // indirect | ||||||
| 	github.com/google/uuid v1.5.0 // indirect | 	github.com/google/uuid v1.5.0 // indirect | ||||||
| 	github.com/json-iterator/go v1.1.12 // indirect | 	github.com/json-iterator/go v1.1.12 // indirect | ||||||
| 	github.com/klauspost/compress v1.17.7 // indirect | 	github.com/klauspost/compress v1.17.8 // indirect | ||||||
| 	github.com/klauspost/cpuid/v2 v2.2.7 // indirect | 	github.com/klauspost/cpuid/v2 v2.2.7 // indirect | ||||||
| 	github.com/leodido/go-urn v1.4.0 // indirect | 	github.com/leodido/go-urn v1.4.0 // indirect | ||||||
| 	github.com/mattn/go-colorable v0.1.13 // indirect | 	github.com/mattn/go-colorable v0.1.13 // indirect | ||||||
| @@ -36,14 +39,14 @@ require ( | |||||||
| 	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect | 	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect | ||||||
| 	github.com/modern-go/reflect2 v1.0.2 // indirect | 	github.com/modern-go/reflect2 v1.0.2 // indirect | ||||||
| 	github.com/montanaflynn/stats v0.7.1 // indirect | 	github.com/montanaflynn/stats v0.7.1 // indirect | ||||||
| 	github.com/pelletier/go-toml/v2 v2.2.0 // indirect | 	github.com/pelletier/go-toml/v2 v2.2.1 // indirect | ||||||
| 	github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect | 	github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect | ||||||
| 	github.com/twitchyliquid64/golang-asm v0.15.1 // indirect | 	github.com/twitchyliquid64/golang-asm v0.15.1 // indirect | ||||||
| 	github.com/ugorji/go/codec v1.2.12 // indirect | 	github.com/ugorji/go/codec v1.2.12 // indirect | ||||||
| 	github.com/xdg-go/pbkdf2 v1.0.0 // indirect | 	github.com/xdg-go/pbkdf2 v1.0.0 // indirect | ||||||
| 	github.com/xdg-go/scram v1.1.2 // indirect | 	github.com/xdg-go/scram v1.1.2 // indirect | ||||||
| 	github.com/xdg-go/stringprep v1.0.4 // indirect | 	github.com/xdg-go/stringprep v1.0.4 // indirect | ||||||
| 	github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a // indirect | 	github.com/youmark/pkcs8 v0.0.0-20240424034433-3c2c7870ae76 // indirect | ||||||
| 	golang.org/x/arch v0.7.0 // indirect | 	golang.org/x/arch v0.7.0 // indirect | ||||||
| 	golang.org/x/net v0.24.0 // indirect | 	golang.org/x/net v0.24.0 // indirect | ||||||
| 	golang.org/x/sync v0.7.0 // indirect | 	golang.org/x/sync v0.7.0 // indirect | ||||||
|   | |||||||
							
								
								
									
										35
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										35
									
								
								go.sum
									
									
									
									
									
								
							| @@ -1,3 +1,4 @@ | |||||||
|  | filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= | ||||||
| github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= | github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= | ||||||
| github.com/bytedance/sonic v1.10.0-rc/go.mod h1:ElCzW+ufi8qKqNW0FY314xriJhyJhuoJ3gFZdAHF7NM= | github.com/bytedance/sonic v1.10.0-rc/go.mod h1:ElCzW+ufi8qKqNW0FY314xriJhyJhuoJ3gFZdAHF7NM= | ||||||
| github.com/bytedance/sonic v1.10.2 h1:GQebETVBxYB7JGWJtLBi07OVzWwt+8dWA00gEVW2ZFE= | github.com/bytedance/sonic v1.10.2 h1:GQebETVBxYB7JGWJtLBi07OVzWwt+8dWA00gEVW2ZFE= | ||||||
| @@ -10,6 +11,15 @@ github.com/bytedance/sonic v1.11.2 h1:ywfwo0a/3j9HR8wsYGWsIWl2mvRsI950HyoxiBERw5 | |||||||
| github.com/bytedance/sonic v1.11.2/go.mod h1:iZcSUejdk5aukTND/Eu/ivjQuEL0Cu9/rf50Hi0u/g4= | github.com/bytedance/sonic v1.11.2/go.mod h1:iZcSUejdk5aukTND/Eu/ivjQuEL0Cu9/rf50Hi0u/g4= | ||||||
| github.com/bytedance/sonic v1.11.3 h1:jRN+yEjakWh8aK5FzrciUHG8OFXK+4/KrAX/ysEtHAA= | github.com/bytedance/sonic v1.11.3 h1:jRN+yEjakWh8aK5FzrciUHG8OFXK+4/KrAX/ysEtHAA= | ||||||
| github.com/bytedance/sonic v1.11.3/go.mod h1:iZcSUejdk5aukTND/Eu/ivjQuEL0Cu9/rf50Hi0u/g4= | github.com/bytedance/sonic v1.11.3/go.mod h1:iZcSUejdk5aukTND/Eu/ivjQuEL0Cu9/rf50Hi0u/g4= | ||||||
|  | github.com/bytedance/sonic v1.11.4 h1:8+OMLSSDDm2/qJc6ld5K5Sm62NK9VHcUKk0NzBoMAM4= | ||||||
|  | github.com/bytedance/sonic v1.11.4/go.mod h1:YrWEqYtlBPS6LUA0vpuG79a1trsh4Ae41uWUWUreHhE= | ||||||
|  | github.com/bytedance/sonic v1.11.5 h1:G00FYjjqll5iQ1PYXynbg/hyzqBqavH8Mo9/oTopd9k= | ||||||
|  | github.com/bytedance/sonic v1.11.5/go.mod h1:X2PC2giUdj/Cv2lliWFLk6c/DUQok5rViJSemeB0wDw= | ||||||
|  | github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc0= | ||||||
|  | github.com/bytedance/sonic v1.11.6/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4= | ||||||
|  | github.com/bytedance/sonic/loader v0.1.0/go.mod h1:UmRT+IRTGKz/DAkzcEGzyVqQFJ7H9BqwBO3pm9H/+HY= | ||||||
|  | github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM= | ||||||
|  | github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= | ||||||
| github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY= | github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY= | ||||||
| github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk= | github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk= | ||||||
| github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d h1:77cEq6EriyTZ0g/qfRdp61a3Uu/AWrgIq2s0ClJV1g0= | github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d h1:77cEq6EriyTZ0g/qfRdp61a3Uu/AWrgIq2s0ClJV1g0= | ||||||
| @@ -17,6 +27,17 @@ github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d/go.mod h1:8EPpV | |||||||
| github.com/chenzhuoyu/iasm v0.9.0/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog= | github.com/chenzhuoyu/iasm v0.9.0/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog= | ||||||
| github.com/chenzhuoyu/iasm v0.9.1 h1:tUHQJXo3NhBqw6s33wkGn9SP3bvrWLdlVIJ3hQBL7P0= | github.com/chenzhuoyu/iasm v0.9.1 h1:tUHQJXo3NhBqw6s33wkGn9SP3bvrWLdlVIJ3hQBL7P0= | ||||||
| github.com/chenzhuoyu/iasm v0.9.1/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog= | github.com/chenzhuoyu/iasm v0.9.1/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog= | ||||||
|  | github.com/cloudwego/base64x v0.1.0 h1:Tg5q9tq1khq9Y9UwfoC6zkHK0FypN2GLDvhqFceOL8U= | ||||||
|  | github.com/cloudwego/base64x v0.1.0/go.mod h1:lM8nFiNbg74QgesNo6EAtv8N9tlRjBWExmHoNDa3PkU= | ||||||
|  | github.com/cloudwego/base64x v0.1.3 h1:b5J/l8xolB7dyDTTmhJP2oTs5LdrjyrUFuNxdfq5hAg= | ||||||
|  | github.com/cloudwego/base64x v0.1.3/go.mod h1:1+1K5BUHIQzyapgpF7LwvOGAEDicKtt1umPV+aN8pi8= | ||||||
|  | github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y= | ||||||
|  | github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= | ||||||
|  | github.com/cloudwego/iasm v0.0.9/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= | ||||||
|  | github.com/cloudwego/iasm v0.1.0 h1:q0OuhwWDMyi3nlrQ6kIr0Yx0c3FI6cq/OZWKodIDdz8= | ||||||
|  | github.com/cloudwego/iasm v0.1.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= | ||||||
|  | github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg= | ||||||
|  | github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= | ||||||
| github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= | github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= | ||||||
| github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||||||
| github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= | ||||||
| @@ -47,6 +68,8 @@ github.com/go-playground/validator/v10 v10.19.0 h1:ol+5Fu+cSq9JD7SoSqe04GMI92cbn | |||||||
| github.com/go-playground/validator/v10 v10.19.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= | github.com/go-playground/validator/v10 v10.19.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= | ||||||
| github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= | github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= | ||||||
| github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= | github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= | ||||||
|  | github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= | ||||||
|  | github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= | ||||||
| github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= | github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= | ||||||
| github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= | github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= | ||||||
| github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= | github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= | ||||||
| @@ -64,6 +87,8 @@ github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU= | |||||||
| github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= | github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= | ||||||
| github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g= | github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g= | ||||||
| github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ= | github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ= | ||||||
|  | github.com/jmoiron/sqlx v1.4.0 h1:1PLqN7S1UYp5t4SrVVnt4nUVNemrDAtxlulVe+Qgm3o= | ||||||
|  | github.com/jmoiron/sqlx v1.4.0/go.mod h1:ZrZ7UsYB/weZdl2Bxg6jCRO9c3YHl8r3ahlKmRT4JLY= | ||||||
| github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= | github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= | ||||||
| github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= | github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= | ||||||
| github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= | github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= | ||||||
| @@ -73,6 +98,8 @@ github.com/klauspost/compress v1.17.6 h1:60eq2E/jlfwQXtvZEeBUYADs+BwKBWURIY+Gj2e | |||||||
| github.com/klauspost/compress v1.17.6/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= | github.com/klauspost/compress v1.17.6/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= | ||||||
| github.com/klauspost/compress v1.17.7 h1:ehO88t2UGzQK66LMdE8tibEd1ErmzZjNEqWkjLAKQQg= | github.com/klauspost/compress v1.17.7 h1:ehO88t2UGzQK66LMdE8tibEd1ErmzZjNEqWkjLAKQQg= | ||||||
| github.com/klauspost/compress v1.17.7/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= | github.com/klauspost/compress v1.17.7/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= | ||||||
|  | github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU= | ||||||
|  | github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= | ||||||
| github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= | github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= | ||||||
| github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/48xc= | github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/48xc= | ||||||
| github.com/klauspost/cpuid/v2 v2.2.6/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= | github.com/klauspost/cpuid/v2 v2.2.6/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= | ||||||
| @@ -85,6 +112,7 @@ github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= | |||||||
| github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= | github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= | ||||||
| github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0= | github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0= | ||||||
| github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= | github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= | ||||||
|  | github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= | ||||||
| github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= | github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= | ||||||
| github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= | github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= | ||||||
| github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= | github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= | ||||||
| @@ -94,6 +122,7 @@ github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D | |||||||
| github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= | github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= | ||||||
| github.com/mattn/go-sqlite3 v1.14.19 h1:fhGleo2h1p8tVChob4I9HpmVFIAkKGpiukdrgQbWfGI= | github.com/mattn/go-sqlite3 v1.14.19 h1:fhGleo2h1p8tVChob4I9HpmVFIAkKGpiukdrgQbWfGI= | ||||||
| github.com/mattn/go-sqlite3 v1.14.19/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= | github.com/mattn/go-sqlite3 v1.14.19/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= | ||||||
|  | github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= | ||||||
| github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= | ||||||
| github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= | ||||||
| github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= | ||||||
| @@ -106,6 +135,8 @@ github.com/pelletier/go-toml/v2 v2.1.1 h1:LWAJwfNvjQZCFIDKWYQaM62NcYeYViCmWIwmOS | |||||||
| github.com/pelletier/go-toml/v2 v2.1.1/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= | github.com/pelletier/go-toml/v2 v2.1.1/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= | ||||||
| github.com/pelletier/go-toml/v2 v2.2.0 h1:QLgLl2yMN7N+ruc31VynXs1vhMZa7CeHHejIeBAsoHo= | github.com/pelletier/go-toml/v2 v2.2.0 h1:QLgLl2yMN7N+ruc31VynXs1vhMZa7CeHHejIeBAsoHo= | ||||||
| github.com/pelletier/go-toml/v2 v2.2.0/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= | github.com/pelletier/go-toml/v2 v2.2.0/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= | ||||||
|  | github.com/pelletier/go-toml/v2 v2.2.1 h1:9TA9+T8+8CUCO2+WYnDLCgrYi9+omqKXyjDtosvtEhg= | ||||||
|  | github.com/pelletier/go-toml/v2 v2.2.1/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= | ||||||
| github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= | ||||||
| github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= | ||||||
| github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | ||||||
| @@ -144,11 +175,15 @@ github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gi | |||||||
| github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= | github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= | ||||||
| github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a h1:fZHgsYlfvtyqToslyjUt3VOPF4J7aK/3MPcK7xp3PDk= | github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a h1:fZHgsYlfvtyqToslyjUt3VOPF4J7aK/3MPcK7xp3PDk= | ||||||
| github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a/go.mod h1:ul22v+Nro/R083muKhosV54bj5niojjWZvU8xrevuH4= | github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a/go.mod h1:ul22v+Nro/R083muKhosV54bj5niojjWZvU8xrevuH4= | ||||||
|  | github.com/youmark/pkcs8 v0.0.0-20240424034433-3c2c7870ae76 h1:tBiBTKHnIjovYoLX/TPkcf+OjqqKGQrPtGT3Foz+Pgo= | ||||||
|  | github.com/youmark/pkcs8 v0.0.0-20240424034433-3c2c7870ae76/go.mod h1:SQliXeA7Dhkt//vS29v3zpbEwoa+zb2Cn5xj5uO4K5U= | ||||||
| github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= | github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= | ||||||
| go.mongodb.org/mongo-driver v1.13.1 h1:YIc7HTYsKndGK4RFzJ3covLz1byri52x0IoMB0Pt/vk= | go.mongodb.org/mongo-driver v1.13.1 h1:YIc7HTYsKndGK4RFzJ3covLz1byri52x0IoMB0Pt/vk= | ||||||
| go.mongodb.org/mongo-driver v1.13.1/go.mod h1:wcDf1JBCXy2mOW0bWHwO/IOYqdca1MPCwDtFu/Z9+eo= | go.mongodb.org/mongo-driver v1.13.1/go.mod h1:wcDf1JBCXy2mOW0bWHwO/IOYqdca1MPCwDtFu/Z9+eo= | ||||||
| go.mongodb.org/mongo-driver v1.14.0 h1:P98w8egYRjYe3XDjxhYJagTokP/H6HzlsnojRgZRd80= | go.mongodb.org/mongo-driver v1.14.0 h1:P98w8egYRjYe3XDjxhYJagTokP/H6HzlsnojRgZRd80= | ||||||
| go.mongodb.org/mongo-driver v1.14.0/go.mod h1:Vzb0Mk/pa7e6cWw85R4F/endUC3u0U9jGcNU603k65c= | go.mongodb.org/mongo-driver v1.14.0/go.mod h1:Vzb0Mk/pa7e6cWw85R4F/endUC3u0U9jGcNU603k65c= | ||||||
|  | go.mongodb.org/mongo-driver v1.15.0 h1:rJCKC8eEliewXjZGf0ddURtl7tTVy1TK3bfl0gkUSLc= | ||||||
|  | go.mongodb.org/mongo-driver v1.15.0/go.mod h1:Vzb0Mk/pa7e6cWw85R4F/endUC3u0U9jGcNU603k65c= | ||||||
| golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= | golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= | ||||||
| golang.org/x/arch v0.7.0 h1:pskyeJh/3AmoQ8CPE95vxHLqp1G1GfGNXTmcl9NEKTc= | golang.org/x/arch v0.7.0 h1:pskyeJh/3AmoQ8CPE95vxHLqp1G1GfGNXTmcl9NEKTc= | ||||||
| golang.org/x/arch v0.7.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= | golang.org/x/arch v0.7.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| package goext | package goext | ||||||
|  |  | ||||||
| const GoextVersion = "0.0.427" | const GoextVersion = "0.0.442" | ||||||
|  |  | ||||||
| const GoextVersionTimestamp = "2024-04-07T15:10:21+0200" | const GoextVersionTimestamp = "2024-04-29T17:24:10+0200" | ||||||
|   | |||||||
| @@ -477,6 +477,10 @@ func ArrRemove[T comparable](arr []T, needle T) []T { | |||||||
| 	return arr | 	return arr | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func ArrRemoveAt[T any](arr []T, idx int) []T { | ||||||
|  | 	return append(arr[:idx], arr[idx+1:]...) | ||||||
|  | } | ||||||
|  |  | ||||||
| func ArrExcept[T comparable](arr []T, needles ...T) []T { | func ArrExcept[T comparable](arr []T, needles ...T) []T { | ||||||
| 	r := make([]T, 0, len(arr)) | 	r := make([]T, 0, len(arr)) | ||||||
| 	rmlist := ArrToSet(needles) | 	rmlist := ArrToSet(needles) | ||||||
|   | |||||||
| @@ -63,3 +63,51 @@ func PatchRemJson[JV string | []byte](rawjson JV, key string) (JV, error) { | |||||||
|  |  | ||||||
| 	return JV(newjson), nil | 	return JV(newjson), nil | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func MarshalJsonOrPanic(v any) string { | ||||||
|  | 	bin, err := json.Marshal(v) | ||||||
|  | 	if err != nil { | ||||||
|  | 		panic(err) | ||||||
|  | 	} | ||||||
|  | 	return string(bin) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func MarshalJsonOrDefault(v any, def string) string { | ||||||
|  | 	bin, err := json.Marshal(v) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return def | ||||||
|  | 	} | ||||||
|  | 	return string(bin) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func MarshalJsonOrNil(v any) *string { | ||||||
|  | 	bin, err := json.Marshal(v) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | 	return Ptr(string(bin)) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func MarshalJsonIndentOrPanic(v any, prefix, indent string) string { | ||||||
|  | 	bin, err := json.MarshalIndent(v, prefix, indent) | ||||||
|  | 	if err != nil { | ||||||
|  | 		panic(err) | ||||||
|  | 	} | ||||||
|  | 	return string(bin) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func MarshalJsonIndentOrDefault(v any, prefix, indent string, def string) string { | ||||||
|  | 	bin, err := json.MarshalIndent(v, prefix, indent) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return def | ||||||
|  | 	} | ||||||
|  | 	return string(bin) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func MarshalJsonIndentOrNil(v any, prefix, indent string) *string { | ||||||
|  | 	bin, err := json.MarshalIndent(v, prefix, indent) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | 	return Ptr(string(bin)) | ||||||
|  | } | ||||||
|   | |||||||
| @@ -27,6 +27,10 @@ func DblPtrNil[T any]() **T { | |||||||
| 	return &v | 	return &v | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func ArrPtr[T any](v ...T) *[]T { | ||||||
|  | 	return &v | ||||||
|  | } | ||||||
|  |  | ||||||
| func PtrInt32(v int32) *int32 { | func PtrInt32(v int32) *int32 { | ||||||
| 	return &v | 	return &v | ||||||
| } | } | ||||||
|   | |||||||
| @@ -2,29 +2,44 @@ package reflectext | |||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"encoding/json" | 	"encoding/json" | ||||||
|  | 	"gogs.mikescher.com/BlackForestBytes/goext/langext" | ||||||
| 	"reflect" | 	"reflect" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| type ConvertStructToMapOpt struct { | type ConvertStructToMapOpt struct { | ||||||
| 	KeepJsonMarshalTypes bool | 	KeepJsonMarshalTypes bool | ||||||
|  | 	MaxDepth             *int | ||||||
| } | } | ||||||
|  |  | ||||||
| func ConvertStructToMap(v any, opts ...ConvertStructToMapOpt) any { | func ConvertStructToMap(v any, opts ...ConvertStructToMapOpt) map[string]any { | ||||||
| 	opt := ConvertStructToMapOpt{} | 	opt := ConvertStructToMapOpt{} | ||||||
| 	if len(opts) > 0 { | 	if len(opts) > 0 { | ||||||
| 		opt = opts[0] | 		opt = opts[0] | ||||||
| 	} | 	} | ||||||
| 	return reflectToMap(reflect.ValueOf(v), opt) |  | ||||||
|  | 	res := reflectToMap(reflect.ValueOf(v), 1, opt) | ||||||
|  |  | ||||||
|  | 	if v, ok := res.(map[string]any); ok { | ||||||
|  | 		return v | ||||||
|  | 	} else if langext.IsNil(res) { | ||||||
|  | 		return nil | ||||||
|  | 	} else { | ||||||
|  | 		panic("not an object") | ||||||
|  | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| func reflectToMap(fv reflect.Value, opt ConvertStructToMapOpt) any { | func reflectToMap(fv reflect.Value, depth int, opt ConvertStructToMapOpt) any { | ||||||
|  |  | ||||||
|  | 	if opt.MaxDepth != nil && depth > *opt.MaxDepth { | ||||||
|  | 		return fv.Interface() | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	if fv.Kind() == reflect.Ptr { | 	if fv.Kind() == reflect.Ptr { | ||||||
|  |  | ||||||
| 		if fv.IsNil() { | 		if fv.IsNil() { | ||||||
| 			return nil | 			return nil | ||||||
| 		} else { | 		} else { | ||||||
| 			return reflectToMap(fv.Elem(), opt) | 			return reflectToMap(fv.Elem(), depth, opt) | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 	} | 	} | ||||||
| @@ -41,7 +56,7 @@ func reflectToMap(fv reflect.Value, opt ConvertStructToMapOpt) any { | |||||||
| 		arrlen := fv.Len() | 		arrlen := fv.Len() | ||||||
| 		arr := make([]any, arrlen) | 		arr := make([]any, arrlen) | ||||||
| 		for i := 0; i < arrlen; i++ { | 		for i := 0; i < arrlen; i++ { | ||||||
| 			arr[i] = reflectToMap(fv.Index(i), opt) | 			arr[i] = reflectToMap(fv.Index(i), depth+1, opt) | ||||||
| 		} | 		} | ||||||
| 		return arr | 		return arr | ||||||
|  |  | ||||||
| @@ -52,7 +67,7 @@ func reflectToMap(fv reflect.Value, opt ConvertStructToMapOpt) any { | |||||||
| 		arrlen := fv.Len() | 		arrlen := fv.Len() | ||||||
| 		arr := make([]any, arrlen) | 		arr := make([]any, arrlen) | ||||||
| 		for i := 0; i < arrlen; i++ { | 		for i := 0; i < arrlen; i++ { | ||||||
| 			arr[i] = reflectToMap(fv.Index(i), opt) | 			arr[i] = reflectToMap(fv.Index(i), depth+1, opt) | ||||||
| 		} | 		} | ||||||
| 		return arr | 		return arr | ||||||
|  |  | ||||||
| @@ -75,7 +90,7 @@ func reflectToMap(fv reflect.Value, opt ConvertStructToMapOpt) any { | |||||||
|  |  | ||||||
| 		for i := 0; i < fv.NumField(); i++ { | 		for i := 0; i < fv.NumField(); i++ { | ||||||
| 			if fv.Type().Field(i).IsExported() { | 			if fv.Type().Field(i).IsExported() { | ||||||
| 				res[fv.Type().Field(i).Name] = reflectToMap(fv.Field(i), opt) | 				res[fv.Type().Field(i).Name] = reflectToMap(fv.Field(i), depth+1, opt) | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										42
									
								
								reflectext/convertToMap_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								reflectext/convertToMap_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,42 @@ | |||||||
|  | package reflectext | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"gogs.mikescher.com/BlackForestBytes/goext/langext" | ||||||
|  | 	"testing" | ||||||
|  | 	"time" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | func TestConvertStructToMap(t *testing.T) { | ||||||
|  |  | ||||||
|  | 	type tst struct { | ||||||
|  | 		FieldA  int | ||||||
|  | 		FieldB  string | ||||||
|  | 		FieldC  time.Time | ||||||
|  | 		FieldD  []float64 | ||||||
|  | 		FieldE1 *int | ||||||
|  | 		FieldE2 **int | ||||||
|  | 		FieldE3 *int | ||||||
|  | 		FieldE4 **int | ||||||
|  | 		FieldE5 *int | ||||||
|  | 		FieldE6 **int | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	value := tst{ | ||||||
|  | 		FieldA:  123, | ||||||
|  | 		FieldB:  "hello", | ||||||
|  | 		FieldC:  time.Date(2020, 05, 12, 8, 30, 0, 0, time.UTC), | ||||||
|  | 		FieldD:  []float64{1, 2, 3, 4, 5, 6, 7}, | ||||||
|  | 		FieldE1: nil, | ||||||
|  | 		FieldE2: nil, | ||||||
|  | 		FieldE3: langext.Ptr(12), | ||||||
|  | 		FieldE4: langext.DblPtr(12), | ||||||
|  | 		FieldE5: nil, | ||||||
|  | 		FieldE6: langext.DblPtrNil[int](), | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	valueOut := ConvertStructToMap(value, ConvertStructToMapOpt{KeepJsonMarshalTypes: true}) | ||||||
|  |  | ||||||
|  | 	fmt.Printf("%+v\n", valueOut) | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -47,9 +47,3 @@ func TestGetMapField(t *testing.T) { | |||||||
| 	tst.AssertEqual(t, fmt.Sprint(GetMapField[PseudoInt](maany2, "Test")), "12 true") | 	tst.AssertEqual(t, fmt.Sprint(GetMapField[PseudoInt](maany2, "Test")), "12 true") | ||||||
| 	tst.AssertEqual(t, fmt.Sprint(GetMapField[PseudoInt](maany2, "Test2")), "0 false") | 	tst.AssertEqual(t, fmt.Sprint(GetMapField[PseudoInt](maany2, "Test2")), "0 false") | ||||||
| } | } | ||||||
|  |  | ||||||
| func main2() { |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func main() { |  | ||||||
| } |  | ||||||
|   | |||||||
| @@ -8,6 +8,7 @@ import ( | |||||||
| 	"go.mongodb.org/mongo-driver/bson/bsoncodec" | 	"go.mongodb.org/mongo-driver/bson/bsoncodec" | ||||||
| 	"go.mongodb.org/mongo-driver/bson/bsonrw" | 	"go.mongodb.org/mongo-driver/bson/bsonrw" | ||||||
| 	"go.mongodb.org/mongo-driver/bson/bsontype" | 	"go.mongodb.org/mongo-driver/bson/bsontype" | ||||||
|  | 	"gogs.mikescher.com/BlackForestBytes/goext/langext" | ||||||
| 	"reflect" | 	"reflect" | ||||||
| 	"time" | 	"time" | ||||||
| ) | ) | ||||||
| @@ -245,6 +246,13 @@ func NewRFC3339(t time.Time) RFC3339Time { | |||||||
| 	return RFC3339Time(t) | 	return RFC3339Time(t) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func NewRFC3339Ptr(t *time.Time) *RFC3339Time { | ||||||
|  | 	if t == nil { | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | 	return langext.Ptr(RFC3339Time(*t)) | ||||||
|  | } | ||||||
|  |  | ||||||
| func NowRFC3339() RFC3339Time { | func NowRFC3339() RFC3339Time { | ||||||
| 	return RFC3339Time(time.Now()) | 	return RFC3339Time(time.Now()) | ||||||
| } | } | ||||||
|   | |||||||
| @@ -8,6 +8,7 @@ import ( | |||||||
| 	"go.mongodb.org/mongo-driver/bson/bsoncodec" | 	"go.mongodb.org/mongo-driver/bson/bsoncodec" | ||||||
| 	"go.mongodb.org/mongo-driver/bson/bsonrw" | 	"go.mongodb.org/mongo-driver/bson/bsonrw" | ||||||
| 	"go.mongodb.org/mongo-driver/bson/bsontype" | 	"go.mongodb.org/mongo-driver/bson/bsontype" | ||||||
|  | 	"gogs.mikescher.com/BlackForestBytes/goext/langext" | ||||||
| 	"reflect" | 	"reflect" | ||||||
| 	"time" | 	"time" | ||||||
| ) | ) | ||||||
| @@ -245,6 +246,13 @@ func NewRFC3339Nano(t time.Time) RFC3339NanoTime { | |||||||
| 	return RFC3339NanoTime(t) | 	return RFC3339NanoTime(t) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func NewRFC3339NanoPtr(t *time.Time) *RFC3339NanoTime { | ||||||
|  | 	if t == nil { | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | 	return langext.Ptr(RFC3339NanoTime(*t)) | ||||||
|  | } | ||||||
|  |  | ||||||
| func NowRFC3339Nano() RFC3339NanoTime { | func NowRFC3339Nano() RFC3339NanoTime { | ||||||
| 	return RFC3339NanoTime(time.Now()) | 	return RFC3339NanoTime(time.Now()) | ||||||
| } | } | ||||||
|   | |||||||
| @@ -8,6 +8,7 @@ import ( | |||||||
| 	"go.mongodb.org/mongo-driver/bson/bsoncodec" | 	"go.mongodb.org/mongo-driver/bson/bsoncodec" | ||||||
| 	"go.mongodb.org/mongo-driver/bson/bsonrw" | 	"go.mongodb.org/mongo-driver/bson/bsonrw" | ||||||
| 	"go.mongodb.org/mongo-driver/bson/bsontype" | 	"go.mongodb.org/mongo-driver/bson/bsontype" | ||||||
|  | 	"gogs.mikescher.com/BlackForestBytes/goext/langext" | ||||||
| 	"reflect" | 	"reflect" | ||||||
| 	"strconv" | 	"strconv" | ||||||
| 	"time" | 	"time" | ||||||
| @@ -239,6 +240,13 @@ func NewUnix(t time.Time) UnixTime { | |||||||
| 	return UnixTime(t) | 	return UnixTime(t) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func NewUnixPtr(t *time.Time) *UnixTime { | ||||||
|  | 	if t == nil { | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | 	return langext.Ptr(UnixTime(*t)) | ||||||
|  | } | ||||||
|  |  | ||||||
| func NowUnix() UnixTime { | func NowUnix() UnixTime { | ||||||
| 	return UnixTime(time.Now()) | 	return UnixTime(time.Now()) | ||||||
| } | } | ||||||
|   | |||||||
| @@ -8,6 +8,7 @@ import ( | |||||||
| 	"go.mongodb.org/mongo-driver/bson/bsoncodec" | 	"go.mongodb.org/mongo-driver/bson/bsoncodec" | ||||||
| 	"go.mongodb.org/mongo-driver/bson/bsonrw" | 	"go.mongodb.org/mongo-driver/bson/bsonrw" | ||||||
| 	"go.mongodb.org/mongo-driver/bson/bsontype" | 	"go.mongodb.org/mongo-driver/bson/bsontype" | ||||||
|  | 	"gogs.mikescher.com/BlackForestBytes/goext/langext" | ||||||
| 	"reflect" | 	"reflect" | ||||||
| 	"strconv" | 	"strconv" | ||||||
| 	"time" | 	"time" | ||||||
| @@ -239,6 +240,13 @@ func NewUnixMilli(t time.Time) UnixMilliTime { | |||||||
| 	return UnixMilliTime(t) | 	return UnixMilliTime(t) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func NewUnixMilliPtr(t *time.Time) *UnixMilliTime { | ||||||
|  | 	if t == nil { | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | 	return langext.Ptr(UnixMilliTime(*t)) | ||||||
|  | } | ||||||
|  |  | ||||||
| func NowUnixMilli() UnixMilliTime { | func NowUnixMilli() UnixMilliTime { | ||||||
| 	return UnixMilliTime(time.Now()) | 	return UnixMilliTime(time.Now()) | ||||||
| } | } | ||||||
|   | |||||||
| @@ -8,6 +8,7 @@ import ( | |||||||
| 	"go.mongodb.org/mongo-driver/bson/bsoncodec" | 	"go.mongodb.org/mongo-driver/bson/bsoncodec" | ||||||
| 	"go.mongodb.org/mongo-driver/bson/bsonrw" | 	"go.mongodb.org/mongo-driver/bson/bsonrw" | ||||||
| 	"go.mongodb.org/mongo-driver/bson/bsontype" | 	"go.mongodb.org/mongo-driver/bson/bsontype" | ||||||
|  | 	"gogs.mikescher.com/BlackForestBytes/goext/langext" | ||||||
| 	"reflect" | 	"reflect" | ||||||
| 	"strconv" | 	"strconv" | ||||||
| 	"time" | 	"time" | ||||||
| @@ -239,6 +240,13 @@ func NewUnixNano(t time.Time) UnixNanoTime { | |||||||
| 	return UnixNanoTime(t) | 	return UnixNanoTime(t) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func NewUnixNanoPtr(t *time.Time) *UnixNanoTime { | ||||||
|  | 	if t == nil { | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | 	return langext.Ptr(UnixNanoTime(*t)) | ||||||
|  | } | ||||||
|  |  | ||||||
| func NowUnixNano() UnixNanoTime { | func NowUnixNano() UnixNanoTime { | ||||||
| 	return UnixNanoTime(time.Now()) | 	return UnixNanoTime(time.Now()) | ||||||
| } | } | ||||||
|   | |||||||
| @@ -125,3 +125,17 @@ func (c *Coll[TData]) createToken(fieldPrimary string, dirPrimary ct.SortDirecti | |||||||
| 		Extra:          ct.Extra{}, | 		Extra:          ct.Extra{}, | ||||||
| 	}, nil | 	}, nil | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func (c *Coll[TData]) needsDoubleSort(ctx context.Context) bool { | ||||||
|  | 	for _, ppl := range c.extraModPipeline { | ||||||
|  | 		for _, stage := range ppl(ctx) { | ||||||
|  | 			for _, bsone := range stage { | ||||||
|  | 				if bsone.Key == "$group" { | ||||||
|  | 					// a group stage in extraModPipeline results in unsorted data, which means the caller must sort again after these pipeline stages... | ||||||
|  | 					return true | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return false | ||||||
|  | } | ||||||
|   | |||||||
| @@ -36,6 +36,14 @@ func (c *Coll[TData]) Find(ctx context.Context, filter bson.M, opts ...*options. | |||||||
| 		pipeline = langext.ArrConcat(pipeline, ppl(ctx)) | 		pipeline = langext.ArrConcat(pipeline, ppl(ctx)) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	if c.needsDoubleSort(ctx) { | ||||||
|  | 		for _, opt := range opts { | ||||||
|  | 			if opt != nil && opt.Sort != nil { | ||||||
|  | 				pipeline = append(pipeline, bson.D{{Key: "$sort", Value: opt.Sort}}) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	for _, opt := range opts { | 	for _, opt := range opts { | ||||||
| 		if opt != nil && opt.Projection != nil { | 		if opt != nil && opt.Projection != nil { | ||||||
| 			pipeline = append(pipeline, bson.D{{Key: "$project", Value: opt.Projection}}) | 			pipeline = append(pipeline, bson.D{{Key: "$project", Value: opt.Projection}}) | ||||||
|   | |||||||
| @@ -35,7 +35,7 @@ func (c *Coll[TData]) List(ctx context.Context, filter ct.Filter, pageSize *int, | |||||||
| 		sortDirSecondary = nil | 		sortDirSecondary = nil | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	paginationPipeline, err := createPaginationPipeline(c, inTok, sortPrimary, sortDirPrimary, sortSecondary, sortDirSecondary, pageSize) | 	paginationPipeline, doubleSortPipeline, err := createPaginationPipeline(c, inTok, sortPrimary, sortDirPrimary, sortSecondary, sortDirSecondary, pageSize) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, ct.CursorToken{}, exerr. | 		return nil, ct.CursorToken{}, exerr. | ||||||
| 			Wrap(err, "failed to create pagination"). | 			Wrap(err, "failed to create pagination"). | ||||||
| @@ -56,6 +56,10 @@ func (c *Coll[TData]) List(ctx context.Context, filter ct.Filter, pageSize *int, | |||||||
| 		pipeline = langext.ArrConcat(pipeline, ppl(ctx)) | 		pipeline = langext.ArrConcat(pipeline, ppl(ctx)) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	if c.needsDoubleSort(ctx) { | ||||||
|  | 		pipeline = langext.ArrConcat(pipeline, doubleSortPipeline) | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	cursor, err := c.coll.Aggregate(ctx, pipeline) | 	cursor, err := c.coll.Aggregate(ctx, pipeline) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, ct.CursorToken{}, exerr.Wrap(err, "mongo-aggregation failed").Any("pipeline", pipeline).Str("collection", c.Name()).Build() | 		return nil, ct.CursorToken{}, exerr.Wrap(err, "mongo-aggregation failed").Any("pipeline", pipeline).Str("collection", c.Name()).Build() | ||||||
| @@ -136,14 +140,50 @@ func (c *Coll[TData]) ListWithCount(ctx context.Context, filter ct.Filter, pageS | |||||||
| 	return data, token, count, nil | 	return data, token, count, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func createPaginationPipeline[TData any](coll *Coll[TData], token ct.CursorToken, fieldPrimary string, sortPrimary ct.SortDirection, fieldSecondary *string, sortSecondary *ct.SortDirection, pageSize *int) ([]bson.D, error) { | func (c *Coll[TData]) ListAllIDs(ctx context.Context, filter ct.RawFilter) ([]string, error) { | ||||||
|  | 	type idObject struct { | ||||||
|  | 		ID string `bson:"_id"` | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	pipelineFilter := mongo.Pipeline{} | ||||||
|  |  | ||||||
|  | 	if filter != nil { | ||||||
|  | 		pipelineFilter = filter.FilterQuery() | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	extrModPipelineResolved := mongo.Pipeline{} | ||||||
|  | 	for _, ppl := range c.extraModPipeline { | ||||||
|  | 		extrModPipelineResolved = langext.ArrConcat(extrModPipelineResolved, ppl(ctx)) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	pipelineProjectIDs := mongo.Pipeline{} | ||||||
|  | 	pipelineProjectIDs = append(pipelineProjectIDs, bson.D{{Key: "$project", Value: bson.M{"_id": 1}}}) | ||||||
|  |  | ||||||
|  | 	pipelineList := langext.ArrConcat(pipelineFilter, extrModPipelineResolved, pipelineProjectIDs) | ||||||
|  |  | ||||||
|  | 	cursorList, err := c.coll.Aggregate(ctx, pipelineList) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, exerr.Wrap(err, "mongo-aggregation failed").Any("pipeline", pipelineList).Str("collection", c.Name()).Build() | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	var res []idObject | ||||||
|  |  | ||||||
|  | 	err = cursorList.All(ctx, &res) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, exerr.Wrap(err, "failed to decode entities").Any("pipeline", pipelineList).Str("collection", c.Name()).Build() | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return langext.ArrMap(res, func(v idObject) string { return v.ID }), nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func createPaginationPipeline[TData any](coll *Coll[TData], token ct.CursorToken, fieldPrimary string, sortPrimary ct.SortDirection, fieldSecondary *string, sortSecondary *ct.SortDirection, pageSize *int) ([]bson.D, []bson.D, error) { | ||||||
|  |  | ||||||
| 	cond := bson.A{} | 	cond := bson.A{} | ||||||
| 	sort := bson.D{} | 	sort := bson.D{} | ||||||
|  |  | ||||||
| 	valuePrimary, err := coll.getTokenValueAsMongoType(token.ValuePrimary, fieldPrimary) | 	valuePrimary, err := coll.getTokenValueAsMongoType(token.ValuePrimary, fieldPrimary) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, exerr.Wrap(err, "failed to get (primary) token-value as mongo-type").Build() | 		return nil, nil, exerr.Wrap(err, "failed to get (primary) token-value as mongo-type").Build() | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if sortPrimary == ct.SortASC { | 	if sortPrimary == ct.SortASC { | ||||||
| @@ -160,7 +200,7 @@ func createPaginationPipeline[TData any](coll *Coll[TData], token ct.CursorToken | |||||||
|  |  | ||||||
| 		valueSecondary, err := coll.getTokenValueAsMongoType(token.ValueSecondary, *fieldSecondary) | 		valueSecondary, err := coll.getTokenValueAsMongoType(token.ValueSecondary, *fieldSecondary) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return nil, exerr.Wrap(err, "failed to get (secondary) token-value as mongo-type").Build() | 			return nil, nil, exerr.Wrap(err, "failed to get (secondary) token-value as mongo-type").Build() | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if *sortSecondary == ct.SortASC { | 		if *sortSecondary == ct.SortASC { | ||||||
| @@ -203,15 +243,17 @@ func createPaginationPipeline[TData any](coll *Coll[TData], token ct.CursorToken | |||||||
|  |  | ||||||
| 	} else { | 	} else { | ||||||
|  |  | ||||||
| 		return nil, exerr.New(exerr.TypeInternal, "unknown ct mode: "+string(token.Mode)).Any("token.Mode", token.Mode).Build() | 		return nil, nil, exerr.New(exerr.TypeInternal, "unknown ct mode: "+string(token.Mode)).Any("token.Mode", token.Mode).Build() | ||||||
|  |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	pipeline = append(pipeline, bson.D{{Key: "$sort", Value: sort}}) | 	pipeline = append(pipeline, bson.D{{Key: "$sort", Value: sort}}) | ||||||
|  |  | ||||||
|  | 	pipelineSort := mongo.Pipeline{bson.D{{Key: "$sort", Value: sort}}} | ||||||
|  |  | ||||||
| 	if pageSize != nil { | 	if pageSize != nil { | ||||||
| 		pipeline = append(pipeline, bson.D{{Key: "$limit", Value: int64(*pageSize + 1)}}) | 		pipeline = append(pipeline, bson.D{{Key: "$limit", Value: int64(*pageSize + 1)}}) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return pipeline, nil | 	return pipeline, pipelineSort, nil | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user