Skip to content

Driver v2: migrate connect.go (mongo.Connect, Disconnect, BSONOptions, write concern) #2

Description

@TopherGopher

Part of the easymongo refactor (see PLAN.md on branch claude/mongotest-easymongo-refactor-wu2vhm). First step of the go.mongodb.org/mongo-driver v1 to go.mongodb.org/mongo-driver/v2 migration. The existing test suite is the regression net and must stay green after each issue.

Working context (read this first)

Scope (connect.go)

  • Import paths to go.mongodb.org/mongo-driver/v2/....
  • mongo.NewClient(opts) + client.Connect(ctx) (currently lines 281/290 and 315/326) become mongo.Connect(opts), which takes no context.
  • Add Connection.Disconnect(ctx context.Context) error. Nothing in the module calls Disconnect today; easymongotest and tests will.
  • EnableDebug currently does *conn.client = *client (copies a client struct). Replace with: build new options with the monitor, Disconnect the old client, mongo.Connect a new one, swap the pointer.
  • Custom registry (bson.NewRegistryBuilder, bsoncodec.NewSliceCodec, bsonoptions.SliceCodec().SetEncodeNilAsEmpty(true), lines 91-107) becomes opts.SetBSONOptions(&options.BSONOptions{NilSliceAsEmpty: true}), still gated on nilSlicesAreNull.
  • writeconcern.New(writeconcern.W(n)) (line 116) becomes &writeconcern.WriteConcern{W: n}. The []writeconcern.Option accumulation in mongoDriverDatabaseOptions and mongoDriverClientOptions (lines 471-484, 520-535) becomes direct struct construction: W as int or "majority", Journal: &true for WriteConcernJournal.
  • readconcern.*() and readpref.*() constructors are unchanged in v2; keep them.
  • event.CommandFailedEvent.Failure is an error in v2; adjust the debug monitor formatting.
  • options.Database() builder and options.ListDatabases() still exist; verify SetReadConcern/SetReadPreference/SetWriteConcern signatures.

Implementation details

Verified v2.9.0 signatures you will use:

func mongo.Connect(opts ...*options.ClientOptions) (*mongo.Client, error)   // no context
func (c *mongo.Client) Disconnect(ctx context.Context) error
func (c *options.ClientOptions) SetBSONOptions(b *options.BSONOptions) *options.ClientOptions
type options.BSONOptions struct { NilSliceAsEmpty bool; NilMapAsEmpty bool; /* ... */ }
type writeconcern.WriteConcern struct { W any /* int or "majority" */; Journal *bool }
func writeconcern.W1() *writeconcern.WriteConcern; func writeconcern.Majority() *writeconcern.WriteConcern; func writeconcern.Journaled() *writeconcern.WriteConcern
type readconcern.ReadConcern struct { Level string }   // readconcern.Local(), Majority(), Linearizable(), Available(), Snapshot() still exist
func options.Database() *options.DatabaseOptionsBuilder  // SetReadConcern, SetWriteConcern, SetReadPreference, SetBSONOptions
type event.CommandFailedEvent struct { /* ... */ Failure error }

Replacement for the write concern flag mapping (mongoDriverClientOptions and mongoDriverDatabaseOptions):

var wc *writeconcern.WriteConcern
switch {
case connectFlag&WriteConcernMajority != 0: wc = writeconcern.Majority()
case connectFlag&WriteConcernW3 != 0:       wc = &writeconcern.WriteConcern{W: 3}
case connectFlag&WriteConcernW2 != 0:       wc = &writeconcern.WriteConcern{W: 2}
case connectFlag&WriteConcernW1 != 0:       wc = writeconcern.W1()
}
if connectFlag&WriteConcernJournal != 0 {
    if wc == nil { wc = &writeconcern.WriteConcern{} }
    j := true; wc.Journal = &j
}
if wc != nil { opts.SetWriteConcern(wc) }

Note the old client-options code applied W1, W2 and W3 cumulatively (later ifs overwrote earlier ones); pick the highest as above and mention it in the pull request.

EnableDebug rewrite:

conn.mongoOptions.debugMode = true
if conn.log == nil { conn.SetLogger(NewDefaultLogger()) }
ctx, cancel := conn.operationCtx(); defer cancel()
_ = conn.client.Disconnect(ctx)
client, err := mongo.Connect(conn.clientOptions())
if err != nil { return err }
conn.client = client
setGlobalConnection(conn)
return conn.Ping()

Write Disconnect so that a second call is a no-op returning nil (the driver returns mongo.ErrClientDisconnected on double disconnect; swallow exactly that error).

Tests first (connect_test.go)

  • Disconnect succeeds and a subsequent Ping returns an error.
  • EnableDebug keeps the connection usable (ping succeeds afterwards) and the debug logger receives at least one Debugf call for a command.
  • Nil slice encoding: insert a struct with a nil []string, read back raw BSON, assert it is an empty array by default and null when nilSlicesAreNull is set.
  • Write concern flags produce the expected WriteConcern values (unit test on mongoDriverClientOptions without a server).

Acceptance

  • go build ./... succeeds with only connect.go and connect_test.go on driver v2 (other files may temporarily import v1 through a replace-free dual requirement; remove the v1 requirement in the final migration issue).

Depends on: #8 (test suite on easymongotest). Lands in one pull request together with #3, #4 and #5, worked in that order.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions