[GODRIVER-681] Cursors and SingleResult ignore client custom registry Created: 09/Dec/18  Updated: 28/Oct/23  Resolved: 20/Dec/18

Status: Closed
Project: Go Driver
Component/s: Core API
Affects Version/s: 0.1.0
Fix Version/s: 0.2.0

Type: Bug Priority: Major - P3
Reporter: Aleksandr Sokolovskii Assignee: Divjot Arora (Inactive)
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

golang 1.11.2, Windows 10


Issue Links:
Related
is related to GODRIVER-636 Add documentation on how to set a cus... Closed

 Description   

Case:
I have developed custom codec for Google protobuf wrappers (wrappers.BoolValue, etc.).
See https://godoc.org/github.com/golang/protobuf/ptypes/wrappers for details.

My code is:
type ProtoWrappersValueCodec struct {
}

func (e *ProtoWrappersValueCodec) EncodeValue(ectx bsoncodec.EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error

{ ... some code }

func (e *ProtoWrappersValueCodec) DecodeValue(ectx bsoncodec.DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { ... some code }

 

I provide custom registry when create new client:
rb := bson.NewRegistryBuilder()
cod := &ProtoWrappersValueCodec{}
rb.RegisterCodec(reflect.TypeOf(wrappers.BoolValue{}), cod).
RegisterCodec(reflect.TypeOf(wrappers.BytesValue{}), cod).
RegisterCodec(reflect.TypeOf(wrappers.DoubleValue{}), cod).
RegisterCodec(reflect.TypeOf(wrappers.FloatValue{}), cod).
RegisterCodec(reflect.TypeOf(wrappers.Int32Value{}), cod).
RegisterCodec(reflect.TypeOf(wrappers.Int64Value{}), cod).
RegisterCodec(reflect.TypeOf(wrappers.StringValue{}), cod).
RegisterCodec(reflect.TypeOf(wrappers.UInt32Value{}), cod).
RegisterCodec(reflect.TypeOf(wrappers.UInt64Value{}), cod)

client, err := mongo.NewClientWithOptions("mongodb://localhost:27017",
&options.ClientOptions

{ Registry: rb.Build(), }

)

So InsertOne command works great. BSON Encoder calls custom encoders.
But FindOne ignores custom decoders.
I debug driver and see:
Result cursor registry is set by default registry.
Looks like it is set by server's registry.
Looks like server's registry is default registry.
I don't know why but custom registry I provided to the client is ignored.

Please let me know if you need more details.
Thanks!



 Comments   
Comment by Githook User [ 20/Dec/18 ]

Author:

{'username': 'divjotarora', 'email': 'divjot.arora@10gen.com', 'name': 'Divjot Arora'}

Message: Pass custom registry to topology options.

GODRIVER-681

Change-Id: I50ac9930acd72719274a03357a20eb841a346c32
Branch: master
https://github.com/mongodb/mongo-go-driver/commit/79e6c40817d03b8b514c92ef62e10ec18e31b220

Comment by Divjot Arora (Inactive) [ 17/Dec/18 ]

Code review: https://review.gerrithub.io/c/mongodb/mongo-go-driver/+/437530

Comment by Aleksandr Sokolovskii [ 12/Dec/18 ]

Great. Thank you very much!

Comment by Divjot Arora (Inactive) [ 12/Dec/18 ]

amsokol We'll be putting the fix for this issue in the SetRegistry() function in the options/clientoptions.go file to add the registry to topology options as well as the options struct. In general, we recommend using the Set* functions to create options structs as they may have some extra logic in addition to setting struct fields. 

Comment by Aleksandr Sokolovskii [ 11/Dec/18 ]

Is my fix correct?

I can create pull request easy.

Should I?

Comment by Aleksandr Sokolovskii [ 11/Dec/18 ]

I think the fix should be the following:

File: mongo-go-driver\mongo\client.go

Func: newClient

 

Old code:

topts := append(
		client.topologyOptions,
		topology.WithConnString(func(connstring.ConnString) connstring.ConnString { return client.connString }),
		topology.WithServerOptions(func(opts ...topology.ServerOption) []topology.ServerOption {
			return append(opts, topology.WithClock(func(clock *session.ClusterClock) *session.ClusterClock {
				return client.clock
			}))
		}),
	)

New Code:

    topts := append(
        client.topologyOptions,
        topology.WithConnString(func(connstring.ConnString) connstring.ConnString { return client.connString }),
        topology.WithServerOptions(func(opts ...topology.ServerOption) []topology.ServerOption {
            return append(opts, topology.WithClock(func(clock *session.ClusterClock) *session.ClusterClock {
                return client.clock
            }), topology.WithRegistry(func(registry *bsoncodec.Registry) *bsoncodec.Registry {
                return client.registry
            }))
        }),
    )

Generated at Thu Feb 08 08:34:43 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.