Skip to content

update mongo driver - #376

Merged
adiom-mark merged 3 commits into
mainfrom
mongo2
Mar 31, 2026
Merged

update mongo driver#376
adiom-mark merged 3 commits into
mainfrom
mongo2

Conversation

@adiom-mark

@adiom-mark adiom-mark commented Mar 30, 2026

Copy link
Copy Markdown
Collaborator

Summary by CodeRabbit

  • Chores
    • Upgraded MongoDB Go driver from v1 to v2 across the project.
    • Migrated BSON types, registries, encoders/decoders, and related APIs to the v2 surface.
    • Updated change-stream, cursor, resume token, and connection option usage to match the new driver.
    • Revised tests, helpers, and internal utilities to use the v2 BSON behavior.

@coderabbitai

coderabbitai Bot commented Mar 30, 2026

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 2509d5c9-007e-4d68-8af5-ca78d89ee184

📥 Commits

Reviewing files that changed from the base of the PR and between 6c88896 and 77112c6.

📒 Files selected for processing (1)
  • connectors/dynamodb/conv.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • connectors/dynamodb/conv.go

📝 Walkthrough

Walkthrough

This PR migrates the codebase to the MongoDB Go driver v2: updating import paths, replacing legacy primitive/bsontype usages with v2 bson types/APIs, refactoring BSON registry/codecs, adjusting change-stream/options signatures, and bumping go.mod to go.mongodb.org/mongo-driver/v2.

Changes

Cohort / File(s) Summary
Broad import/type migrations
connectors/airbyte/helpers.go, connectors/common/hash_test.go, connectors/random/connv2.go, connectors/random/util.go, connectors/file/connector.go, connectors/file/connector_test.go, connectors/file/util.go, connectors/s3/connector.go, connectors/sqlbatch/cs.go, pkg/test/connector.go, protocol/test/connector_testsuite.go
Replaced legacy MongoDB imports with go.mongodb.org/mongo-driver/v2/...; marshaling/unmarshaling calls now reference v2 bson; no functional logic changes.
Concrete BSON type conversions & assertions
connectors/common/base.go, connectors/dynamodb/conv.go, connectors/null/connector.go, connectors/s3vector/conn.go, connectors/testconn/connector.go, connectors/vector/conn.go, internal/app/verify.go, connectors/cosmos/range_partitioning.go
Replaced primitive.* and bsontype usages with v2 bson.* types (ObjectID, Binary, DateTime, Decimal128, Timestamp), updated type switches/assertions and a few raw/array conversions.
Cosmos connector & change streams
connectors/cosmos/change_streams.go, connectors/cosmos/conn.go, connectors/cosmos/util.go, connectors/cosmos/token_map.go, connectors/cosmos/connector_test.go
Updated imports to v2, switched change-stream option parameter types to moptions.Lister[...] where applicable, switched resume token/timestamp handling to v2 types, and removed some explicit connect timeout wrappers.
Mongo connector, Watchable API & planners
connectors/mongo/conn.go, connectors/mongo/connector_test.go, connectors/mongo/docdb.go, connectors/mongo/planner.go, connectors/mongo/util.go, statestores/mongo/statestore.go
Migrated to v2 imports/types; replaced primitive.E/Regex/Timestamp with v2 equivalents; changed Watch signatures to accept ...options.Lister[options.ChangeStreamOptions]; adjusted cursor/timestamp handling and connection callsites.
Postgres BSON registry & helpers
connectors/postgres/bson_registry.go, connectors/postgres/bson_conv.go, connectors/postgres/conn.go
Refactored BSON codec/registry to v2 APIs: NewBSONRegistry()*bson.Registry; implemented bson.ValueEncoder/ValueDecoder for custom codecs; added marshalWithRegistry and marshalValueWithRegistry wrappers and updated callsites to use the new registry.
Other connectors updated to v2 BSON
connectors/cosmos/check_deletes.go, connectors/cosmos/planner.go, connectors/cosmos/token_map.go, connectors/s3vector/conn.go, connectors/random/*, connectors/sqlbatch/cs.go, connectors/testconn/connector.go, connectors/vector/conn.go
Various files updated to use v2 bson APIs (e.g., bson.Type(...) for raw values, bson.Raw usage, minor cast updates) without altering control flow.
Dependency bump
go.mod
Replaced go.mongodb.org/mongo-driver v1.x with go.mongodb.org/mongo-driver/v2 v2.5.0; updated indirect deps accordingly.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • Add SQL Batch #371: touches connectors/sqlbatch/cs.go and overlaps BSON/connector changes consistent with the v2 migration.

Poem

🐰 Hop-hop, the BSON hopped to v2,

ObjectIDs donned a new shoe,
Registries hummed a tidy tune,
ChangeStreams sorted options soon,
A rabbit winks — migration through!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 32.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'update mongo driver' accurately describes the main change across all files: migrating MongoDB Go driver from v1 to v2.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch mongo2

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
connectors/mongo/conn.go (1)

954-965: ⚠️ Potential issue | 🟡 Minor

Disconnect the client when Ping fails.

If Ping fails after mongo.Connect succeeds, the function returns without calling client.Disconnect(), leaving the client resource undisposed on the startup error path. The MongoDB v2 driver requires explicit disconnection to clean up resources.

Also, line 967 should return nil instead of err on success (err is nil at that point).

🛠️ Suggested fix
 	client, err := mongo.Connect(clientOptions)
 	if err != nil {
 		return nil, err
 	}
 
 	// Check the connection
 	ctxPing, cancelPing := context.WithTimeout(ctx, settings.PingTimeout)
 	defer cancelPing()
 	err = client.Ping(ctxPing, nil)
 	if err != nil {
+		_ = client.Disconnect(context.Background())
 		return nil, err
 	}
 
-	return client, err
+	return client, nil
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@connectors/mongo/conn.go` around lines 954 - 965, If mongo.Connect succeeds
but client.Ping fails, the code currently returns without disconnecting the
client; update the Ping error path to call client.Disconnect(...) (e.g.,
client.Disconnect(context.Background())) and handle or log any disconnect error
before returning the Ping error so resources are cleaned up; also correct the
successful return to return the connected client and nil error (replace
returning err with nil) so the function returns (client, nil) on success.
🧹 Nitpick comments (2)
connectors/cosmos/check_deletes.go (1)

181-181: Consider adding defensive type assertion handling for missingIds

Line 181 uses an unchecked type assertion to bson.A. While the MongoDB driver v2 guarantees BSON arrays decode as bson.A under standard codec configuration, defensive handling prevents panic if a custom registry differs from the default behavior.

The existing nil check at line 175 provides some safety, but the type assertion itself remains unguarded.

Suggested defensive fix
-		missingIds = []interface{}(res["missingIds"].(bson.A))
+		switch arr := res["missingIds"].(type) {
+		case bson.A:
+			missingIds = []interface{}(arr)
+		case []interface{}:
+			missingIds = arr
+		default:
+			slog.Error(fmt.Sprintf("Unexpected missingIds type: %T", res["missingIds"]))
+			return
+		}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@connectors/cosmos/check_deletes.go` at line 181, The unchecked type assertion
on res["missingIds"] to bson.A can panic if a custom codec returns a different
type; update the code around the missingIds assignment in checkDeletes (variable
missingIds and map res) to use a guarded type assertion (ok idiom) or a type
switch: attempt to cast to bson.A, else handle []interface{} or nil cases, and
fall back to constructing missingIds safely (e.g., iterate and append elements)
or return an error; ensure the subsequent code uses the safely constructed
missingIds variable.
connectors/postgres/bson_conv.go (1)

10-15: Make nested document decoding explicit.

Without an explicit decoder mode, embedded docs inside map[string]interface{} still decode as bson.D in v2. If callers expect recursive plain maps, opt into DefaultDocumentMap() on v2.5+ or set the equivalent TypeEmbeddedDocument mapping in the registry. (pkg.go.dev)

♻️ Suggested tweak (v2.5+)
 func bsonToMap(reg *bson.Registry, data []byte) (map[string]interface{}, error) {
 	var m map[string]interface{}
 	dec := bson.NewDecoder(bson.NewDocumentReader(bytes.NewReader(data)))
 	dec.SetRegistry(reg)
+	dec.DefaultDocumentMap()
 	if err := dec.Decode(&m); err != nil {
 		return nil, err
 	}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@connectors/postgres/bson_conv.go` around lines 10 - 15, bsonToMap currently
decodes embedded documents into bson.D because the registry lacks the explicit
document-map mapping; update bsonToMap to opt into recursive plain maps by using
a registry built with the DefaultDocumentMap option (or by setting the
TypeEmbeddedDocument mapping in the provided registry) before calling
dec.SetRegistry(reg) so nested documents decode into map[string]interface{}
instead of bson.D; target the bsonToMap function and adjust registry
construction/registration accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@connectors/dynamodb/conv.go`:
- Around line 117-123: In the case handling *types.AttributeValueMemberBS in
connectors/dynamodb/conv.go (inside the conversion function), remove the extra
nil being appended so each DynamoDB BS element appends only the bson.Binary
value; replace the current append(arr, bson.Binary{Subtype:
bson.TypeBinaryGeneric, Data: v}, nil) with a single-value append like
append(arr, bson.Binary{Subtype: bson.TypeBinaryGeneric, Data: v}) so binary
sets no longer get interleaved nils.

In `@connectors/s3vector/conn.go`:
- Line 117: The code currently casts first.GetType() (a uint32) directly to
bson.Type (a byte) before calling bson.UnmarshalValue in function/method around
conn.go, which can silently truncate values >255; add explicit range validation:
read the uint32 via first.GetType(), if it is >255 or less than 0 (checking
upper bound is sufficient for unsigned) return an error (or propagate)
indicating invalid BSON type, otherwise cast to bson.Type and proceed to call
bson.UnmarshalValue(&idAny) as before; update the error path where
bson.UnmarshalValue(bson.Type(first.GetType()), first.GetData(), &idAny) is used
so invalid type values fail fast with a clear error message.

---

Outside diff comments:
In `@connectors/mongo/conn.go`:
- Around line 954-965: If mongo.Connect succeeds but client.Ping fails, the code
currently returns without disconnecting the client; update the Ping error path
to call client.Disconnect(...) (e.g., client.Disconnect(context.Background()))
and handle or log any disconnect error before returning the Ping error so
resources are cleaned up; also correct the successful return to return the
connected client and nil error (replace returning err with nil) so the function
returns (client, nil) on success.

---

Nitpick comments:
In `@connectors/cosmos/check_deletes.go`:
- Line 181: The unchecked type assertion on res["missingIds"] to bson.A can
panic if a custom codec returns a different type; update the code around the
missingIds assignment in checkDeletes (variable missingIds and map res) to use a
guarded type assertion (ok idiom) or a type switch: attempt to cast to bson.A,
else handle []interface{} or nil cases, and fall back to constructing missingIds
safely (e.g., iterate and append elements) or return an error; ensure the
subsequent code uses the safely constructed missingIds variable.

In `@connectors/postgres/bson_conv.go`:
- Around line 10-15: bsonToMap currently decodes embedded documents into bson.D
because the registry lacks the explicit document-map mapping; update bsonToMap
to opt into recursive plain maps by using a registry built with the
DefaultDocumentMap option (or by setting the TypeEmbeddedDocument mapping in the
provided registry) before calling dec.SetRegistry(reg) so nested documents
decode into map[string]interface{} instead of bson.D; target the bsonToMap
function and adjust registry construction/registration accordingly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d37048a9-c65b-4df6-9761-3b1091e5a72e

📥 Commits

Reviewing files that changed from the base of the PR and between 65ec928 and 56d0f76.

⛔ Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (36)
  • connectors/airbyte/helpers.go
  • connectors/common/base.go
  • connectors/common/hash_test.go
  • connectors/cosmos/change_streams.go
  • connectors/cosmos/check_deletes.go
  • connectors/cosmos/conn.go
  • connectors/cosmos/connector_test.go
  • connectors/cosmos/planner.go
  • connectors/cosmos/range_partitioning.go
  • connectors/cosmos/token_map.go
  • connectors/cosmos/util.go
  • connectors/dynamodb/conv.go
  • connectors/file/connector.go
  • connectors/file/connector_test.go
  • connectors/file/util.go
  • connectors/mongo/conn.go
  • connectors/mongo/connector_test.go
  • connectors/mongo/docdb.go
  • connectors/mongo/planner.go
  • connectors/mongo/util.go
  • connectors/null/connector.go
  • connectors/postgres/bson_conv.go
  • connectors/postgres/bson_registry.go
  • connectors/postgres/conn.go
  • connectors/random/connv2.go
  • connectors/random/util.go
  • connectors/s3/connector.go
  • connectors/s3vector/conn.go
  • connectors/sqlbatch/cs.go
  • connectors/testconn/connector.go
  • connectors/vector/conn.go
  • go.mod
  • internal/app/verify.go
  • pkg/test/connector.go
  • protocol/test/connector_testsuite.go
  • statestores/mongo/statestore.go

Comment thread connectors/dynamodb/conv.go Outdated
var res string
var idAny any
if err := bson.UnmarshalValue(bsontype.Type(first.GetType()), first.GetData(), &idAny); err != nil {
if err := bson.UnmarshalValue(bson.Type(first.GetType()), first.GetData(), &idAny); err != nil {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🌐 Web query:

In go.mongodb.org/mongo-driver/v2/bson, what is the underlying type and valid numeric range for bson.Type, and is converting from uint32 to bson.Type potentially lossy?

💡 Result:

In go.mongodb.org/mongo-driver/v2/bson, bson.Type is a type alias for byte (type Type byte). Its valid numeric range corresponds to defined BSON type constants: standard types from 0x01 (Double) to 0x13 (Decimal128), plus MinKey (0xFF) and MaxKey (0x7F). Values outside these are invalid per the bsontype.IsValid method (deprecated but indicative). Converting from uint32 to bson.Type is potentially lossy because uint32 (0 to 4,294,967,295) exceeds byte's range (0 to 255), truncating values >255.

Citations:


🏁 Script executed:

cat -n connectors/s3vector/conn.go | sed -n '100,130p'

Repository: adiom-data/dsync

Length of output: 1023


🏁 Script executed:

# Search for the definition of GetType() to understand what type it returns
rg "GetType\(\)" connectors/s3vector/conn.go -A 2 -B 2

Repository: adiom-data/dsync

Length of output: 704


🏁 Script executed:

# Find the type of 'first' variable to understand the full context
ast-grep --pattern 'first := $_'

Repository: adiom-data/dsync

Length of output: 108


🏁 Script executed:

fd -e proto -e go | xargs grep -l "BsonValue" | head -20

Repository: adiom-data/dsync

Length of output: 631


🏁 Script executed:

rg "type BsonValue" --type go -A 3

Repository: adiom-data/dsync

Length of output: 459


🏁 Script executed:

rg "func.*GetType" adiomv1 --type go -A 1

Repository: adiom-data/dsync

Length of output: 107


🏁 Script executed:

rg "func.*GetType\(\)" gen/adiom/v1/messages.pb.go -A 2

Repository: adiom-data/dsync

Length of output: 618


🏁 Script executed:

head -30 connectors/s3vector/conn.go | grep -E "^import|^$|^\s+\"fmt\""

Repository: adiom-data/dsync

Length of output: 78


🏁 Script executed:

cat -n connectors/s3vector/conn.go | sed -n '1,20p'

Repository: adiom-data/dsync

Length of output: 794


Add range validation before converting uint32 to bson.Type.

Line 117 converts first.GetType() (which returns uint32 from protobuf) directly to bson.Type (which is a byte with range 0–255). Values above 255 silently truncate without error. Add an explicit check to fail fast on invalid BSON type values:

Proposed fix
-		if err := bson.UnmarshalValue(bson.Type(first.GetType()), first.GetData(), &idAny); err != nil {
+		t := first.GetType()
+		if t > 255 {
+			return "", fmt.Errorf("unsupported bson type value: %d", t)
+		}
+		if err := bson.UnmarshalValue(bson.Type(t), first.GetData(), &idAny); err != nil {
 			return "", fmt.Errorf("err unmarshalling id: %w", err)
 		}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if err := bson.UnmarshalValue(bson.Type(first.GetType()), first.GetData(), &idAny); err != nil {
t := first.GetType()
if t > 255 {
return "", fmt.Errorf("unsupported bson type value: %d", t)
}
if err := bson.UnmarshalValue(bson.Type(t), first.GetData(), &idAny); err != nil {
return "", fmt.Errorf("err unmarshalling id: %w", err)
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@connectors/s3vector/conn.go` at line 117, The code currently casts
first.GetType() (a uint32) directly to bson.Type (a byte) before calling
bson.UnmarshalValue in function/method around conn.go, which can silently
truncate values >255; add explicit range validation: read the uint32 via
first.GetType(), if it is >255 or less than 0 (checking upper bound is
sufficient for unsigned) return an error (or propagate) indicating invalid BSON
type, otherwise cast to bson.Type and proceed to call
bson.UnmarshalValue(&idAny) as before; update the error path where
bson.UnmarshalValue(bson.Type(first.GetType()), first.GetData(), &idAny) is used
so invalid type values fail fast with a clear error message.

@adiom-mark
adiom-mark merged commit 4dae88c into main Mar 31, 2026
2 checks passed
@adiom-mark
adiom-mark deleted the mongo2 branch March 31, 2026 19:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant