Merge remote-tracking branch 'origin/feature/mongo-driver-v2'
Build Docker and Deploy / Run goext test-suite (push) Successful in 1m34s

This commit is contained in:
2026-04-26 14:35:07 +02:00
34 changed files with 203 additions and 473 deletions
+2 -2
View File
@@ -16,7 +16,7 @@ import (
"git.blackforestbytes.com/BlackForestBytes/goext/langext"
"github.com/gin-gonic/gin"
"github.com/rs/zerolog"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/v2/bson"
)
//
@@ -253,7 +253,7 @@ func (b *Builder) Bytes(key string, val []byte) *Builder {
return b.addMeta(key, MDTBytes, val)
}
func (b *Builder) ObjectID(key string, val primitive.ObjectID) *Builder {
func (b *Builder) ObjectID(key string, val bson.ObjectID) *Builder {
return b.addMeta(key, MDTObjectID, val)
}
+4 -3
View File
@@ -3,11 +3,12 @@ package exerr
import (
"encoding/json"
"fmt"
"git.blackforestbytes.com/BlackForestBytes/goext/langext"
"go.mongodb.org/mongo-driver/bson/primitive"
"maps"
"reflect"
"time"
"git.blackforestbytes.com/BlackForestBytes/goext/langext"
"go.mongodb.org/mongo-driver/v2/bson"
)
var reflectTypeStr = reflect.TypeFor[string]()
@@ -222,7 +223,7 @@ func getReflectedMetaValues(value any, remainingDepth int) map[string]MetaValue
return map[string]MetaValue{"": {DataType: MDTIntArray, Value: ifraw}}
case []int32:
return map[string]MetaValue{"": {DataType: MDTInt32Array, Value: ifraw}}
case primitive.ObjectID:
case bson.ObjectID:
return map[string]MetaValue{"": {DataType: MDTObjectID, Value: ifraw}}
case []string:
return map[string]MetaValue{"": {DataType: MDTStringArray, Value: ifraw}}
+10 -44
View File
@@ -4,11 +4,8 @@ import (
"encoding/json"
"errors"
"fmt"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/bsoncodec"
"go.mongodb.org/mongo-driver/bson/bsonrw"
"go.mongodb.org/mongo-driver/bson/bsontype"
"reflect"
"go.mongodb.org/mongo-driver/v2/bson"
)
type ErrorCategory struct{ Category string }
@@ -28,8 +25,8 @@ func (e ErrorCategory) MarshalJSON() ([]byte, error) {
return json.Marshal(e.Category)
}
func (e *ErrorCategory) UnmarshalBSONValue(bt bsontype.Type, data []byte) error {
if bt == bson.TypeNull {
func (e *ErrorCategory) UnmarshalBSONValue(bt byte, data []byte) error {
if bson.Type(bt) == bson.TypeNull {
// we can't set nil in UnmarshalBSONValue (so we use default(struct))
// Use mongoext.CreateGoExtBsonRegistry if you need to unmarsh pointer values
// https://stackoverflow.com/questions/75167597
@@ -37,11 +34,11 @@ func (e *ErrorCategory) UnmarshalBSONValue(bt bsontype.Type, data []byte) error
*e = ErrorCategory{}
return nil
}
if bt != bson.TypeString {
return errors.New(fmt.Sprintf("cannot unmarshal %v into String", bt))
if bson.Type(bt) != bson.TypeString {
return errors.New(fmt.Sprintf("cannot unmarshal %v into String", bson.Type(bt)))
}
var tt string
err := bson.RawValue{Type: bt, Value: data}.Unmarshal(&tt)
err := bson.RawValue{Type: bson.Type(bt), Value: data}.Unmarshal(&tt)
if err != nil {
return err
}
@@ -49,40 +46,9 @@ func (e *ErrorCategory) UnmarshalBSONValue(bt bsontype.Type, data []byte) error
return nil
}
func (e ErrorCategory) MarshalBSONValue() (bsontype.Type, []byte, error) {
return bson.MarshalValue(e.Category)
}
func (e ErrorCategory) DecodeValue(dc bsoncodec.DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
if val.Kind() == reflect.Pointer && val.IsNil() {
if !val.CanSet() {
return errors.New("ValueUnmarshalerDecodeValue")
}
val.Set(reflect.New(val.Type().Elem()))
}
tp, src, err := bsonrw.Copier{}.CopyValueToBytes(vr)
if err != nil {
return err
}
if val.Kind() == reflect.Pointer && len(src) == 0 {
val.Set(reflect.Zero(val.Type()))
return nil
}
err = e.UnmarshalBSONValue(tp, src)
if err != nil {
return err
}
if val.Kind() == reflect.Pointer {
val.Set(reflect.ValueOf(&e))
} else {
val.Set(reflect.ValueOf(e))
}
return nil
func (e ErrorCategory) MarshalBSONValue() (byte, []byte, error) {
tp, data, err := bson.MarshalValue(e.Category)
return byte(tp), data, err
}
//goland:noinspection GoUnusedGlobalVariable
+10 -44
View File
@@ -4,11 +4,8 @@ import (
"encoding/json"
"errors"
"fmt"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/bsoncodec"
"go.mongodb.org/mongo-driver/bson/bsonrw"
"go.mongodb.org/mongo-driver/bson/bsontype"
"reflect"
"go.mongodb.org/mongo-driver/v2/bson"
)
type ErrorSeverity struct{ Severity string }
@@ -30,8 +27,8 @@ func (e ErrorSeverity) MarshalJSON() ([]byte, error) {
return json.Marshal(e.Severity)
}
func (e *ErrorSeverity) UnmarshalBSONValue(bt bsontype.Type, data []byte) error {
if bt == bson.TypeNull {
func (e *ErrorSeverity) UnmarshalBSONValue(bt byte, data []byte) error {
if bson.Type(bt) == bson.TypeNull {
// we can't set nil in UnmarshalBSONValue (so we use default(struct))
// Use mongoext.CreateGoExtBsonRegistry if you need to unmarsh pointer values
// https://stackoverflow.com/questions/75167597
@@ -39,11 +36,11 @@ func (e *ErrorSeverity) UnmarshalBSONValue(bt bsontype.Type, data []byte) error
*e = ErrorSeverity{}
return nil
}
if bt != bson.TypeString {
return errors.New(fmt.Sprintf("cannot unmarshal %v into String", bt))
if bson.Type(bt) != bson.TypeString {
return errors.New(fmt.Sprintf("cannot unmarshal %v into String", bson.Type(bt)))
}
var tt string
err := bson.RawValue{Type: bt, Value: data}.Unmarshal(&tt)
err := bson.RawValue{Type: bson.Type(bt), Value: data}.Unmarshal(&tt)
if err != nil {
return err
}
@@ -51,40 +48,9 @@ func (e *ErrorSeverity) UnmarshalBSONValue(bt bsontype.Type, data []byte) error
return nil
}
func (e ErrorSeverity) MarshalBSONValue() (bsontype.Type, []byte, error) {
return bson.MarshalValue(e.Severity)
}
func (e ErrorSeverity) DecodeValue(dc bsoncodec.DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
if val.Kind() == reflect.Pointer && val.IsNil() {
if !val.CanSet() {
return errors.New("ValueUnmarshalerDecodeValue")
}
val.Set(reflect.New(val.Type().Elem()))
}
tp, src, err := bsonrw.Copier{}.CopyValueToBytes(vr)
if err != nil {
return err
}
if val.Kind() == reflect.Pointer && len(src) == 0 {
val.Set(reflect.Zero(val.Type()))
return nil
}
err = e.UnmarshalBSONValue(tp, src)
if err != nil {
return err
}
if val.Kind() == reflect.Pointer {
val.Set(reflect.ValueOf(&e))
} else {
val.Set(reflect.ValueOf(e))
}
return nil
func (e ErrorSeverity) MarshalBSONValue() (byte, []byte, error) {
tp, data, err := bson.MarshalValue(e.Severity)
return byte(tp), data, err
}
//goland:noinspection GoUnusedGlobalVariable
+9 -44
View File
@@ -4,13 +4,9 @@ import (
"encoding/json"
"errors"
"fmt"
"reflect"
"git.blackforestbytes.com/BlackForestBytes/goext/dataext"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/bsoncodec"
"go.mongodb.org/mongo-driver/bson/bsonrw"
"go.mongodb.org/mongo-driver/bson/bsontype"
"go.mongodb.org/mongo-driver/v2/bson"
)
type ErrorType struct {
@@ -80,8 +76,8 @@ func (e ErrorType) MarshalJSON() ([]byte, error) {
return json.Marshal(e.Key)
}
func (e *ErrorType) UnmarshalBSONValue(bt bsontype.Type, data []byte) error {
if bt == bson.TypeNull {
func (e *ErrorType) UnmarshalBSONValue(bt byte, data []byte) error {
if bson.Type(bt) == bson.TypeNull {
// we can't set nil in UnmarshalBSONValue (so we use default(struct))
// Use mongoext.CreateGoExtBsonRegistry if you need to unmarsh pointer values
// https://stackoverflow.com/questions/75167597
@@ -89,11 +85,11 @@ func (e *ErrorType) UnmarshalBSONValue(bt bsontype.Type, data []byte) error {
*e = ErrorType{}
return nil
}
if bt != bson.TypeString {
return errors.New(fmt.Sprintf("cannot unmarshal %v into String", bt))
if bson.Type(bt) != bson.TypeString {
return errors.New(fmt.Sprintf("cannot unmarshal %v into String", bson.Type(bt)))
}
var tt string
err := bson.RawValue{Type: bt, Value: data}.Unmarshal(&tt)
err := bson.RawValue{Type: bson.Type(bt), Value: data}.Unmarshal(&tt)
if err != nil {
return err
}
@@ -107,40 +103,9 @@ func (e *ErrorType) UnmarshalBSONValue(bt bsontype.Type, data []byte) error {
}
}
func (e ErrorType) MarshalBSONValue() (bsontype.Type, []byte, error) {
return bson.MarshalValue(e.Key)
}
func (e ErrorType) DecodeValue(dc bsoncodec.DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
if val.Kind() == reflect.Pointer && val.IsNil() {
if !val.CanSet() {
return errors.New("ValueUnmarshalerDecodeValue")
}
val.Set(reflect.New(val.Type().Elem()))
}
tp, src, err := bsonrw.Copier{}.CopyValueToBytes(vr)
if err != nil {
return err
}
if val.Kind() == reflect.Pointer && len(src) == 0 {
val.Set(reflect.Zero(val.Type()))
return nil
}
err = e.UnmarshalBSONValue(tp, src)
if err != nil {
return err
}
if val.Kind() == reflect.Pointer {
val.Set(reflect.ValueOf(&e))
} else {
val.Set(reflect.ValueOf(e))
}
return nil
func (e ErrorType) MarshalBSONValue() (byte, []byte, error) {
tp, data, err := bson.MarshalValue(e.Key)
return byte(tp), data, err
}
var registeredTypes = dataext.SyncMap[string, ErrorType]{}
+16 -16
View File
@@ -3,12 +3,12 @@ package exerr
import (
"context"
"encoding/json"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
"git.blackforestbytes.com/BlackForestBytes/goext/tst"
"testing"
"time"
"git.blackforestbytes.com/BlackForestBytes/goext/tst"
"go.mongodb.org/mongo-driver/v2/bson"
"go.mongodb.org/mongo-driver/v2/mongo"
)
func TestJSONMarshalErrorCategory(t *testing.T) {
@@ -57,7 +57,7 @@ func TestBSONMarshalErrorCategory(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), 350*time.Millisecond)
defer cancel()
client, err := mongo.Connect(ctx)
client, err := mongo.Connect()
if err != nil {
t.Skip("Skip test - no local mongo found")
return
@@ -68,7 +68,7 @@ func TestBSONMarshalErrorCategory(t *testing.T) {
return
}
primimd := primitive.NewObjectID()
primimd := bson.NewObjectID()
_, err = client.Database("_test").Collection("goext-cicd").InsertOne(ctx, bson.M{"_id": primimd, "val": CatSystem})
tst.AssertNoErr(t, err)
@@ -76,8 +76,8 @@ func TestBSONMarshalErrorCategory(t *testing.T) {
cursor := client.Database("_test").Collection("goext-cicd").FindOne(ctx, bson.M{"_id": primimd, "val": bson.M{"$type": "string"}})
var c1 struct {
ID primitive.ObjectID `bson:"_id"`
Val ErrorCategory `bson:"val"`
ID bson.ObjectID `bson:"_id"`
Val ErrorCategory `bson:"val"`
}
err = cursor.Decode(&c1)
@@ -90,7 +90,7 @@ func TestBSONMarshalErrorSeverity(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), 350*time.Millisecond)
defer cancel()
client, err := mongo.Connect(ctx)
client, err := mongo.Connect()
if err != nil {
t.Skip("Skip test - no local mongo found")
return
@@ -101,7 +101,7 @@ func TestBSONMarshalErrorSeverity(t *testing.T) {
return
}
primimd := primitive.NewObjectID()
primimd := bson.NewObjectID()
_, err = client.Database("_test").Collection("goext-cicd").InsertOne(ctx, bson.M{"_id": primimd, "val": SevErr})
tst.AssertNoErr(t, err)
@@ -109,8 +109,8 @@ func TestBSONMarshalErrorSeverity(t *testing.T) {
cursor := client.Database("_test").Collection("goext-cicd").FindOne(ctx, bson.M{"_id": primimd, "val": bson.M{"$type": "string"}})
var c1 struct {
ID primitive.ObjectID `bson:"_id"`
Val ErrorSeverity `bson:"val"`
ID bson.ObjectID `bson:"_id"`
Val ErrorSeverity `bson:"val"`
}
err = cursor.Decode(&c1)
@@ -123,7 +123,7 @@ func TestBSONMarshalErrorType(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), 350*time.Millisecond)
defer cancel()
client, err := mongo.Connect(ctx)
client, err := mongo.Connect()
if err != nil {
t.Skip("Skip test - no local mongo found")
return
@@ -134,7 +134,7 @@ func TestBSONMarshalErrorType(t *testing.T) {
return
}
primimd := primitive.NewObjectID()
primimd := bson.NewObjectID()
_, err = client.Database("_test").Collection("goext-cicd").InsertOne(ctx, bson.M{"_id": primimd, "val": TypeNotImplemented})
tst.AssertNoErr(t, err)
@@ -142,8 +142,8 @@ func TestBSONMarshalErrorType(t *testing.T) {
cursor := client.Database("_test").Collection("goext-cicd").FindOne(ctx, bson.M{"_id": primimd, "val": bson.M{"$type": "string"}})
var c1 struct {
ID primitive.ObjectID `bson:"_id"`
Val ErrorType `bson:"val"`
ID bson.ObjectID `bson:"_id"`
Val ErrorType `bson:"val"`
}
err = cursor.Decode(&c1)
+12 -12
View File
@@ -5,14 +5,14 @@ import (
"encoding/json"
"errors"
"fmt"
"git.blackforestbytes.com/BlackForestBytes/goext/langext"
"github.com/rs/zerolog"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"math"
"strconv"
"strings"
"time"
"git.blackforestbytes.com/BlackForestBytes/goext/langext"
"github.com/rs/zerolog"
"go.mongodb.org/mongo-driver/v2/bson"
)
// This is a buffed up map[string]any
@@ -99,7 +99,7 @@ func (v MetaValue) SerializeValue() (string, error) {
case MDTBytes:
return hex.EncodeToString(v.Value.([]byte)), nil
case MDTObjectID:
return v.Value.(primitive.ObjectID).Hex(), nil
return v.Value.(bson.ObjectID).Hex(), nil
case MDTTime:
return strconv.FormatInt(v.Value.(time.Time).Unix(), 10) + "|" + strconv.FormatInt(int64(v.Value.(time.Time).Nanosecond()), 10), nil
case MDTDuration:
@@ -178,7 +178,7 @@ func (v MetaValue) ShortString(lim int) string {
case MDTBytes:
return langext.StrLimit(hex.EncodeToString(v.Value.([]byte)), lim, "...")
case MDTObjectID:
return v.Value.(primitive.ObjectID).Hex()
return v.Value.(bson.ObjectID).Hex()
case MDTTime:
return v.Value.(time.Time).Format(time.RFC3339)
case MDTDuration:
@@ -266,7 +266,7 @@ func (v MetaValue) Apply(key string, evt *zerolog.Event, limitLen *int) *zerolog
case MDTBytes:
return evt.Bytes(key, v.Value.([]byte))
case MDTObjectID:
return evt.Str(key, v.Value.(primitive.ObjectID).Hex())
return evt.Str(key, v.Value.(bson.ObjectID).Hex())
case MDTTime:
return evt.Time(key, v.Value.(time.Time))
case MDTDuration:
@@ -460,7 +460,7 @@ func (v *MetaValue) Deserialize(value string, datatype metaDataType) error {
v.DataType = datatype
return nil
case MDTObjectID:
r, err := primitive.ObjectIDFromHex(value)
r, err := bson.ObjectIDFromHex(value)
if err != nil {
return err
}
@@ -577,7 +577,7 @@ func (v MetaValue) ValueString() string {
case MDTBytes:
return hex.EncodeToString(v.Value.([]byte))
case MDTObjectID:
return v.Value.(primitive.ObjectID).Hex()
return v.Value.(bson.ObjectID).Hex()
case MDTTime:
return v.Value.(time.Time).Format(time.RFC3339Nano)
case MDTDuration:
@@ -628,8 +628,8 @@ func (v MetaValue) rawValueForJson() any {
if v.Value.(AnyWrap).IsError {
return bson.M{"@error": true}
}
jsonobj := primitive.M{}
jsonarr := primitive.A{}
jsonobj := bson.M{}
jsonarr := bson.A{}
if err := json.Unmarshal([]byte(v.Value.(AnyWrap).Json), &jsonobj); err == nil {
return jsonobj
} else if err := json.Unmarshal([]byte(v.Value.(AnyWrap).Json), &jsonarr); err == nil {
@@ -654,7 +654,7 @@ func (v MetaValue) rawValueForJson() any {
return v.Value.(time.Time).Format(time.RFC3339Nano)
}
if v.DataType == MDTObjectID {
return v.Value.(primitive.ObjectID).Hex()
return v.Value.(bson.ObjectID).Hex()
}
if v.DataType == MDTNil {
return nil