You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Part of the easymongo refactor (see PLAN.md on the refactor branch).
Working context (read this first)
Repository github.com/tophergopher/easymongo. Start from branch claude/mongotest-easymongo-refactor-wu2vhm; create a branch issue-<number>-<short-slug> from it and open a pull request back into it. PLAN.md on that branch is the source of truth; read it before writing code.
Go project, single module, all packages at the repo root except the new easymongotest/ subpackage. The final toolchain target is Go 1.27 (set by Toolchain: go 1.27, latest dependencies, tidy, remove replace directives #10); any Go 1.24 or newer works until then. Before pushing: gofmt -l . prints nothing, go vet ./..., go test -race ./....
The existing test suite (*_test.go at the root, package easymongo_test, every test function calling setup(t) from common_test.go) is the regression net for this refactor. It must pass after your change. It needs a Docker daemon reachable through the normal Docker environment and the mongo:8 image.
Method is test-driven: write the tests listed under "Tests first", confirm they fail for the expected reason, then implement. Never delete, skip or weaken an existing test to get green; if a test must change because the public API changed (for example primitive.ObjectID to bson.ObjectID), change only the types.
Commit messages: imperative summary line, blank line, body explaining why. Mention this issue number in the pull request description.
Scope
primitive.ObjectID becomes bson.ObjectID, primitive.NewObjectID() becomes bson.NewObjectID(), primitive.NewObjectIDFromTimestamp becomes bson.NewObjectIDFromTimestamp. Occurrences: insert_query.go return types (24, 44, 59, 69), delete_query.go (70), collection.go (163-172), common_test.go (40, 57-62), and any primitive.M/primitive.D in tests.
This is a public API change for easymongo (Insert().One returns bson.ObjectID). Agreed with the maintainer: easymongo is 0.x, so this ships as a minor version bump with a CHANGELOG note, not as an easymongo/v2 module.
index.go uses the deprecated go.mongodb.org/mongo-driver/x/bsonx package (bsonx.Doc{{Key: ..., Value: bsonx.Int32(1)}}) to build mongo.IndexModel.Keys. Replace with bson.D{{Key: field, Value: int32(1)}} / int32(-1) for descending. Indexes().CreateOne still returns (string, error).
utils.goindexKeyToBsonE keeps returning bson.E; verify direction parsing for -name style keys.
Re-export helpers if callers relied on easymongo types: consider type ObjectID = bson.ObjectID in easymongo so downstream code has one import. Decide and document.
Implementation details
Verified in v2.9.0: type bson.ObjectID [12]byte, bson.NewObjectID(), bson.NewObjectIDFromTimestamp(time.Time), bson.NilObjectID. mongo.IndexModel{Keys: bson.D{{Key: "name", Value: int32(1)}}} and coll.Indexes().CreateOne(ctx, model, opts ...options.Lister[options.CreateIndexesOptions]) (string, error); ListSpecifications(ctx, opts...) ([]mongo.IndexSpecification, error) returns values, not pointers.
Add to easymongo (new file types.go) so downstream code can avoid importing the driver for ids:
// ObjectID is an alias of the driver's bson.ObjectID.typeObjectID= bson.ObjectIDfuncNewObjectID() ObjectID { returnbson.NewObjectID() }
Change the Insert return types and DeleteByID/FindByID/ReplaceByID/UpsertByID parameters to ObjectID; since it is an alias, bson.ObjectID values work unchanged.
Mechanical rewrite help: grep -rln 'bson/primitive' --include=*.go . | xargs sed -i 's#go.mongodb.org/mongo-driver/bson/primitive#go.mongodb.org/mongo-driver/v2/bson#; s/primitive\./bson./g' then fix duplicate bson imports by hand and run gofmt -w ..
Tests first
index_test.go: creating an ascending and a descending index yields index specs (via ListSpecifications) with the expected keys and names; Ensure twice is idempotent.
insert_query_test.go: the returned id decodes back to the inserted document's _id.
A test that NewObjectIDFromTimestamp filtering in collection.go (the CreatedBetween-style helpers) returns the expected subset.
Part of the easymongo refactor (see
PLAN.mdon the refactor branch).Working context (read this first)
github.com/tophergopher/easymongo. Start from branchclaude/mongotest-easymongo-refactor-wu2vhm; create a branchissue-<number>-<short-slug>from it and open a pull request back into it.PLAN.mdon that branch is the source of truth; read it before writing code.easymongotest/subpackage. The final toolchain target is Go 1.27 (set by Toolchain: go 1.27, latest dependencies, tidy, remove replace directives #10); any Go 1.24 or newer works until then. Before pushing:gofmt -l .prints nothing,go vet ./...,go test -race ./....*_test.goat the root, packageeasymongo_test, every test function callingsetup(t)fromcommon_test.go) is the regression net for this refactor. It must pass after your change. It needs a Docker daemon reachable through the normal Docker environment and themongo:8image.*mongo.Clienttype flows fromConnectiontoDatabasetoCollection), so the four driver issues Driver v2: migrate connect.go (mongo.Connect, Disconnect, BSONOptions, write concern) #2, Driver v2: options struct literals become builders; drop MaxTime; ArrayFilters and Delete option changes #3, Driver v2: primitive package merged into bson; replace x/bsonx in index.go #4 and Driver v2: Distinct returns a DistinctResult that must be decoded #5 land together in one pull request, worked in that order. Before them, New easymongotest subpackage wrapping mongotest/v2 #7 and Switch the easymongo test suite to easymongotest #8 must land so the test suite no longer depends on the oldgithub.com/tophergopher/mongotestv0.1.0 module (which itself imports easymongo and breaks the moment easymongo's types change). Until mongotest'sv2module is tagged, use a localreplace github.com/tophergopher/mongotest/v2 => ../mongotest/v2ingo.modand say so in the pull request; Toolchain: go 1.27, latest dependencies, tidy, remove replace directives #10 removes it.primitive.ObjectIDtobson.ObjectID), change only the types.Scope
primitive.ObjectIDbecomesbson.ObjectID,primitive.NewObjectID()becomesbson.NewObjectID(),primitive.NewObjectIDFromTimestampbecomesbson.NewObjectIDFromTimestamp. Occurrences:insert_query.goreturn types (24, 44, 59, 69),delete_query.go(70),collection.go(163-172),common_test.go(40, 57-62), and anyprimitive.M/primitive.Din tests.Insert().Onereturnsbson.ObjectID). Agreed with the maintainer: easymongo is 0.x, so this ships as a minor version bump with a CHANGELOG note, not as aneasymongo/v2module.index.gouses the deprecatedgo.mongodb.org/mongo-driver/x/bsonxpackage (bsonx.Doc{{Key: ..., Value: bsonx.Int32(1)}}) to buildmongo.IndexModel.Keys. Replace withbson.D{{Key: field, Value: int32(1)}}/int32(-1)for descending.Indexes().CreateOnestill returns(string, error).utils.goindexKeyToBsonEkeeps returningbson.E; verify direction parsing for-namestyle keys.easymongotypes: considertype ObjectID = bson.ObjectIDin easymongo so downstream code has one import. Decide and document.Implementation details
Verified in v2.9.0:
type bson.ObjectID [12]byte,bson.NewObjectID(),bson.NewObjectIDFromTimestamp(time.Time),bson.NilObjectID.mongo.IndexModel{Keys: bson.D{{Key: "name", Value: int32(1)}}}andcoll.Indexes().CreateOne(ctx, model, opts ...options.Lister[options.CreateIndexesOptions]) (string, error);ListSpecifications(ctx, opts...) ([]mongo.IndexSpecification, error)returns values, not pointers.Add to
easymongo(new filetypes.go) so downstream code can avoid importing the driver for ids:Change the
Insertreturn types andDeleteByID/FindByID/ReplaceByID/UpsertByIDparameters toObjectID; since it is an alias,bson.ObjectIDvalues work unchanged.Mechanical rewrite help:
grep -rln 'bson/primitive' --include=*.go . | xargs sed -i 's#go.mongodb.org/mongo-driver/bson/primitive#go.mongodb.org/mongo-driver/v2/bson#; s/primitive\./bson./g'then fix duplicatebsonimports by hand and rungofmt -w ..Tests first
index_test.go: creating an ascending and a descending index yields index specs (viaListSpecifications) with the expected keys and names;Ensuretwice is idempotent.insert_query_test.go: the returned id decodes back to the inserted document's_id.NewObjectIDFromTimestampfiltering incollection.go(theCreatedBetween-style helpers) returns the expected subset.Acceptance
grep -rn "bson/primitive\|x/bsonx" --include=*.go .returns nothing.Depends on: #3. Lands in the same pull request as #2, #3 and #5.