From a9f34ad934fcb64116c23ab32afb52c6ede247e1 Mon Sep 17 00:00:00 2001 From: Qingyang Hu Date: Mon, 7 Jul 2025 18:58:25 -0400 Subject: [PATCH 01/13] add aggregate --- mongo/collection.go | 3 +++ mongo/options/aggregateoptions.go | 13 +++++++++++++ x/mongo/driver/operation/aggregate.go | 15 +++++++++++++++ 3 files changed, 31 insertions(+) diff --git a/mongo/collection.go b/mongo/collection.go index d7693c4245..a48266efd0 100644 --- a/mongo/collection.go +++ b/mongo/collection.go @@ -1036,6 +1036,9 @@ func aggregate(a aggregateParams, opts ...options.Lister[options.AggregateOption } op.CustomOptions(customOptions) } + if args.RawData != nil { + op = op.RawData(*args.RawData) + } retry := driver.RetryNone if a.retryRead && !hasOutputStage { diff --git a/mongo/options/aggregateoptions.go b/mongo/options/aggregateoptions.go index cf419677dc..5c1513c98a 100644 --- a/mongo/options/aggregateoptions.go +++ b/mongo/options/aggregateoptions.go @@ -26,6 +26,7 @@ type AggregateOptions struct { Hint interface{} Let interface{} Custom bson.M + RawData *bool } // AggregateOptionsBuilder contains options to configure aggregate operations. @@ -163,3 +164,15 @@ func (ao *AggregateOptionsBuilder) SetCustom(c bson.M) *AggregateOptionsBuilder return ao } + +// SetRawData sets the value for the RawData field. If true, it allows the CRUD operations to access timeseries +// collections on the bucket-level. This option is only valid for MongoDB versions >= 9.0. The default value is false. +func (ao *AggregateOptionsBuilder) SetRawData(rawData bool) *AggregateOptionsBuilder { + ao.Opts = append(ao.Opts, func(opts *AggregateOptions) error { + opts.RawData = &rawData + + return nil + }) + + return ao +} diff --git a/x/mongo/driver/operation/aggregate.go b/x/mongo/driver/operation/aggregate.go index a0cd5bd25e..380789ab04 100644 --- a/x/mongo/driver/operation/aggregate.go +++ b/x/mongo/driver/operation/aggregate.go @@ -50,6 +50,7 @@ type Aggregate struct { customOptions map[string]bsoncore.Value timeout *time.Duration omitMaxTimeMS bool + rawData *bool result driver.CursorResponse } @@ -159,6 +160,10 @@ func (a *Aggregate) command(dst []byte, desc description.SelectedServer) ([]byte if a.let != nil { dst = bsoncore.AppendDocumentElement(dst, "let", a.let) } + // Set rawData for 8.2+ servers. + if a.rawData != nil && desc.WireVersion != nil && driverutil.VersionRangeIncludes(*desc.WireVersion, 27) { + dst = bsoncore.AppendBooleanElement(dst, "rawData", *a.rawData) + } for optionName, optionValue := range a.customOptions { dst = bsoncore.AppendValueElement(dst, optionName, optionValue) } @@ -431,3 +436,13 @@ func (a *Aggregate) OmitMaxTimeMS(omit bool) *Aggregate { a.omitMaxTimeMS = omit return a } + +// RawData sets the rawData to access timeseries data in the compressed format. +func (a *Aggregate) RawData(rawData bool) *Aggregate { + if a == nil { + a = new(Aggregate) + } + + a.rawData = &rawData + return a +} From 547db1d3280a26930f1fa105bcf860d18d49fcbd Mon Sep 17 00:00:00 2001 From: Qingyang Hu Date: Mon, 7 Jul 2025 19:36:31 -0400 Subject: [PATCH 02/13] add count --- mongo/collection.go | 6 ++++++ mongo/options/countoptions.go | 13 +++++++++++++ mongo/options/estimatedcountoptions.go | 13 +++++++++++++ x/mongo/driver/operation/count.go | 17 ++++++++++++++++- 4 files changed, 48 insertions(+), 1 deletion(-) diff --git a/mongo/collection.go b/mongo/collection.go index a48266efd0..9085de2a87 100644 --- a/mongo/collection.go +++ b/mongo/collection.go @@ -1127,6 +1127,9 @@ func (coll *Collection) CountDocuments(ctx context.Context, filter interface{}, } op.Hint(hintVal) } + if args.RawData != nil { + op = op.RawData(*args.RawData) + } retry := driver.RetryNone if coll.client.retryReads { retry = driver.RetryOncePerCommand @@ -1208,6 +1211,9 @@ func (coll *Collection) EstimatedDocumentCount( } op = op.Comment(comment) } + if args.RawData != nil { + op = op.RawData(*args.RawData) + } retry := driver.RetryNone if coll.client.retryReads { diff --git a/mongo/options/countoptions.go b/mongo/options/countoptions.go index 27df828b00..ab16764529 100644 --- a/mongo/options/countoptions.go +++ b/mongo/options/countoptions.go @@ -16,6 +16,7 @@ type CountOptions struct { Hint interface{} Limit *int64 Skip *int64 + RawData *bool } // CountOptionsBuilder contains options to configure count operations. Each @@ -99,3 +100,15 @@ func (co *CountOptionsBuilder) SetSkip(i int64) *CountOptionsBuilder { return co } + +// SetRawData sets the value for the RawData field. If true, it allows the CRUD operations to access timeseries +// collections on the bucket-level. This option is only valid for MongoDB versions >= 9.0. The default value is false. +func (co *CountOptionsBuilder) SetRawData(rawData bool) *CountOptionsBuilder { + co.Opts = append(co.Opts, func(opts *CountOptions) error { + opts.RawData = &rawData + + return nil + }) + + return co +} diff --git a/mongo/options/estimatedcountoptions.go b/mongo/options/estimatedcountoptions.go index 2bee45a8f6..e30ea42a85 100644 --- a/mongo/options/estimatedcountoptions.go +++ b/mongo/options/estimatedcountoptions.go @@ -12,6 +12,7 @@ package options // See corresponding setter methods for documentation. type EstimatedDocumentCountOptions struct { Comment interface{} + RawData *bool } // EstimatedDocumentCountOptionsBuilder contains options to estimate document @@ -44,3 +45,15 @@ func (eco *EstimatedDocumentCountOptionsBuilder) SetComment(comment interface{}) return eco } + +// SetRawData sets the value for the RawData field. If true, it allows the CRUD operations to access timeseries +// collections on the bucket-level. This option is only valid for MongoDB versions >= 9.0. The default value is false. +func (eco *EstimatedDocumentCountOptionsBuilder) SetRawData(rawData bool) *EstimatedDocumentCountOptionsBuilder { + eco.Opts = append(eco.Opts, func(opts *EstimatedDocumentCountOptions) error { + opts.RawData = &rawData + + return nil + }) + + return eco +} diff --git a/x/mongo/driver/operation/count.go b/x/mongo/driver/operation/count.go index 5ecaa3a936..d056702aab 100644 --- a/x/mongo/driver/operation/count.go +++ b/x/mongo/driver/operation/count.go @@ -41,6 +41,7 @@ type Count struct { result CountResult serverAPI *driver.ServerAPIOptions timeout *time.Duration + rawData *bool } // CountResult represents a count result returned by the server. @@ -139,7 +140,7 @@ func (c *Count) Execute(ctx context.Context) error { return err } -func (c *Count) command(dst []byte, _ description.SelectedServer) ([]byte, error) { +func (c *Count) command(dst []byte, desc description.SelectedServer) ([]byte, error) { dst = bsoncore.AppendStringElement(dst, "count", c.collection) if c.query != nil { dst = bsoncore.AppendDocumentElement(dst, "query", c.query) @@ -147,6 +148,10 @@ func (c *Count) command(dst []byte, _ description.SelectedServer) ([]byte, error if c.comment.Type != bsoncore.Type(0) { dst = bsoncore.AppendValueElement(dst, "comment", c.comment) } + // Set rawData for 8.2+ servers. + if c.rawData != nil && desc.WireVersion != nil && driverutil.VersionRangeIncludes(*desc.WireVersion, 27) { + dst = bsoncore.AppendBooleanElement(dst, "rawData", *c.rawData) + } return dst, nil } @@ -310,3 +315,13 @@ func (c *Count) Authenticator(authenticator driver.Authenticator) *Count { c.authenticator = authenticator return c } + +// RawData sets the rawData to access timeseries data in the compressed format. +func (c *Count) RawData(rawData bool) *Count { + if c == nil { + c = new(Count) + } + + c.rawData = &rawData + return c +} From b1bb1fc0cbe4cc52d9f9bef5890e82f5a0a748a5 Mon Sep 17 00:00:00 2001 From: Qingyang Hu Date: Mon, 7 Jul 2025 20:00:36 -0400 Subject: [PATCH 03/13] add delete --- mongo/collection.go | 4 ++++ mongo/options/deleteoptions.go | 26 ++++++++++++++++++++++++++ x/mongo/driver/operation/delete.go | 15 +++++++++++++++ 3 files changed, 45 insertions(+) diff --git a/mongo/collection.go b/mongo/collection.go index 9085de2a87..71a68cf21d 100644 --- a/mongo/collection.go +++ b/mongo/collection.go @@ -534,6 +534,9 @@ func (coll *Collection) delete( } op = op.Let(let) } + if args.RawData != nil { + op = op.RawData(*args.RawData) + } // deleteMany cannot be retried retryMode := driver.RetryNone @@ -575,6 +578,7 @@ func (coll *Collection) DeleteOne( Comment: args.Comment, Hint: args.Hint, Let: args.Let, + RawData: args.RawData, } return coll.delete(ctx, filter, true, rrOne, deleteOptions) diff --git a/mongo/options/deleteoptions.go b/mongo/options/deleteoptions.go index 1d045d9960..2034483a40 100644 --- a/mongo/options/deleteoptions.go +++ b/mongo/options/deleteoptions.go @@ -15,6 +15,7 @@ type DeleteOneOptions struct { Comment interface{} Hint interface{} Let interface{} + RawData *bool } // DeleteOneOptionsBuilder contains options to configure DeleteOne operations. Each @@ -93,6 +94,18 @@ func (do *DeleteOneOptionsBuilder) SetLet(let interface{}) *DeleteOneOptionsBuil return do } +// SetRawData sets the value for the RawData field. If true, it allows the CRUD operations to access timeseries +// collections on the bucket-level. This option is only valid for MongoDB versions >= 9.0. The default value is false. +func (do *DeleteOneOptionsBuilder) SetRawData(rawData bool) *DeleteOneOptionsBuilder { + do.Opts = append(do.Opts, func(opts *DeleteOneOptions) error { + opts.RawData = &rawData + + return nil + }) + + return do +} + // DeleteManyOptions represents arguments that can be used to configure DeleteMany // operations. // @@ -102,6 +115,7 @@ type DeleteManyOptions struct { Comment interface{} Hint interface{} Let interface{} + RawData *bool } // DeleteManyOptionsBuilder contains options to configure DeleteMany operations. @@ -179,3 +193,15 @@ func (do *DeleteManyOptionsBuilder) SetLet(let interface{}) *DeleteManyOptionsBu return do } + +// SetRawData sets the value for the RawData field. If true, it allows the CRUD operations to access timeseries +// collections on the bucket-level. This option is only valid for MongoDB versions >= 9.0. The default value is false. +func (do *DeleteManyOptionsBuilder) SetRawData(rawData bool) *DeleteManyOptionsBuilder { + do.Opts = append(do.Opts, func(opts *DeleteManyOptions) error { + opts.RawData = &rawData + + return nil + }) + + return do +} diff --git a/x/mongo/driver/operation/delete.go b/x/mongo/driver/operation/delete.go index e6f47042a8..e4510fb8fa 100644 --- a/x/mongo/driver/operation/delete.go +++ b/x/mongo/driver/operation/delete.go @@ -43,6 +43,7 @@ type Delete struct { serverAPI *driver.ServerAPIOptions let bsoncore.Document timeout *time.Duration + rawData *bool logger *logger.Logger } @@ -139,6 +140,10 @@ func (d *Delete) command(dst []byte, desc description.SelectedServer) ([]byte, e if d.let != nil { dst = bsoncore.AppendDocumentElement(dst, "let", d.let) } + // Set rawData for 8.2+ servers. + if d.rawData != nil && desc.WireVersion != nil && driverutil.VersionRangeIncludes(*desc.WireVersion, 27) { + dst = bsoncore.AppendBooleanElement(dst, "rawData", *d.rawData) + } return dst, nil } @@ -337,3 +342,13 @@ func (d *Delete) Authenticator(authenticator driver.Authenticator) *Delete { d.authenticator = authenticator return d } + +// RawData sets the rawData to access timeseries data in the compressed format. +func (d *Delete) RawData(rawData bool) *Delete { + if d == nil { + d = new(Delete) + } + + d.rawData = &rawData + return d +} From 4485d8ee21127bbdde6868d8c0350ea629bab4a5 Mon Sep 17 00:00:00 2001 From: Qingyang Hu Date: Mon, 7 Jul 2025 21:24:32 -0400 Subject: [PATCH 04/13] add distinct --- mongo/collection.go | 3 +++ mongo/options/distinctoptions.go | 13 +++++++++++++ x/mongo/driver/operation/distinct.go | 15 +++++++++++++++ 3 files changed, 31 insertions(+) diff --git a/mongo/collection.go b/mongo/collection.go index 71a68cf21d..0e23bcc59a 100644 --- a/mongo/collection.go +++ b/mongo/collection.go @@ -1307,6 +1307,9 @@ func (coll *Collection) Distinct( } op.Hint(hint) } + if args.RawData != nil { + op = op.RawData(*args.RawData) + } retry := driver.RetryNone if coll.client.retryReads { retry = driver.RetryOncePerCommand diff --git a/mongo/options/distinctoptions.go b/mongo/options/distinctoptions.go index 3449ecee36..2ea2acf249 100644 --- a/mongo/options/distinctoptions.go +++ b/mongo/options/distinctoptions.go @@ -14,6 +14,7 @@ type DistinctOptions struct { Collation *Collation Comment interface{} Hint interface{} + RawData *bool } // DistinctOptionsBuilder contains options to configure distinct operations. Each @@ -77,3 +78,15 @@ func (do *DistinctOptionsBuilder) SetHint(hint interface{}) *DistinctOptionsBuil return do } + +// SetRawData sets the value for the RawData field. If true, it allows the CRUD operations to access timeseries +// collections on the bucket-level. This option is only valid for MongoDB versions >= 9.0. The default value is false. +func (do *DistinctOptionsBuilder) SetRawData(rawData bool) *DistinctOptionsBuilder { + do.Opts = append(do.Opts, func(opts *DistinctOptions) error { + opts.RawData = &rawData + + return nil + }) + + return do +} diff --git a/x/mongo/driver/operation/distinct.go b/x/mongo/driver/operation/distinct.go index 89d412def3..ef235e2475 100644 --- a/x/mongo/driver/operation/distinct.go +++ b/x/mongo/driver/operation/distinct.go @@ -43,6 +43,7 @@ type Distinct struct { result DistinctResult serverAPI *driver.ServerAPIOptions timeout *time.Duration + rawData *bool } // DistinctResult represents a distinct result returned by the server. @@ -130,6 +131,10 @@ func (d *Distinct) command(dst []byte, desc description.SelectedServer) ([]byte, if d.query != nil { dst = bsoncore.AppendDocumentElement(dst, "query", d.query) } + // Set rawData for 8.2+ servers. + if d.rawData != nil && desc.WireVersion != nil && driverutil.VersionRangeIncludes(*desc.WireVersion, 27) { + dst = bsoncore.AppendBooleanElement(dst, "rawData", *d.rawData) + } return dst, nil } @@ -323,3 +328,13 @@ func (d *Distinct) Authenticator(authenticator driver.Authenticator) *Distinct { d.authenticator = authenticator return d } + +// RawData sets the rawData to access timeseries data in the compressed format. +func (d *Distinct) RawData(rawData bool) *Distinct { + if d == nil { + d = new(Distinct) + } + + d.rawData = &rawData + return d +} From b573bb74372e6c5fc264499275147d3f3dca71d2 Mon Sep 17 00:00:00 2001 From: Qingyang Hu Date: Mon, 7 Jul 2025 22:38:26 -0400 Subject: [PATCH 05/13] add insert --- mongo/collection.go | 6 ++++++ mongo/options/insertoptions.go | 26 ++++++++++++++++++++++++++ x/mongo/driver/operation/insert.go | 15 +++++++++++++++ 3 files changed, 47 insertions(+) diff --git a/mongo/collection.go b/mongo/collection.go index 0e23bcc59a..d7dabe5b72 100644 --- a/mongo/collection.go +++ b/mongo/collection.go @@ -324,6 +324,9 @@ func (coll *Collection) insert( if args.Ordered != nil { op = op.Ordered(*args.Ordered) } + if args.RawData != nil { + op = op.RawData(*args.RawData) + } retry := driver.RetryNone if coll.client.retryWrites { retry = driver.RetryOncePerCommand @@ -375,6 +378,9 @@ func (coll *Collection) InsertOne(ctx context.Context, document interface{}, if args.Comment != nil { imOpts.SetComment(args.Comment) } + if args.RawData != nil { + imOpts = imOpts.SetRawData(*args.RawData) + } res, err := coll.insert(ctx, []interface{}{document}, imOpts) rr, err := processWriteError(err) diff --git a/mongo/options/insertoptions.go b/mongo/options/insertoptions.go index 61745600a9..de282f8628 100644 --- a/mongo/options/insertoptions.go +++ b/mongo/options/insertoptions.go @@ -13,6 +13,7 @@ package options type InsertOneOptions struct { BypassDocumentValidation *bool Comment interface{} + RawData *bool } // InsertOneOptionsBuilder represents functional options that configure an @@ -53,6 +54,18 @@ func (ioo *InsertOneOptionsBuilder) SetComment(comment interface{}) *InsertOneOp return ioo } +// SetRawData sets the value for the RawData field. If true, it allows the CRUD operations to access timeseries +// collections on the bucket-level. This option is only valid for MongoDB versions >= 9.0. The default value is false. +func (ioo *InsertOneOptionsBuilder) SetRawData(rawData bool) *InsertOneOptionsBuilder { + ioo.Opts = append(ioo.Opts, func(ioo *InsertOneOptions) error { + ioo.RawData = &rawData + + return nil + }) + + return ioo +} + // InsertManyOptions represents arguments that can be used to configure an // InsertMany operation. // @@ -61,6 +74,7 @@ type InsertManyOptions struct { BypassDocumentValidation *bool Comment interface{} Ordered *bool + RawData *bool } // InsertManyOptionsBuilder contains options to configure insert operations. @@ -121,3 +135,15 @@ func (imo *InsertManyOptionsBuilder) SetOrdered(b bool) *InsertManyOptionsBuilde return imo } + +// SetRawData sets the value for the RawData field. If true, it allows the CRUD operations to access timeseries +// collections on the bucket-level. This option is only valid for MongoDB versions >= 9.0. The default value is false. +func (imo *InsertManyOptionsBuilder) SetRawData(rawData bool) *InsertManyOptionsBuilder { + imo.Opts = append(imo.Opts, func(opts *InsertManyOptions) error { + opts.RawData = &rawData + + return nil + }) + + return imo +} diff --git a/x/mongo/driver/operation/insert.go b/x/mongo/driver/operation/insert.go index b48e2c85f3..57d461ae3b 100644 --- a/x/mongo/driver/operation/insert.go +++ b/x/mongo/driver/operation/insert.go @@ -42,6 +42,7 @@ type Insert struct { result InsertResult serverAPI *driver.ServerAPIOptions timeout *time.Duration + rawData *bool logger *logger.Logger } @@ -132,6 +133,10 @@ func (i *Insert) command(dst []byte, desc description.SelectedServer) ([]byte, e if i.ordered != nil { dst = bsoncore.AppendBooleanElement(dst, "ordered", *i.ordered) } + // Set rawData for 8.2+ servers. + if i.rawData != nil && desc.WireVersion != nil && driverutil.VersionRangeIncludes(*desc.WireVersion, 27) { + dst = bsoncore.AppendBooleanElement(dst, "rawData", *i.rawData) + } return dst, nil } @@ -318,3 +323,13 @@ func (i *Insert) Authenticator(authenticator driver.Authenticator) *Insert { i.authenticator = authenticator return i } + +// RawData sets the rawData to access timeseries data in the compressed format. +func (i *Insert) RawData(rawData bool) *Insert { + if i == nil { + i = new(Insert) + } + + i.rawData = &rawData + return i +} From 6724da36f3b6c453b8e6686c9193b6e5fca6b9f7 Mon Sep 17 00:00:00 2001 From: Qingyang Hu Date: Mon, 7 Jul 2025 22:43:25 -0400 Subject: [PATCH 06/13] update integration --- .../unified/collection_operation_execution.go | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/internal/integration/unified/collection_operation_execution.go b/internal/integration/unified/collection_operation_execution.go index c3e7040256..fdb2947ca0 100644 --- a/internal/integration/unified/collection_operation_execution.go +++ b/internal/integration/unified/collection_operation_execution.go @@ -75,6 +75,8 @@ func executeAggregate(ctx context.Context, operation *operation) (*operationResu pipeline = bsonutil.RawToInterfaces(bsonutil.RawArrayToDocuments(val.Array())...) case "let": opts.SetLet(val.Document()) + case "rawData": + opts.SetRawData(val.Boolean()) default: return nil, fmt.Errorf("unrecognized aggregate option %q", key) } @@ -202,6 +204,8 @@ func executeCountDocuments(ctx context.Context, operation *operation) (*operatio return nil, fmt.Errorf("the maxTimeMS collection option is not supported") case "skip": opts.SetSkip(int64(val.Int32())) + case "rawData": + opts.SetRawData(val.Boolean()) default: return nil, fmt.Errorf("unrecognized countDocuments option %q", key) } @@ -433,6 +437,8 @@ func executeDeleteOne(ctx context.Context, operation *operation) (*operationResu opts.SetHint(hint) case "let": opts.SetLet(val.Document()) + case "rawData": + opts.SetRawData(val.Boolean()) default: return nil, fmt.Errorf("unrecognized deleteOne option %q", key) } @@ -487,6 +493,8 @@ func executeDeleteMany(ctx context.Context, operation *operation) (*operationRes opts.SetHint(hint) case "let": opts.SetLet(val.Document()) + case "rawData": + opts.SetRawData(val.Boolean()) default: return nil, fmt.Errorf("unrecognized deleteMany option %q", key) } @@ -545,6 +553,8 @@ func executeDistinct(ctx context.Context, operation *operation) (*operationResul // ensured an analogue exists, extend "skippedTestDescriptions" to avoid // this error. return nil, fmt.Errorf("the maxTimeMS collection option is not supported") + case "rawData": + opts.SetRawData(val.Boolean()) default: return nil, fmt.Errorf("unrecognized distinct option %q", key) } @@ -690,6 +700,8 @@ func executeEstimatedDocumentCount(ctx context.Context, operation *operation) (* // ensured an analogue exists, extend "skippedTestDescriptions" to avoid // this error. return nil, fmt.Errorf("the maxTimeMS collection option is not supported") + case "rawData": + opts.SetRawData(val.Boolean()) default: return nil, fmt.Errorf("unrecognized estimatedDocumentCount option %q", key) } @@ -1062,6 +1074,8 @@ func executeInsertMany(ctx context.Context, operation *operation) (*operationRes documents = bsonutil.RawToInterfaces(bsonutil.RawArrayToDocuments(val.Array())...) case "ordered": opts.SetOrdered(val.Boolean()) + case "rawData": + opts.SetRawData(val.Boolean()) default: return nil, fmt.Errorf("unrecognized insertMany option %q", key) } @@ -1112,6 +1126,8 @@ func executeInsertOne(ctx context.Context, operation *operation) (*operationResu opts.SetBypassDocumentValidation(val.Boolean()) case "comment": opts.SetComment(val) + case "rawData": + opts.SetRawData(val.Boolean()) default: return nil, fmt.Errorf("unrecognized insertOne option %q", key) } From 244ab641edf4e7c8497de48f08a7825825b6aeb9 Mon Sep 17 00:00:00 2001 From: Qingyang Hu Date: Fri, 18 Jul 2025 13:43:29 -0400 Subject: [PATCH 07/13] make rawDate internal --- .../unified/collection_operation_execution.go | 41 +++- mongo/collection.go | 55 ++++-- mongo/options/aggregateoptions.go | 18 +- mongo/options/countoptions.go | 19 +- mongo/options/deleteoptions.go | 36 +--- mongo/options/distinctoptions.go | 19 +- mongo/options/estimatedcountoptions.go | 19 +- mongo/options/insertoptions.go | 36 +--- x/mongo/driver/xoptions/options.go | 184 ++++++++++++++++++ 9 files changed, 296 insertions(+), 131 deletions(-) diff --git a/internal/integration/unified/collection_operation_execution.go b/internal/integration/unified/collection_operation_execution.go index fdb2947ca0..e58a869eed 100644 --- a/internal/integration/unified/collection_operation_execution.go +++ b/internal/integration/unified/collection_operation_execution.go @@ -19,6 +19,7 @@ import ( "go.mongodb.org/mongo-driver/v2/mongo" "go.mongodb.org/mongo-driver/v2/mongo/options" "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore" + "go.mongodb.org/mongo-driver/v2/x/mongo/driver/xoptions" ) // This file contains helpers to execute collection operations. @@ -76,7 +77,10 @@ func executeAggregate(ctx context.Context, operation *operation) (*operationResu case "let": opts.SetLet(val.Document()) case "rawData": - opts.SetRawData(val.Boolean()) + err = xoptions.SetInternalAggregateOptions(opts, key, val.Boolean()) + if err != nil { + return nil, err + } default: return nil, fmt.Errorf("unrecognized aggregate option %q", key) } @@ -205,7 +209,10 @@ func executeCountDocuments(ctx context.Context, operation *operation) (*operatio case "skip": opts.SetSkip(int64(val.Int32())) case "rawData": - opts.SetRawData(val.Boolean()) + err = xoptions.SetInternalCountOptions(opts, key, val.Boolean()) + if err != nil { + return nil, err + } default: return nil, fmt.Errorf("unrecognized countDocuments option %q", key) } @@ -438,7 +445,10 @@ func executeDeleteOne(ctx context.Context, operation *operation) (*operationResu case "let": opts.SetLet(val.Document()) case "rawData": - opts.SetRawData(val.Boolean()) + err = xoptions.SetInternalDeleteOneOptions(opts, key, val.Boolean()) + if err != nil { + return nil, err + } default: return nil, fmt.Errorf("unrecognized deleteOne option %q", key) } @@ -494,7 +504,10 @@ func executeDeleteMany(ctx context.Context, operation *operation) (*operationRes case "let": opts.SetLet(val.Document()) case "rawData": - opts.SetRawData(val.Boolean()) + err = xoptions.SetInternalDeleteManyOptions(opts, key, val.Boolean()) + if err != nil { + return nil, err + } default: return nil, fmt.Errorf("unrecognized deleteMany option %q", key) } @@ -554,7 +567,10 @@ func executeDistinct(ctx context.Context, operation *operation) (*operationResul // this error. return nil, fmt.Errorf("the maxTimeMS collection option is not supported") case "rawData": - opts.SetRawData(val.Boolean()) + err = xoptions.SetInternalDistinctOptions(opts, key, val.Boolean()) + if err != nil { + return nil, err + } default: return nil, fmt.Errorf("unrecognized distinct option %q", key) } @@ -701,7 +717,10 @@ func executeEstimatedDocumentCount(ctx context.Context, operation *operation) (* // this error. return nil, fmt.Errorf("the maxTimeMS collection option is not supported") case "rawData": - opts.SetRawData(val.Boolean()) + err = xoptions.SetInternalEstimatedDocumentCountOptions(opts, key, val.Boolean()) + if err != nil { + return nil, err + } default: return nil, fmt.Errorf("unrecognized estimatedDocumentCount option %q", key) } @@ -1075,7 +1094,10 @@ func executeInsertMany(ctx context.Context, operation *operation) (*operationRes case "ordered": opts.SetOrdered(val.Boolean()) case "rawData": - opts.SetRawData(val.Boolean()) + err = xoptions.SetInternalInsertManyOptions(opts, key, val.Boolean()) + if err != nil { + return nil, err + } default: return nil, fmt.Errorf("unrecognized insertMany option %q", key) } @@ -1127,7 +1149,10 @@ func executeInsertOne(ctx context.Context, operation *operation) (*operationResu case "comment": opts.SetComment(val) case "rawData": - opts.SetRawData(val.Boolean()) + err = xoptions.SetInternalInsertOneOptions(opts, key, val.Boolean()) + if err != nil { + return nil, err + } default: return nil, fmt.Errorf("unrecognized insertOne option %q", key) } diff --git a/mongo/collection.go b/mongo/collection.go index d7dabe5b72..9017b831f8 100644 --- a/mongo/collection.go +++ b/mongo/collection.go @@ -17,6 +17,7 @@ import ( "go.mongodb.org/mongo-driver/v2/bson" "go.mongodb.org/mongo-driver/v2/internal/csfle" "go.mongodb.org/mongo-driver/v2/internal/mongoutil" + "go.mongodb.org/mongo-driver/v2/internal/optionsutil" "go.mongodb.org/mongo-driver/v2/internal/serverselector" "go.mongodb.org/mongo-driver/v2/mongo/options" "go.mongodb.org/mongo-driver/v2/mongo/readconcern" @@ -324,8 +325,10 @@ func (coll *Collection) insert( if args.Ordered != nil { op = op.Ordered(*args.Ordered) } - if args.RawData != nil { - op = op.RawData(*args.RawData) + if rawDataOpt := optionsutil.Value(args.CustomOptions, "rawData"); rawDataOpt != nil { + if rawData, ok := rawDataOpt.(bool); ok { + op = op.RawData(rawData) + } } retry := driver.RetryNone if coll.client.retryWrites { @@ -378,8 +381,12 @@ func (coll *Collection) InsertOne(ctx context.Context, document interface{}, if args.Comment != nil { imOpts.SetComment(args.Comment) } - if args.RawData != nil { - imOpts = imOpts.SetRawData(*args.RawData) + if rawDataOpt := optionsutil.Value(args.CustomOptions, "rawData"); rawDataOpt != nil { + imOpts.Opts = append(imOpts.Opts, func(opts *options.InsertManyOptions) error { + optionsutil.WithValue(opts.CustomOptions, "rawData", rawDataOpt) + + return nil + }) } res, err := coll.insert(ctx, []interface{}{document}, imOpts) @@ -540,8 +547,10 @@ func (coll *Collection) delete( } op = op.Let(let) } - if args.RawData != nil { - op = op.RawData(*args.RawData) + if rawDataOpt := optionsutil.Value(args.CustomOptions, "rawData"); rawDataOpt != nil { + if rawData, ok := rawDataOpt.(bool); ok { + op = op.RawData(rawData) + } } // deleteMany cannot be retried @@ -580,11 +589,11 @@ func (coll *Collection) DeleteOne( return nil, fmt.Errorf("failed to construct options from builder: %w", err) } deleteOptions := &options.DeleteManyOptions{ - Collation: args.Collation, - Comment: args.Comment, - Hint: args.Hint, - Let: args.Let, - RawData: args.RawData, + Collation: args.Collation, + Comment: args.Comment, + Hint: args.Hint, + Let: args.Let, + CustomOptions: args.CustomOptions, } return coll.delete(ctx, filter, true, rrOne, deleteOptions) @@ -1046,8 +1055,10 @@ func aggregate(a aggregateParams, opts ...options.Lister[options.AggregateOption } op.CustomOptions(customOptions) } - if args.RawData != nil { - op = op.RawData(*args.RawData) + if rawDataOpt := optionsutil.Value(args.CustomOptions, "rawData"); rawDataOpt != nil { + if rawData, ok := rawDataOpt.(bool); ok { + op = op.RawData(rawData) + } } retry := driver.RetryNone @@ -1137,8 +1148,10 @@ func (coll *Collection) CountDocuments(ctx context.Context, filter interface{}, } op.Hint(hintVal) } - if args.RawData != nil { - op = op.RawData(*args.RawData) + if rawDataOpt := optionsutil.Value(args.CustomOptions, "rawData"); rawDataOpt != nil { + if rawData, ok := rawDataOpt.(bool); ok { + op = op.RawData(rawData) + } } retry := driver.RetryNone if coll.client.retryReads { @@ -1221,8 +1234,10 @@ func (coll *Collection) EstimatedDocumentCount( } op = op.Comment(comment) } - if args.RawData != nil { - op = op.RawData(*args.RawData) + if rawDataOpt := optionsutil.Value(args.CustomOptions, "rawData"); rawDataOpt != nil { + if rawData, ok := rawDataOpt.(bool); ok { + op = op.RawData(rawData) + } } retry := driver.RetryNone @@ -1313,8 +1328,10 @@ func (coll *Collection) Distinct( } op.Hint(hint) } - if args.RawData != nil { - op = op.RawData(*args.RawData) + if rawDataOpt := optionsutil.Value(args.CustomOptions, "rawData"); rawDataOpt != nil { + if rawData, ok := rawDataOpt.(bool); ok { + op = op.RawData(rawData) + } } retry := driver.RetryNone if coll.client.retryReads { diff --git a/mongo/options/aggregateoptions.go b/mongo/options/aggregateoptions.go index 5c1513c98a..432358dfce 100644 --- a/mongo/options/aggregateoptions.go +++ b/mongo/options/aggregateoptions.go @@ -10,6 +10,7 @@ import ( "time" "go.mongodb.org/mongo-driver/v2/bson" + "go.mongodb.org/mongo-driver/v2/internal/optionsutil" ) // AggregateOptions represents arguments that can be used to configure an @@ -26,7 +27,10 @@ type AggregateOptions struct { Hint interface{} Let interface{} Custom bson.M - RawData *bool + + // Deprecated: This option is for internal use only and should not be set. It may be changed or removed in any + // release. + CustomOptions optionsutil.Options } // AggregateOptionsBuilder contains options to configure aggregate operations. @@ -164,15 +168,3 @@ func (ao *AggregateOptionsBuilder) SetCustom(c bson.M) *AggregateOptionsBuilder return ao } - -// SetRawData sets the value for the RawData field. If true, it allows the CRUD operations to access timeseries -// collections on the bucket-level. This option is only valid for MongoDB versions >= 9.0. The default value is false. -func (ao *AggregateOptionsBuilder) SetRawData(rawData bool) *AggregateOptionsBuilder { - ao.Opts = append(ao.Opts, func(opts *AggregateOptions) error { - opts.RawData = &rawData - - return nil - }) - - return ao -} diff --git a/mongo/options/countoptions.go b/mongo/options/countoptions.go index ab16764529..bc226fdc40 100644 --- a/mongo/options/countoptions.go +++ b/mongo/options/countoptions.go @@ -6,6 +6,8 @@ package options +import "go.mongodb.org/mongo-driver/v2/internal/optionsutil" + // CountOptions represents arguments that can be used to configure a // CountDocuments operation. // @@ -16,7 +18,10 @@ type CountOptions struct { Hint interface{} Limit *int64 Skip *int64 - RawData *bool + + // Deprecated: This option is for internal use only and should not be set. It may be changed or removed in any + // release. + CustomOptions optionsutil.Options } // CountOptionsBuilder contains options to configure count operations. Each @@ -100,15 +105,3 @@ func (co *CountOptionsBuilder) SetSkip(i int64) *CountOptionsBuilder { return co } - -// SetRawData sets the value for the RawData field. If true, it allows the CRUD operations to access timeseries -// collections on the bucket-level. This option is only valid for MongoDB versions >= 9.0. The default value is false. -func (co *CountOptionsBuilder) SetRawData(rawData bool) *CountOptionsBuilder { - co.Opts = append(co.Opts, func(opts *CountOptions) error { - opts.RawData = &rawData - - return nil - }) - - return co -} diff --git a/mongo/options/deleteoptions.go b/mongo/options/deleteoptions.go index 2034483a40..e19ecc5a92 100644 --- a/mongo/options/deleteoptions.go +++ b/mongo/options/deleteoptions.go @@ -6,6 +6,8 @@ package options +import "go.mongodb.org/mongo-driver/v2/internal/optionsutil" + // DeleteOneOptions represents arguments that can be used to configure DeleteOne // operations. // @@ -15,7 +17,10 @@ type DeleteOneOptions struct { Comment interface{} Hint interface{} Let interface{} - RawData *bool + + // Deprecated: This option is for internal use only and should not be set. It may be changed or removed in any + // release. + CustomOptions optionsutil.Options } // DeleteOneOptionsBuilder contains options to configure DeleteOne operations. Each @@ -94,18 +99,6 @@ func (do *DeleteOneOptionsBuilder) SetLet(let interface{}) *DeleteOneOptionsBuil return do } -// SetRawData sets the value for the RawData field. If true, it allows the CRUD operations to access timeseries -// collections on the bucket-level. This option is only valid for MongoDB versions >= 9.0. The default value is false. -func (do *DeleteOneOptionsBuilder) SetRawData(rawData bool) *DeleteOneOptionsBuilder { - do.Opts = append(do.Opts, func(opts *DeleteOneOptions) error { - opts.RawData = &rawData - - return nil - }) - - return do -} - // DeleteManyOptions represents arguments that can be used to configure DeleteMany // operations. // @@ -115,7 +108,10 @@ type DeleteManyOptions struct { Comment interface{} Hint interface{} Let interface{} - RawData *bool + + // Deprecated: This option is for internal use only and should not be set. It may be changed or removed in any + // release. + CustomOptions optionsutil.Options } // DeleteManyOptionsBuilder contains options to configure DeleteMany operations. @@ -193,15 +189,3 @@ func (do *DeleteManyOptionsBuilder) SetLet(let interface{}) *DeleteManyOptionsBu return do } - -// SetRawData sets the value for the RawData field. If true, it allows the CRUD operations to access timeseries -// collections on the bucket-level. This option is only valid for MongoDB versions >= 9.0. The default value is false. -func (do *DeleteManyOptionsBuilder) SetRawData(rawData bool) *DeleteManyOptionsBuilder { - do.Opts = append(do.Opts, func(opts *DeleteManyOptions) error { - opts.RawData = &rawData - - return nil - }) - - return do -} diff --git a/mongo/options/distinctoptions.go b/mongo/options/distinctoptions.go index 2ea2acf249..2de13e5774 100644 --- a/mongo/options/distinctoptions.go +++ b/mongo/options/distinctoptions.go @@ -6,6 +6,8 @@ package options +import "go.mongodb.org/mongo-driver/v2/internal/optionsutil" + // DistinctOptions represents arguments that can be used to configure a Distinct // operation. // @@ -14,7 +16,10 @@ type DistinctOptions struct { Collation *Collation Comment interface{} Hint interface{} - RawData *bool + + // Deprecated: This option is for internal use only and should not be set. It may be changed or removed in any + // release. + CustomOptions optionsutil.Options } // DistinctOptionsBuilder contains options to configure distinct operations. Each @@ -78,15 +83,3 @@ func (do *DistinctOptionsBuilder) SetHint(hint interface{}) *DistinctOptionsBuil return do } - -// SetRawData sets the value for the RawData field. If true, it allows the CRUD operations to access timeseries -// collections on the bucket-level. This option is only valid for MongoDB versions >= 9.0. The default value is false. -func (do *DistinctOptionsBuilder) SetRawData(rawData bool) *DistinctOptionsBuilder { - do.Opts = append(do.Opts, func(opts *DistinctOptions) error { - opts.RawData = &rawData - - return nil - }) - - return do -} diff --git a/mongo/options/estimatedcountoptions.go b/mongo/options/estimatedcountoptions.go index e30ea42a85..ca1d9992cc 100644 --- a/mongo/options/estimatedcountoptions.go +++ b/mongo/options/estimatedcountoptions.go @@ -6,13 +6,18 @@ package options +import "go.mongodb.org/mongo-driver/v2/internal/optionsutil" + // EstimatedDocumentCountOptions represents arguments that can be used to configure // an EstimatedDocumentCount operation. // // See corresponding setter methods for documentation. type EstimatedDocumentCountOptions struct { Comment interface{} - RawData *bool + + // Deprecated: This option is for internal use only and should not be set. It may be changed or removed in any + // release. + CustomOptions optionsutil.Options } // EstimatedDocumentCountOptionsBuilder contains options to estimate document @@ -45,15 +50,3 @@ func (eco *EstimatedDocumentCountOptionsBuilder) SetComment(comment interface{}) return eco } - -// SetRawData sets the value for the RawData field. If true, it allows the CRUD operations to access timeseries -// collections on the bucket-level. This option is only valid for MongoDB versions >= 9.0. The default value is false. -func (eco *EstimatedDocumentCountOptionsBuilder) SetRawData(rawData bool) *EstimatedDocumentCountOptionsBuilder { - eco.Opts = append(eco.Opts, func(opts *EstimatedDocumentCountOptions) error { - opts.RawData = &rawData - - return nil - }) - - return eco -} diff --git a/mongo/options/insertoptions.go b/mongo/options/insertoptions.go index de282f8628..90a5625189 100644 --- a/mongo/options/insertoptions.go +++ b/mongo/options/insertoptions.go @@ -6,6 +6,8 @@ package options +import "go.mongodb.org/mongo-driver/v2/internal/optionsutil" + // InsertOneOptions represents arguments that can be used to configure an InsertOne // operation. // @@ -13,7 +15,10 @@ package options type InsertOneOptions struct { BypassDocumentValidation *bool Comment interface{} - RawData *bool + + // Deprecated: This option is for internal use only and should not be set. It may be changed or removed in any + // release. + CustomOptions optionsutil.Options } // InsertOneOptionsBuilder represents functional options that configure an @@ -54,18 +59,6 @@ func (ioo *InsertOneOptionsBuilder) SetComment(comment interface{}) *InsertOneOp return ioo } -// SetRawData sets the value for the RawData field. If true, it allows the CRUD operations to access timeseries -// collections on the bucket-level. This option is only valid for MongoDB versions >= 9.0. The default value is false. -func (ioo *InsertOneOptionsBuilder) SetRawData(rawData bool) *InsertOneOptionsBuilder { - ioo.Opts = append(ioo.Opts, func(ioo *InsertOneOptions) error { - ioo.RawData = &rawData - - return nil - }) - - return ioo -} - // InsertManyOptions represents arguments that can be used to configure an // InsertMany operation. // @@ -74,7 +67,10 @@ type InsertManyOptions struct { BypassDocumentValidation *bool Comment interface{} Ordered *bool - RawData *bool + + // Deprecated: This option is for internal use only and should not be set. It may be changed or removed in any + // release. + CustomOptions optionsutil.Options } // InsertManyOptionsBuilder contains options to configure insert operations. @@ -135,15 +131,3 @@ func (imo *InsertManyOptionsBuilder) SetOrdered(b bool) *InsertManyOptionsBuilde return imo } - -// SetRawData sets the value for the RawData field. If true, it allows the CRUD operations to access timeseries -// collections on the bucket-level. This option is only valid for MongoDB versions >= 9.0. The default value is false. -func (imo *InsertManyOptionsBuilder) SetRawData(rawData bool) *InsertManyOptionsBuilder { - imo.Opts = append(imo.Opts, func(opts *InsertManyOptions) error { - opts.RawData = &rawData - - return nil - }) - - return imo -} diff --git a/x/mongo/driver/xoptions/options.go b/x/mongo/driver/xoptions/options.go index 68e28e7cd8..7ba259979e 100644 --- a/x/mongo/driver/xoptions/options.go +++ b/x/mongo/driver/xoptions/options.go @@ -45,3 +45,187 @@ func SetInternalClientOptions(opts *options.ClientOptions, key string, option an } return nil } + +// SetInternalAggregateOptions sets internal options for AggregateOptions. +// +// Deprecated: This function is for internal use only. It may be changed or removed in any release. +func SetInternalAggregateOptions(a *options.AggregateOptionsBuilder, key string, option any) error { + typeErrFunc := func(t string) error { + return fmt.Errorf("unexpected type for %s: %T is not %s", key, option, t) + } + switch key { + case "rawData": + b, ok := option.(bool) + if !ok { + return typeErrFunc("bool") + } + a.Opts = append(a.Opts, func(opts *options.AggregateOptions) error { + opts.CustomOptions = optionsutil.WithValue(opts.CustomOptions, key, b) + return nil + }) + default: + return fmt.Errorf("unsupported option: %s", key) + } + return nil +} + +// SetInternalCountOptions sets internal options for CountOptions. +// +// Deprecated: This function is for internal use only. It may be changed or removed in any release. +func SetInternalCountOptions(a *options.CountOptionsBuilder, key string, option any) error { + typeErrFunc := func(t string) error { + return fmt.Errorf("unexpected type for %s: %T is not %s", key, option, t) + } + switch key { + case "rawData": + b, ok := option.(bool) + if !ok { + return typeErrFunc("bool") + } + a.Opts = append(a.Opts, func(opts *options.CountOptions) error { + opts.CustomOptions = optionsutil.WithValue(opts.CustomOptions, key, b) + return nil + }) + default: + return fmt.Errorf("unsupported option: %s", key) + } + return nil +} + +// SetInternalDeleteOneOptions sets internal options for DeleteOneOptions. +// +// Deprecated: This function is for internal use only. It may be changed or removed in any release. +func SetInternalDeleteOneOptions(a *options.DeleteOneOptionsBuilder, key string, option any) error { + typeErrFunc := func(t string) error { + return fmt.Errorf("unexpected type for %s: %T is not %s", key, option, t) + } + switch key { + case "rawData": + b, ok := option.(bool) + if !ok { + return typeErrFunc("bool") + } + a.Opts = append(a.Opts, func(opts *options.DeleteOneOptions) error { + opts.CustomOptions = optionsutil.WithValue(opts.CustomOptions, key, b) + return nil + }) + default: + return fmt.Errorf("unsupported option: %s", key) + } + return nil +} + +// SetInternalDeleteManyOptions sets internal options for DeleteManyOptions. +// +// Deprecated: This function is for internal use only. It may be changed or removed in any release. +func SetInternalDeleteManyOptions(a *options.DeleteManyOptionsBuilder, key string, option any) error { + typeErrFunc := func(t string) error { + return fmt.Errorf("unexpected type for %s: %T is not %s", key, option, t) + } + switch key { + case "rawData": + b, ok := option.(bool) + if !ok { + return typeErrFunc("bool") + } + a.Opts = append(a.Opts, func(opts *options.DeleteManyOptions) error { + opts.CustomOptions = optionsutil.WithValue(opts.CustomOptions, key, b) + return nil + }) + default: + return fmt.Errorf("unsupported option: %s", key) + } + return nil +} + +// SetInternalDistinctOptions sets internal options for DistinctOptions. +// +// Deprecated: This function is for internal use only. It may be changed or removed in any release. +func SetInternalDistinctOptions(a *options.DistinctOptionsBuilder, key string, option any) error { + typeErrFunc := func(t string) error { + return fmt.Errorf("unexpected type for %s: %T is not %s", key, option, t) + } + switch key { + case "rawData": + b, ok := option.(bool) + if !ok { + return typeErrFunc("bool") + } + a.Opts = append(a.Opts, func(opts *options.DistinctOptions) error { + opts.CustomOptions = optionsutil.WithValue(opts.CustomOptions, key, b) + return nil + }) + default: + return fmt.Errorf("unsupported option: %s", key) + } + return nil +} + +// SetInternalEstimatedDocumentCountOptions sets internal options for EstimatedDocumentCountOptions. +// +// Deprecated: This function is for internal use only. It may be changed or removed in any release. +func SetInternalEstimatedDocumentCountOptions(a *options.EstimatedDocumentCountOptionsBuilder, key string, option any) error { + typeErrFunc := func(t string) error { + return fmt.Errorf("unexpected type for %s: %T is not %s", key, option, t) + } + switch key { + case "rawData": + b, ok := option.(bool) + if !ok { + return typeErrFunc("bool") + } + a.Opts = append(a.Opts, func(opts *options.EstimatedDocumentCountOptions) error { + opts.CustomOptions = optionsutil.WithValue(opts.CustomOptions, key, b) + return nil + }) + default: + return fmt.Errorf("unsupported option: %s", key) + } + return nil +} + +// SetInternalInsertManyOptions sets internal options for InsertManyOptions. +// +// Deprecated: This function is for internal use only. It may be changed or removed in any release. +func SetInternalInsertManyOptions(a *options.InsertManyOptionsBuilder, key string, option any) error { + typeErrFunc := func(t string) error { + return fmt.Errorf("unexpected type for %s: %T is not %s", key, option, t) + } + switch key { + case "rawData": + b, ok := option.(bool) + if !ok { + return typeErrFunc("bool") + } + a.Opts = append(a.Opts, func(opts *options.InsertManyOptions) error { + opts.CustomOptions = optionsutil.WithValue(opts.CustomOptions, key, b) + return nil + }) + default: + return fmt.Errorf("unsupported option: %s", key) + } + return nil +} + +// SetInternalInsertOneOptions sets internal options for InsertOneOptions. +// +// Deprecated: This function is for internal use only. It may be changed or removed in any release. +func SetInternalInsertOneOptions(a *options.InsertOneOptionsBuilder, key string, option any) error { + typeErrFunc := func(t string) error { + return fmt.Errorf("unexpected type for %s: %T is not %s", key, option, t) + } + switch key { + case "rawData": + b, ok := option.(bool) + if !ok { + return typeErrFunc("bool") + } + a.Opts = append(a.Opts, func(opts *options.InsertOneOptions) error { + opts.CustomOptions = optionsutil.WithValue(opts.CustomOptions, key, b) + return nil + }) + default: + return fmt.Errorf("unsupported option: %s", key) + } + return nil +} From 6a2e0d4aabebf5711fbd0836892f8a460b21f776 Mon Sep 17 00:00:00 2001 From: Qingyang Hu Date: Fri, 25 Jul 2025 17:27:08 -0400 Subject: [PATCH 08/13] minor updates --- x/mongo/driver/xoptions/options.go | 36 ++++++++---------------------- 1 file changed, 9 insertions(+), 27 deletions(-) diff --git a/x/mongo/driver/xoptions/options.go b/x/mongo/driver/xoptions/options.go index 7ba259979e..5f97705708 100644 --- a/x/mongo/driver/xoptions/options.go +++ b/x/mongo/driver/xoptions/options.go @@ -15,11 +15,9 @@ import ( ) // SetInternalClientOptions sets internal options for ClientOptions. -// -// Deprecated: This function is for internal use only. It may be changed or removed in any release. func SetInternalClientOptions(opts *options.ClientOptions, key string, option any) error { typeErrFunc := func(t string) error { - return fmt.Errorf("unexpected type for %s: %T is not %s", key, option, t) + return fmt.Errorf("unexpected type for %q: %T is not %s", key, option, t) } switch key { case "crypt": @@ -47,11 +45,9 @@ func SetInternalClientOptions(opts *options.ClientOptions, key string, option an } // SetInternalAggregateOptions sets internal options for AggregateOptions. -// -// Deprecated: This function is for internal use only. It may be changed or removed in any release. func SetInternalAggregateOptions(a *options.AggregateOptionsBuilder, key string, option any) error { typeErrFunc := func(t string) error { - return fmt.Errorf("unexpected type for %s: %T is not %s", key, option, t) + return fmt.Errorf("unexpected type for %q: %T is not %s", key, option, t) } switch key { case "rawData": @@ -70,11 +66,9 @@ func SetInternalAggregateOptions(a *options.AggregateOptionsBuilder, key string, } // SetInternalCountOptions sets internal options for CountOptions. -// -// Deprecated: This function is for internal use only. It may be changed or removed in any release. func SetInternalCountOptions(a *options.CountOptionsBuilder, key string, option any) error { typeErrFunc := func(t string) error { - return fmt.Errorf("unexpected type for %s: %T is not %s", key, option, t) + return fmt.Errorf("unexpected type for %q: %T is not %s", key, option, t) } switch key { case "rawData": @@ -93,11 +87,9 @@ func SetInternalCountOptions(a *options.CountOptionsBuilder, key string, option } // SetInternalDeleteOneOptions sets internal options for DeleteOneOptions. -// -// Deprecated: This function is for internal use only. It may be changed or removed in any release. func SetInternalDeleteOneOptions(a *options.DeleteOneOptionsBuilder, key string, option any) error { typeErrFunc := func(t string) error { - return fmt.Errorf("unexpected type for %s: %T is not %s", key, option, t) + return fmt.Errorf("unexpected type for %q: %T is not %s", key, option, t) } switch key { case "rawData": @@ -116,11 +108,9 @@ func SetInternalDeleteOneOptions(a *options.DeleteOneOptionsBuilder, key string, } // SetInternalDeleteManyOptions sets internal options for DeleteManyOptions. -// -// Deprecated: This function is for internal use only. It may be changed or removed in any release. func SetInternalDeleteManyOptions(a *options.DeleteManyOptionsBuilder, key string, option any) error { typeErrFunc := func(t string) error { - return fmt.Errorf("unexpected type for %s: %T is not %s", key, option, t) + return fmt.Errorf("unexpected type for %q: %T is not %s", key, option, t) } switch key { case "rawData": @@ -139,11 +129,9 @@ func SetInternalDeleteManyOptions(a *options.DeleteManyOptionsBuilder, key strin } // SetInternalDistinctOptions sets internal options for DistinctOptions. -// -// Deprecated: This function is for internal use only. It may be changed or removed in any release. func SetInternalDistinctOptions(a *options.DistinctOptionsBuilder, key string, option any) error { typeErrFunc := func(t string) error { - return fmt.Errorf("unexpected type for %s: %T is not %s", key, option, t) + return fmt.Errorf("unexpected type for %q: %T is not %s", key, option, t) } switch key { case "rawData": @@ -162,11 +150,9 @@ func SetInternalDistinctOptions(a *options.DistinctOptionsBuilder, key string, o } // SetInternalEstimatedDocumentCountOptions sets internal options for EstimatedDocumentCountOptions. -// -// Deprecated: This function is for internal use only. It may be changed or removed in any release. func SetInternalEstimatedDocumentCountOptions(a *options.EstimatedDocumentCountOptionsBuilder, key string, option any) error { typeErrFunc := func(t string) error { - return fmt.Errorf("unexpected type for %s: %T is not %s", key, option, t) + return fmt.Errorf("unexpected type for %q: %T is not %s", key, option, t) } switch key { case "rawData": @@ -185,11 +171,9 @@ func SetInternalEstimatedDocumentCountOptions(a *options.EstimatedDocumentCountO } // SetInternalInsertManyOptions sets internal options for InsertManyOptions. -// -// Deprecated: This function is for internal use only. It may be changed or removed in any release. func SetInternalInsertManyOptions(a *options.InsertManyOptionsBuilder, key string, option any) error { typeErrFunc := func(t string) error { - return fmt.Errorf("unexpected type for %s: %T is not %s", key, option, t) + return fmt.Errorf("unexpected type for %q: %T is not %s", key, option, t) } switch key { case "rawData": @@ -208,11 +192,9 @@ func SetInternalInsertManyOptions(a *options.InsertManyOptionsBuilder, key strin } // SetInternalInsertOneOptions sets internal options for InsertOneOptions. -// -// Deprecated: This function is for internal use only. It may be changed or removed in any release. func SetInternalInsertOneOptions(a *options.InsertOneOptionsBuilder, key string, option any) error { typeErrFunc := func(t string) error { - return fmt.Errorf("unexpected type for %s: %T is not %s", key, option, t) + return fmt.Errorf("unexpected type for %q: %T is not %s", key, option, t) } switch key { case "rawData": From 53f022603f98aba88a4d6e80c8688cad6c0a6eb8 Mon Sep 17 00:00:00 2001 From: Qingyang Hu Date: Thu, 31 Jul 2025 15:55:55 -0400 Subject: [PATCH 09/13] Rename custom options fields --- mongo/collection.go | 26 ++++++++++++------------- mongo/options/aggregateoptions.go | 2 +- mongo/options/countoptions.go | 2 +- mongo/options/deleteoptions.go | 4 ++-- mongo/options/distinctoptions.go | 2 +- mongo/options/estimatedcountoptions.go | 2 +- mongo/options/insertoptions.go | 4 ++-- x/mongo/driver/xoptions/options.go | 16 +++++++-------- x/mongo/driver/xoptions/options_test.go | 4 ++-- 9 files changed, 31 insertions(+), 31 deletions(-) diff --git a/mongo/collection.go b/mongo/collection.go index 9017b831f8..000b5b27b3 100644 --- a/mongo/collection.go +++ b/mongo/collection.go @@ -325,7 +325,7 @@ func (coll *Collection) insert( if args.Ordered != nil { op = op.Ordered(*args.Ordered) } - if rawDataOpt := optionsutil.Value(args.CustomOptions, "rawData"); rawDataOpt != nil { + if rawDataOpt := optionsutil.Value(args.Internal, "rawData"); rawDataOpt != nil { if rawData, ok := rawDataOpt.(bool); ok { op = op.RawData(rawData) } @@ -381,9 +381,9 @@ func (coll *Collection) InsertOne(ctx context.Context, document interface{}, if args.Comment != nil { imOpts.SetComment(args.Comment) } - if rawDataOpt := optionsutil.Value(args.CustomOptions, "rawData"); rawDataOpt != nil { + if rawDataOpt := optionsutil.Value(args.Internal, "rawData"); rawDataOpt != nil { imOpts.Opts = append(imOpts.Opts, func(opts *options.InsertManyOptions) error { - optionsutil.WithValue(opts.CustomOptions, "rawData", rawDataOpt) + optionsutil.WithValue(opts.Internal, "rawData", rawDataOpt) return nil }) @@ -547,7 +547,7 @@ func (coll *Collection) delete( } op = op.Let(let) } - if rawDataOpt := optionsutil.Value(args.CustomOptions, "rawData"); rawDataOpt != nil { + if rawDataOpt := optionsutil.Value(args.Internal, "rawData"); rawDataOpt != nil { if rawData, ok := rawDataOpt.(bool); ok { op = op.RawData(rawData) } @@ -589,11 +589,11 @@ func (coll *Collection) DeleteOne( return nil, fmt.Errorf("failed to construct options from builder: %w", err) } deleteOptions := &options.DeleteManyOptions{ - Collation: args.Collation, - Comment: args.Comment, - Hint: args.Hint, - Let: args.Let, - CustomOptions: args.CustomOptions, + Collation: args.Collation, + Comment: args.Comment, + Hint: args.Hint, + Let: args.Let, + Internal: args.Internal, } return coll.delete(ctx, filter, true, rrOne, deleteOptions) @@ -1055,7 +1055,7 @@ func aggregate(a aggregateParams, opts ...options.Lister[options.AggregateOption } op.CustomOptions(customOptions) } - if rawDataOpt := optionsutil.Value(args.CustomOptions, "rawData"); rawDataOpt != nil { + if rawDataOpt := optionsutil.Value(args.Internal, "rawData"); rawDataOpt != nil { if rawData, ok := rawDataOpt.(bool); ok { op = op.RawData(rawData) } @@ -1148,7 +1148,7 @@ func (coll *Collection) CountDocuments(ctx context.Context, filter interface{}, } op.Hint(hintVal) } - if rawDataOpt := optionsutil.Value(args.CustomOptions, "rawData"); rawDataOpt != nil { + if rawDataOpt := optionsutil.Value(args.Internal, "rawData"); rawDataOpt != nil { if rawData, ok := rawDataOpt.(bool); ok { op = op.RawData(rawData) } @@ -1234,7 +1234,7 @@ func (coll *Collection) EstimatedDocumentCount( } op = op.Comment(comment) } - if rawDataOpt := optionsutil.Value(args.CustomOptions, "rawData"); rawDataOpt != nil { + if rawDataOpt := optionsutil.Value(args.Internal, "rawData"); rawDataOpt != nil { if rawData, ok := rawDataOpt.(bool); ok { op = op.RawData(rawData) } @@ -1328,7 +1328,7 @@ func (coll *Collection) Distinct( } op.Hint(hint) } - if rawDataOpt := optionsutil.Value(args.CustomOptions, "rawData"); rawDataOpt != nil { + if rawDataOpt := optionsutil.Value(args.Internal, "rawData"); rawDataOpt != nil { if rawData, ok := rawDataOpt.(bool); ok { op = op.RawData(rawData) } diff --git a/mongo/options/aggregateoptions.go b/mongo/options/aggregateoptions.go index 432358dfce..070e126583 100644 --- a/mongo/options/aggregateoptions.go +++ b/mongo/options/aggregateoptions.go @@ -30,7 +30,7 @@ type AggregateOptions struct { // Deprecated: This option is for internal use only and should not be set. It may be changed or removed in any // release. - CustomOptions optionsutil.Options + Internal optionsutil.Options } // AggregateOptionsBuilder contains options to configure aggregate operations. diff --git a/mongo/options/countoptions.go b/mongo/options/countoptions.go index bc226fdc40..3e689d9a54 100644 --- a/mongo/options/countoptions.go +++ b/mongo/options/countoptions.go @@ -21,7 +21,7 @@ type CountOptions struct { // Deprecated: This option is for internal use only and should not be set. It may be changed or removed in any // release. - CustomOptions optionsutil.Options + Internal optionsutil.Options } // CountOptionsBuilder contains options to configure count operations. Each diff --git a/mongo/options/deleteoptions.go b/mongo/options/deleteoptions.go index e19ecc5a92..27a77b4581 100644 --- a/mongo/options/deleteoptions.go +++ b/mongo/options/deleteoptions.go @@ -20,7 +20,7 @@ type DeleteOneOptions struct { // Deprecated: This option is for internal use only and should not be set. It may be changed or removed in any // release. - CustomOptions optionsutil.Options + Internal optionsutil.Options } // DeleteOneOptionsBuilder contains options to configure DeleteOne operations. Each @@ -111,7 +111,7 @@ type DeleteManyOptions struct { // Deprecated: This option is for internal use only and should not be set. It may be changed or removed in any // release. - CustomOptions optionsutil.Options + Internal optionsutil.Options } // DeleteManyOptionsBuilder contains options to configure DeleteMany operations. diff --git a/mongo/options/distinctoptions.go b/mongo/options/distinctoptions.go index 2de13e5774..346432c07a 100644 --- a/mongo/options/distinctoptions.go +++ b/mongo/options/distinctoptions.go @@ -19,7 +19,7 @@ type DistinctOptions struct { // Deprecated: This option is for internal use only and should not be set. It may be changed or removed in any // release. - CustomOptions optionsutil.Options + Internal optionsutil.Options } // DistinctOptionsBuilder contains options to configure distinct operations. Each diff --git a/mongo/options/estimatedcountoptions.go b/mongo/options/estimatedcountoptions.go index ca1d9992cc..ccddd98c59 100644 --- a/mongo/options/estimatedcountoptions.go +++ b/mongo/options/estimatedcountoptions.go @@ -17,7 +17,7 @@ type EstimatedDocumentCountOptions struct { // Deprecated: This option is for internal use only and should not be set. It may be changed or removed in any // release. - CustomOptions optionsutil.Options + Internal optionsutil.Options } // EstimatedDocumentCountOptionsBuilder contains options to estimate document diff --git a/mongo/options/insertoptions.go b/mongo/options/insertoptions.go index 90a5625189..36f18a987d 100644 --- a/mongo/options/insertoptions.go +++ b/mongo/options/insertoptions.go @@ -18,7 +18,7 @@ type InsertOneOptions struct { // Deprecated: This option is for internal use only and should not be set. It may be changed or removed in any // release. - CustomOptions optionsutil.Options + Internal optionsutil.Options } // InsertOneOptionsBuilder represents functional options that configure an @@ -70,7 +70,7 @@ type InsertManyOptions struct { // Deprecated: This option is for internal use only and should not be set. It may be changed or removed in any // release. - CustomOptions optionsutil.Options + Internal optionsutil.Options } // InsertManyOptionsBuilder contains options to configure insert operations. diff --git a/x/mongo/driver/xoptions/options.go b/x/mongo/driver/xoptions/options.go index 5f97705708..97c47e233f 100644 --- a/x/mongo/driver/xoptions/options.go +++ b/x/mongo/driver/xoptions/options.go @@ -56,7 +56,7 @@ func SetInternalAggregateOptions(a *options.AggregateOptionsBuilder, key string, return typeErrFunc("bool") } a.Opts = append(a.Opts, func(opts *options.AggregateOptions) error { - opts.CustomOptions = optionsutil.WithValue(opts.CustomOptions, key, b) + opts.Internal = optionsutil.WithValue(opts.Internal, key, b) return nil }) default: @@ -77,7 +77,7 @@ func SetInternalCountOptions(a *options.CountOptionsBuilder, key string, option return typeErrFunc("bool") } a.Opts = append(a.Opts, func(opts *options.CountOptions) error { - opts.CustomOptions = optionsutil.WithValue(opts.CustomOptions, key, b) + opts.Internal = optionsutil.WithValue(opts.Internal, key, b) return nil }) default: @@ -98,7 +98,7 @@ func SetInternalDeleteOneOptions(a *options.DeleteOneOptionsBuilder, key string, return typeErrFunc("bool") } a.Opts = append(a.Opts, func(opts *options.DeleteOneOptions) error { - opts.CustomOptions = optionsutil.WithValue(opts.CustomOptions, key, b) + opts.Internal = optionsutil.WithValue(opts.Internal, key, b) return nil }) default: @@ -119,7 +119,7 @@ func SetInternalDeleteManyOptions(a *options.DeleteManyOptionsBuilder, key strin return typeErrFunc("bool") } a.Opts = append(a.Opts, func(opts *options.DeleteManyOptions) error { - opts.CustomOptions = optionsutil.WithValue(opts.CustomOptions, key, b) + opts.Internal = optionsutil.WithValue(opts.Internal, key, b) return nil }) default: @@ -140,7 +140,7 @@ func SetInternalDistinctOptions(a *options.DistinctOptionsBuilder, key string, o return typeErrFunc("bool") } a.Opts = append(a.Opts, func(opts *options.DistinctOptions) error { - opts.CustomOptions = optionsutil.WithValue(opts.CustomOptions, key, b) + opts.Internal = optionsutil.WithValue(opts.Internal, key, b) return nil }) default: @@ -161,7 +161,7 @@ func SetInternalEstimatedDocumentCountOptions(a *options.EstimatedDocumentCountO return typeErrFunc("bool") } a.Opts = append(a.Opts, func(opts *options.EstimatedDocumentCountOptions) error { - opts.CustomOptions = optionsutil.WithValue(opts.CustomOptions, key, b) + opts.Internal = optionsutil.WithValue(opts.Internal, key, b) return nil }) default: @@ -182,7 +182,7 @@ func SetInternalInsertManyOptions(a *options.InsertManyOptionsBuilder, key strin return typeErrFunc("bool") } a.Opts = append(a.Opts, func(opts *options.InsertManyOptions) error { - opts.CustomOptions = optionsutil.WithValue(opts.CustomOptions, key, b) + opts.Internal = optionsutil.WithValue(opts.Internal, key, b) return nil }) default: @@ -203,7 +203,7 @@ func SetInternalInsertOneOptions(a *options.InsertOneOptionsBuilder, key string, return typeErrFunc("bool") } a.Opts = append(a.Opts, func(opts *options.InsertOneOptions) error { - opts.CustomOptions = optionsutil.WithValue(opts.CustomOptions, key, b) + opts.Internal = optionsutil.WithValue(opts.Internal, key, b) return nil }) default: diff --git a/x/mongo/driver/xoptions/options_test.go b/x/mongo/driver/xoptions/options_test.go index 284fe914a1..e56de6bdcc 100644 --- a/x/mongo/driver/xoptions/options_test.go +++ b/x/mongo/driver/xoptions/options_test.go @@ -58,7 +58,7 @@ func TestSetInternalClientOptions(t *testing.T) { opts := options.Client() err := SetInternalClientOptions(opts, "crypt", &drivertest.MockDeployment{}) - require.EqualError(t, err, "unexpected type for crypt: *drivertest.MockDeployment is not driver.Crypt") + require.EqualError(t, err, "unexpected type for \"crypt\": *drivertest.MockDeployment is not driver.Crypt") }) t.Run("set deployment", func(t *testing.T) { @@ -76,7 +76,7 @@ func TestSetInternalClientOptions(t *testing.T) { opts := options.Client() err := SetInternalClientOptions(opts, "deployment", driver.NewCrypt(&driver.CryptOptions{})) - require.EqualError(t, err, "unexpected type for deployment: *driver.crypt is not driver.Deployment") + require.EqualError(t, err, "unexpected type for \"deployment\": *driver.crypt is not driver.Deployment") }) t.Run("set unsupported option", func(t *testing.T) { From 503f3d34c7de6cd16774324e1675890735657d4d Mon Sep 17 00:00:00 2001 From: Qingyang Hu Date: Tue, 8 Jul 2025 09:30:48 -0400 Subject: [PATCH 10/13] add find/findAndModify --- .../unified/collection_operation_execution.go | 20 +++ mongo/collection.go | 21 +++ mongo/options/findoptions.go | 22 ++++ x/mongo/driver/operation/find.go | 15 +++ x/mongo/driver/operation/find_and_modify.go | 15 +++ x/mongo/driver/xoptions/options.go | 123 ++++++++++++++++-- 6 files changed, 207 insertions(+), 9 deletions(-) diff --git a/internal/integration/unified/collection_operation_execution.go b/internal/integration/unified/collection_operation_execution.go index e58a869eed..7bfb3fdef6 100644 --- a/internal/integration/unified/collection_operation_execution.go +++ b/internal/integration/unified/collection_operation_execution.go @@ -873,6 +873,11 @@ func executeFindOneAndDelete(ctx context.Context, operation *operation) (*operat opts.SetSort(val.Document()) case "let": opts.SetLet(val.Document()) + case "rawData": + err = xoptions.SetInternalFindOneAndDeleteOptions(opts, key, val.Boolean()) + if err != nil { + return nil, err + } default: return nil, fmt.Errorf("unrecognized findOneAndDelete option %q", key) } @@ -955,6 +960,11 @@ func executeFindOneAndReplace(ctx context.Context, operation *operation) (*opera opts.SetSort(val.Document()) case "upsert": opts.SetUpsert(val.Boolean()) + case "rawData": + err = xoptions.SetInternalFindOneAndReplaceOptions(opts, key, val.Boolean()) + if err != nil { + return nil, err + } default: return nil, fmt.Errorf("unrecognized findOneAndReplace option %q", key) } @@ -1047,6 +1057,11 @@ func executeFindOneAndUpdate(ctx context.Context, operation *operation) (*operat } case "upsert": opts.SetUpsert(val.Boolean()) + case "rawData": + err = xoptions.SetInternalFindOneAndUpdateOptions(opts, key, val.Boolean()) + if err != nil { + return nil, err + } default: return nil, fmt.Errorf("unrecognized findOneAndUpdate option %q", key) } @@ -1541,6 +1556,11 @@ func createFindCursor(ctx context.Context, operation *operation) (*cursorResult, case "maxAwaitTimeMS": maxAwaitTimeMS := time.Duration(val.Int32()) * time.Millisecond opts.SetMaxAwaitTime(maxAwaitTimeMS) + case "rawData": + err = xoptions.SetInternalFindOptions(opts, key, val.Boolean()) + if err != nil { + return nil, err + } default: return nil, fmt.Errorf("unrecognized find option %q", key) } diff --git a/mongo/collection.go b/mongo/collection.go index 000b5b27b3..7bcb5cf4da 100644 --- a/mongo/collection.go +++ b/mongo/collection.go @@ -1536,6 +1536,11 @@ func (coll *Collection) find( } op.Sort(sort) } + if rawDataOpt := optionsutil.Value(args.Internal, "rawData"); rawDataOpt != nil { + if rawData, ok := rawDataOpt.(bool); ok { + op = op.RawData(rawData) + } + } retry := driver.RetryNone if coll.client.retryReads { retry = driver.RetryOncePerCommand @@ -1569,6 +1574,7 @@ func newFindArgsFromFindOneArgs(args *options.FindOneOptions) *options.FindOptio v.ShowRecordID = args.ShowRecordID v.Skip = args.Skip v.Sort = args.Sort + v.Internal = args.Internal } return v } @@ -1731,6 +1737,11 @@ func (coll *Collection) FindOneAndDelete( } op = op.Let(let) } + if rawDataOpt := optionsutil.Value(args.Internal, "rawData"); rawDataOpt != nil { + if rawData, ok := rawDataOpt.(bool); ok { + op = op.RawData(rawData) + } + } return coll.findAndModify(ctx, op) } @@ -1828,6 +1839,11 @@ func (coll *Collection) FindOneAndReplace( } op = op.Let(let) } + if rawDataOpt := optionsutil.Value(args.Internal, "rawData"); rawDataOpt != nil { + if rawData, ok := rawDataOpt.(bool); ok { + op = op.RawData(rawData) + } + } return coll.findAndModify(ctx, op) } @@ -1937,6 +1953,11 @@ func (coll *Collection) FindOneAndUpdate( } op = op.Let(let) } + if rawDataOpt := optionsutil.Value(args.Internal, "rawData"); rawDataOpt != nil { + if rawData, ok := rawDataOpt.(bool); ok { + op = op.RawData(rawData) + } + } return coll.findAndModify(ctx, op) } diff --git a/mongo/options/findoptions.go b/mongo/options/findoptions.go index ea627900ea..dd66eabc7a 100644 --- a/mongo/options/findoptions.go +++ b/mongo/options/findoptions.go @@ -8,6 +8,8 @@ package options import ( "time" + + "go.mongodb.org/mongo-driver/v2/internal/optionsutil" ) // FindOptions represents arguments that can be used to configure a Find @@ -35,6 +37,10 @@ type FindOptions struct { Let interface{} Limit *int64 NoCursorTimeout *bool + + // Deprecated: This option is for internal use only and should not be set. It may be changed or removed in any + // release. + Internal optionsutil.Options } // FindOptionsBuilder represents functional options that configure an Findopts. @@ -285,6 +291,10 @@ type FindOneOptions struct { ShowRecordID *bool Skip *int64 Sort interface{} + + // Deprecated: This option is for internal use only and should not be set. It may be changed or removed in any + // release. + Internal optionsutil.Options } // FindOneOptionsBuilder represents functional options that configure an @@ -450,6 +460,10 @@ type FindOneAndReplaceOptions struct { Upsert *bool Hint interface{} Let interface{} + + // Deprecated: This option is for internal use only and should not be set. It may be changed or removed in any + // release. + Internal optionsutil.Options } // FindOneAndReplaceOptionsBuilder contains options to perform a findAndModify @@ -611,6 +625,10 @@ type FindOneAndUpdateOptions struct { Upsert *bool Hint interface{} Let interface{} + + // Deprecated: This option is for internal use only and should not be set. It may be changed or removed in any + // release. + Internal optionsutil.Options } // FindOneAndUpdateOptionsBuilder contains options to configure a @@ -782,6 +800,10 @@ type FindOneAndDeleteOptions struct { Sort interface{} Hint interface{} Let interface{} + + // Deprecated: This option is for internal use only and should not be set. It may be changed or removed in any + // release. + Internal optionsutil.Options } // FindOneAndDeleteOptionsBuilder contains options to configure delete diff --git a/x/mongo/driver/operation/find.go b/x/mongo/driver/operation/find.go index b607cb14d7..615e240850 100644 --- a/x/mongo/driver/operation/find.go +++ b/x/mongo/driver/operation/find.go @@ -61,6 +61,7 @@ type Find struct { result driver.CursorResponse serverAPI *driver.ServerAPIOptions timeout *time.Duration + rawData *bool logger *logger.Logger omitMaxTimeMS bool } @@ -191,6 +192,10 @@ func (f *Find) command(dst []byte, desc description.SelectedServer) ([]byte, err if f.tailable != nil { dst = bsoncore.AppendBooleanElement(dst, "tailable", *f.tailable) } + // Set rawData for 8.2+ servers. + if f.rawData != nil && desc.WireVersion != nil && driverutil.VersionRangeIncludes(*desc.WireVersion, 27) { + dst = bsoncore.AppendBooleanElement(dst, "rawData", *f.rawData) + } return dst, nil } @@ -565,6 +570,16 @@ func (f *Find) Authenticator(authenticator driver.Authenticator) *Find { return f } +// RawData sets the rawData to access timeseries data in the compressed format. +func (f *Find) RawData(rawData bool) *Find { + if f == nil { + f = new(Find) + } + + f.rawData = &rawData + return f +} + // OmitMaxTimeMS omits the automatically-calculated "maxTimeMS" from the // command. func (f *Find) OmitMaxTimeMS(omit bool) *Find { diff --git a/x/mongo/driver/operation/find_and_modify.go b/x/mongo/driver/operation/find_and_modify.go index 505c56b06c..2e524e78db 100644 --- a/x/mongo/driver/operation/find_and_modify.go +++ b/x/mongo/driver/operation/find_and_modify.go @@ -50,6 +50,7 @@ type FindAndModify struct { serverAPI *driver.ServerAPIOptions let bsoncore.Document timeout *time.Duration + rawData *bool result FindAndModifyResult } @@ -211,6 +212,10 @@ func (fam *FindAndModify) command(dst []byte, desc description.SelectedServer) ( if fam.let != nil { dst = bsoncore.AppendDocumentElement(dst, "let", fam.let) } + // Set rawData for 8.2+ servers. + if fam.rawData != nil && desc.WireVersion != nil && driverutil.VersionRangeIncludes(*desc.WireVersion, 27) { + dst = bsoncore.AppendBooleanElement(dst, "rawData", *fam.rawData) + } return dst, nil } @@ -476,3 +481,13 @@ func (fam *FindAndModify) Authenticator(authenticator driver.Authenticator) *Fin fam.authenticator = authenticator return fam } + +// RawData sets the rawData to access timeseries data in the compressed format. +func (fam *FindAndModify) RawData(rawData bool) *FindAndModify { + if fam == nil { + fam = new(FindAndModify) + } + + fam.rawData = &rawData + return fam +} diff --git a/x/mongo/driver/xoptions/options.go b/x/mongo/driver/xoptions/options.go index 97c47e233f..2a3af03780 100644 --- a/x/mongo/driver/xoptions/options.go +++ b/x/mongo/driver/xoptions/options.go @@ -39,7 +39,7 @@ func SetInternalClientOptions(opts *options.ClientOptions, key string, option an } opts.Custom = optionsutil.WithValue(opts.Custom, key, b) default: - return fmt.Errorf("unsupported option: %s", key) + return fmt.Errorf("unsupported option: %q", key) } return nil } @@ -60,7 +60,7 @@ func SetInternalAggregateOptions(a *options.AggregateOptionsBuilder, key string, return nil }) default: - return fmt.Errorf("unsupported option: %s", key) + return fmt.Errorf("unsupported option: %q", key) } return nil } @@ -81,7 +81,7 @@ func SetInternalCountOptions(a *options.CountOptionsBuilder, key string, option return nil }) default: - return fmt.Errorf("unsupported option: %s", key) + return fmt.Errorf("unsupported option: %q", key) } return nil } @@ -102,7 +102,7 @@ func SetInternalDeleteOneOptions(a *options.DeleteOneOptionsBuilder, key string, return nil }) default: - return fmt.Errorf("unsupported option: %s", key) + return fmt.Errorf("unsupported option: %q", key) } return nil } @@ -123,7 +123,7 @@ func SetInternalDeleteManyOptions(a *options.DeleteManyOptionsBuilder, key strin return nil }) default: - return fmt.Errorf("unsupported option: %s", key) + return fmt.Errorf("unsupported option: %q", key) } return nil } @@ -144,7 +144,7 @@ func SetInternalDistinctOptions(a *options.DistinctOptionsBuilder, key string, o return nil }) default: - return fmt.Errorf("unsupported option: %s", key) + return fmt.Errorf("unsupported option: %q", key) } return nil } @@ -165,7 +165,112 @@ func SetInternalEstimatedDocumentCountOptions(a *options.EstimatedDocumentCountO return nil }) default: - return fmt.Errorf("unsupported option: %s", key) + return fmt.Errorf("unsupported option: %q", key) + } + return nil +} + +// SetInternalFindOptions sets internal options for FindOptions. +func SetInternalFindOptions(a *options.FindOptionsBuilder, key string, option any) error { + typeErrFunc := func(t string) error { + return fmt.Errorf("unexpected type for %q: %T is not %s", key, option, t) + } + switch key { + case "rawData": + b, ok := option.(bool) + if !ok { + return typeErrFunc("bool") + } + a.Opts = append(a.Opts, func(opts *options.FindOptions) error { + opts.Internal = optionsutil.WithValue(opts.Internal, key, b) + return nil + }) + default: + return fmt.Errorf("unsupported option: %q", key) + } + return nil +} + +// SetInternalFindOneOptions sets internal options for FindOneOptions. +func SetInternalFindOneOptions(a *options.FindOneOptionsBuilder, key string, option any) error { + typeErrFunc := func(t string) error { + return fmt.Errorf("unexpected type for %q: %T is not %s", key, option, t) + } + switch key { + case "rawData": + b, ok := option.(bool) + if !ok { + return typeErrFunc("bool") + } + a.Opts = append(a.Opts, func(opts *options.FindOneOptions) error { + opts.Internal = optionsutil.WithValue(opts.Internal, key, b) + return nil + }) + default: + return fmt.Errorf("unsupported option: %q", key) + } + return nil +} + +// SetInternalFindOneAndDeleteOptions sets internal options for FindOneAndDeleteOptions. +func SetInternalFindOneAndDeleteOptions(a *options.FindOneAndDeleteOptionsBuilder, key string, option any) error { + typeErrFunc := func(t string) error { + return fmt.Errorf("unexpected type for %q: %T is not %s", key, option, t) + } + switch key { + case "rawData": + b, ok := option.(bool) + if !ok { + return typeErrFunc("bool") + } + a.Opts = append(a.Opts, func(opts *options.FindOneAndDeleteOptions) error { + opts.Internal = optionsutil.WithValue(opts.Internal, key, b) + return nil + }) + default: + return fmt.Errorf("unsupported option: %q", key) + } + return nil +} + +// SetInternalFindOneAndReplaceOptions sets internal options for FindOneAndReplaceOptions. +func SetInternalFindOneAndReplaceOptions(a *options.FindOneAndReplaceOptionsBuilder, key string, option any) error { + typeErrFunc := func(t string) error { + return fmt.Errorf("unexpected type for %q: %T is not %s", key, option, t) + } + switch key { + case "rawData": + b, ok := option.(bool) + if !ok { + return typeErrFunc("bool") + } + a.Opts = append(a.Opts, func(opts *options.FindOneAndReplaceOptions) error { + opts.Internal = optionsutil.WithValue(opts.Internal, key, b) + return nil + }) + default: + return fmt.Errorf("unsupported option: %q", key) + } + return nil +} + +// SetInternalFindOneAndUpdateOptions sets internal options for FindOneAndUpdateOptions. +func SetInternalFindOneAndUpdateOptions(a *options.FindOneAndUpdateOptionsBuilder, key string, option any) error { + typeErrFunc := func(t string) error { + return fmt.Errorf("unexpected type for %q: %T is not %s", key, option, t) + } + switch key { + case "rawData": + b, ok := option.(bool) + if !ok { + return typeErrFunc("bool") + } + a.Opts = append(a.Opts, func(opts *options.FindOneAndUpdateOptions) error { + opts.Internal = optionsutil.WithValue(opts.Internal, key, b) + return nil + }) + default: + return fmt.Errorf("unsupported option: %q", key) } return nil } @@ -186,7 +291,7 @@ func SetInternalInsertManyOptions(a *options.InsertManyOptionsBuilder, key strin return nil }) default: - return fmt.Errorf("unsupported option: %s", key) + return fmt.Errorf("unsupported option: %q", key) } return nil } @@ -207,7 +312,7 @@ func SetInternalInsertOneOptions(a *options.InsertOneOptionsBuilder, key string, return nil }) default: - return fmt.Errorf("unsupported option: %s", key) + return fmt.Errorf("unsupported option: %q", key) } return nil } From fdef4af3ecae61c3b74e301cc747f6e533e92b0a Mon Sep 17 00:00:00 2001 From: Qingyang Hu Date: Tue, 8 Jul 2025 09:47:21 -0400 Subject: [PATCH 11/13] add update/replace --- .../unified/collection_operation_execution.go | 5 ++ internal/integration/unified/crud_helpers.go | 11 ++++ mongo/collection.go | 7 +++ mongo/options/replaceoptions.go | 6 ++ mongo/options/updateoptions.go | 10 +++ x/mongo/driver/operation/update.go | 15 +++++ x/mongo/driver/xoptions/options.go | 63 +++++++++++++++++++ 7 files changed, 117 insertions(+) diff --git a/internal/integration/unified/collection_operation_execution.go b/internal/integration/unified/collection_operation_execution.go index 7bfb3fdef6..41e74bf5c6 100644 --- a/internal/integration/unified/collection_operation_execution.go +++ b/internal/integration/unified/collection_operation_execution.go @@ -1358,6 +1358,11 @@ func executeReplaceOne(ctx context.Context, operation *operation) (*operationRes opts.SetUpsert(val.Boolean()) case "let": opts.SetLet(val.Document()) + case "rawData": + err = xoptions.SetInternalReplaceOptions(opts, key, val.Boolean()) + if err != nil { + return nil, err + } default: return nil, fmt.Errorf("unrecognized replaceOne option %q", key) } diff --git a/internal/integration/unified/crud_helpers.go b/internal/integration/unified/crud_helpers.go index 34de29d683..98719224c4 100644 --- a/internal/integration/unified/crud_helpers.go +++ b/internal/integration/unified/crud_helpers.go @@ -12,6 +12,7 @@ import ( "go.mongodb.org/mongo-driver/v2/bson" "go.mongodb.org/mongo-driver/v2/internal/bsonutil" "go.mongodb.org/mongo-driver/v2/mongo/options" + "go.mongodb.org/mongo-driver/v2/x/mongo/driver/xoptions" ) // newMissingArgumentError creates an error to convey that an argument that is required to run an operation is missing @@ -67,6 +68,11 @@ func createUpdateManyArguments(args bson.Raw) (*updateArguments, *options.Update } case "upsert": opts.SetUpsert(val.Boolean()) + case "rawData": + err := xoptions.SetInternalUpdateManyOptions(opts, key, val.Boolean()) + if err != nil { + return nil, nil, err + } default: return nil, nil, fmt.Errorf("unrecognized update option %q", key) } @@ -125,6 +131,11 @@ func createUpdateOneArguments(args bson.Raw) (*updateArguments, *options.UpdateO opts.SetUpsert(val.Boolean()) case "sort": opts.SetSort(val.Document()) + case "rawData": + err := xoptions.SetInternalUpdateOneOptions(opts, key, val.Boolean()) + if err != nil { + return nil, nil, err + } default: return nil, nil, fmt.Errorf("unrecognized update option %q", key) } diff --git a/mongo/collection.go b/mongo/collection.go index 7bcb5cf4da..d4c696d0d0 100644 --- a/mongo/collection.go +++ b/mongo/collection.go @@ -700,6 +700,11 @@ func (coll *Collection) updateOrReplace( } op = op.Comment(comment) } + if rawDataOpt := optionsutil.Value(args.Internal, "rawData"); rawDataOpt != nil { + if rawData, ok := rawDataOpt.(bool); ok { + op = op.RawData(rawData) + } + } retry := driver.RetryNone // retryable writes are only enabled updateOne/replaceOne operations if !multi && coll.client.retryWrites { @@ -794,6 +799,7 @@ func (coll *Collection) UpdateOne( Hint: args.Hint, Upsert: args.Upsert, Let: args.Let, + Internal: args.Internal, } return coll.updateOrReplace(ctx, f, update, false, rrOne, true, args.Sort, updateOptions) @@ -884,6 +890,7 @@ func (coll *Collection) ReplaceOne( Hint: args.Hint, Let: args.Let, Comment: args.Comment, + Internal: args.Internal, } return coll.updateOrReplace(ctx, f, r, false, rrOne, false, args.Sort, updateOptions) diff --git a/mongo/options/replaceoptions.go b/mongo/options/replaceoptions.go index 32caceff16..8b6c7e166d 100644 --- a/mongo/options/replaceoptions.go +++ b/mongo/options/replaceoptions.go @@ -6,6 +6,8 @@ package options +import "go.mongodb.org/mongo-driver/v2/internal/optionsutil" + // ReplaceOptions represents arguments that can be used to configure a ReplaceOne // operation. // @@ -18,6 +20,10 @@ type ReplaceOptions struct { Upsert *bool Let interface{} Sort interface{} + + // Deprecated: This option is for internal use only and should not be set. It may be changed or removed in any + // release. + Internal optionsutil.Options } // ReplaceOptionsBuilder contains options to configure replace operations. Each diff --git a/mongo/options/updateoptions.go b/mongo/options/updateoptions.go index f7b22e6f84..2a9f4f48d0 100644 --- a/mongo/options/updateoptions.go +++ b/mongo/options/updateoptions.go @@ -6,6 +6,8 @@ package options +import "go.mongodb.org/mongo-driver/v2/internal/optionsutil" + // UpdateOneOptions represents arguments that can be used to configure UpdateOne // operations. // @@ -19,6 +21,10 @@ type UpdateOneOptions struct { Upsert *bool Let interface{} Sort interface{} + + // Deprecated: This option is for internal use only and should not be set. It may be changed or removed in any + // release. + Internal optionsutil.Options } // UpdateOneOptionsBuilder contains options to configure UpdateOne operations. @@ -164,6 +170,10 @@ type UpdateManyOptions struct { Hint interface{} Upsert *bool Let interface{} + + // Deprecated: This option is for internal use only and should not be set. It may be changed or removed in any + // release. + Internal optionsutil.Options } // UpdateManyOptionsBuilder contains options to configure UpdateMany operations. diff --git a/x/mongo/driver/operation/update.go b/x/mongo/driver/operation/update.go index 722c06ef94..9b06deef33 100644 --- a/x/mongo/driver/operation/update.go +++ b/x/mongo/driver/operation/update.go @@ -46,6 +46,7 @@ type Update struct { serverAPI *driver.ServerAPIOptions let bsoncore.Document timeout *time.Duration + rawData *bool logger *logger.Logger } @@ -203,6 +204,10 @@ func (u *Update) command(dst []byte, desc description.SelectedServer) ([]byte, e if u.let != nil { dst = bsoncore.AppendDocumentElement(dst, "let", u.let) } + // Set rawData for 8.2+ servers. + if u.rawData != nil && desc.WireVersion != nil && driverutil.VersionRangeIncludes(*desc.WireVersion, 27) { + dst = bsoncore.AppendBooleanElement(dst, "rawData", *u.rawData) + } return dst, nil } @@ -422,3 +427,13 @@ func (u *Update) Authenticator(authenticator driver.Authenticator) *Update { u.authenticator = authenticator return u } + +// RawData sets the rawData to access timeseries data in the compressed format. +func (u *Update) RawData(rawData bool) *Update { + if u == nil { + u = new(Update) + } + + u.rawData = &rawData + return u +} diff --git a/x/mongo/driver/xoptions/options.go b/x/mongo/driver/xoptions/options.go index 2a3af03780..91ebf7bb86 100644 --- a/x/mongo/driver/xoptions/options.go +++ b/x/mongo/driver/xoptions/options.go @@ -316,3 +316,66 @@ func SetInternalInsertOneOptions(a *options.InsertOneOptionsBuilder, key string, } return nil } + +// SetInternalReplaceOptions sets internal options for ReplaceOptions. +func SetInternalReplaceOptions(a *options.ReplaceOptionsBuilder, key string, option any) error { + typeErrFunc := func(t string) error { + return fmt.Errorf("unexpected type for %q: %T is not %s", key, option, t) + } + switch key { + case "rawData": + b, ok := option.(bool) + if !ok { + return typeErrFunc("bool") + } + a.Opts = append(a.Opts, func(opts *options.ReplaceOptions) error { + opts.Internal = optionsutil.WithValue(opts.Internal, key, b) + return nil + }) + default: + return fmt.Errorf("unsupported option: %q", key) + } + return nil +} + +// SetInternalUpdateManyOptions sets internal options for UpdateManyOptions. +func SetInternalUpdateManyOptions(a *options.UpdateManyOptionsBuilder, key string, option any) error { + typeErrFunc := func(t string) error { + return fmt.Errorf("unexpected type for %q: %T is not %s", key, option, t) + } + switch key { + case "rawData": + b, ok := option.(bool) + if !ok { + return typeErrFunc("bool") + } + a.Opts = append(a.Opts, func(opts *options.UpdateManyOptions) error { + opts.Internal = optionsutil.WithValue(opts.Internal, key, b) + return nil + }) + default: + return fmt.Errorf("unsupported option: %q", key) + } + return nil +} + +// SetInternalUpdateOneOptions sets internal options for UpdateOneOptions. +func SetInternalUpdateOneOptions(a *options.UpdateOneOptionsBuilder, key string, option any) error { + typeErrFunc := func(t string) error { + return fmt.Errorf("unexpected type for %q: %T is not %s", key, option, t) + } + switch key { + case "rawData": + b, ok := option.(bool) + if !ok { + return typeErrFunc("bool") + } + a.Opts = append(a.Opts, func(opts *options.UpdateOneOptions) error { + opts.Internal = optionsutil.WithValue(opts.Internal, key, b) + return nil + }) + default: + return fmt.Errorf("unsupported option: %q", key) + } + return nil +} From bccaed58815b1cc07abef2f9bf28fa4a55c47194 Mon Sep 17 00:00:00 2001 From: Qingyang Hu Date: Tue, 8 Jul 2025 09:58:36 -0400 Subject: [PATCH 12/13] add bulkWrite --- .../unified/collection_operation_execution.go | 5 +++++ mongo/bulk_write.go | 13 ++++++++++++ mongo/collection.go | 5 +++++ mongo/options/bulkwriteoptions.go | 6 ++++++ x/mongo/driver/xoptions/options.go | 21 +++++++++++++++++++ 5 files changed, 50 insertions(+) diff --git a/internal/integration/unified/collection_operation_execution.go b/internal/integration/unified/collection_operation_execution.go index 41e74bf5c6..be9afe0cd7 100644 --- a/internal/integration/unified/collection_operation_execution.go +++ b/internal/integration/unified/collection_operation_execution.go @@ -131,6 +131,11 @@ func executeBulkWrite(ctx context.Context, operation *operation) (*operationResu } case "let": opts.SetLet(val.Document()) + case "rawData": + err = xoptions.SetInternalBulkWriteOptions(opts, key, val.Boolean()) + if err != nil { + return nil, err + } default: return nil, fmt.Errorf("unrecognized bulkWrite option %q", key) } diff --git a/mongo/bulk_write.go b/mongo/bulk_write.go index 415a90ae55..7a3181c6c4 100644 --- a/mongo/bulk_write.go +++ b/mongo/bulk_write.go @@ -39,6 +39,7 @@ type bulkWrite struct { writeConcern *writeconcern.WriteConcern result BulkWriteResult let interface{} + rawData *bool } func (bw *bulkWrite) execute(ctx context.Context) error { @@ -209,6 +210,10 @@ func (bw *bulkWrite) runInsert(ctx context.Context, batch bulkWriteBatch) (opera } op = op.Retry(retry) + if bw.rawData != nil { + op.RawData(*bw.rawData) + } + err := op.Execute(ctx) return op.Result(), err @@ -282,6 +287,10 @@ func (bw *bulkWrite) runDelete(ctx context.Context, batch bulkWriteBatch) (opera } op = op.Retry(retry) + if bw.rawData != nil { + op.RawData(*bw.rawData) + } + err := op.Execute(ctx) return op.Result(), err @@ -415,6 +424,10 @@ func (bw *bulkWrite) runUpdate(ctx context.Context, batch bulkWriteBatch) (opera } op = op.Retry(retry) + if bw.rawData != nil { + op.RawData(*bw.rawData) + } + err := op.Execute(ctx) return op.Result(), err diff --git a/mongo/collection.go b/mongo/collection.go index d4c696d0d0..e87b13cea1 100644 --- a/mongo/collection.go +++ b/mongo/collection.go @@ -246,6 +246,11 @@ func (coll *Collection) BulkWrite(ctx context.Context, models []WriteModel, writeConcern: wc, let: args.Let, } + if rawDataOpt := optionsutil.Value(args.Internal, "rawData"); rawDataOpt != nil { + if rawData, ok := rawDataOpt.(bool); ok { + op.rawData = &rawData + } + } err = op.execute(ctx) diff --git a/mongo/options/bulkwriteoptions.go b/mongo/options/bulkwriteoptions.go index 186e83a0c5..20d0395efe 100644 --- a/mongo/options/bulkwriteoptions.go +++ b/mongo/options/bulkwriteoptions.go @@ -6,6 +6,8 @@ package options +import "go.mongodb.org/mongo-driver/v2/internal/optionsutil" + // DefaultOrdered is the default value for the Ordered option in BulkWriteOptions. var DefaultOrdered = true @@ -18,6 +20,10 @@ type BulkWriteOptions struct { Comment interface{} Ordered *bool Let interface{} + + // Deprecated: This option is for internal use only and should not be set. It may be changed or removed in any + // release. + Internal optionsutil.Options } // BulkWriteOptionsBuilder contains options to configure bulk write operations. diff --git a/x/mongo/driver/xoptions/options.go b/x/mongo/driver/xoptions/options.go index 91ebf7bb86..52b308a74e 100644 --- a/x/mongo/driver/xoptions/options.go +++ b/x/mongo/driver/xoptions/options.go @@ -65,6 +65,27 @@ func SetInternalAggregateOptions(a *options.AggregateOptionsBuilder, key string, return nil } +// SetInternalBulkWriteOptions sets internal options for BulkWriteOptions. +func SetInternalBulkWriteOptions(a *options.BulkWriteOptionsBuilder, key string, option any) error { + typeErrFunc := func(t string) error { + return fmt.Errorf("unexpected type for %q: %T is not %s", key, option, t) + } + switch key { + case "rawData": + b, ok := option.(bool) + if !ok { + return typeErrFunc("bool") + } + a.Opts = append(a.Opts, func(opts *options.BulkWriteOptions) error { + opts.Internal = optionsutil.WithValue(opts.Internal, key, b) + return nil + }) + default: + return fmt.Errorf("unsupported option: %q", key) + } + return nil +} + // SetInternalCountOptions sets internal options for CountOptions. func SetInternalCountOptions(a *options.CountOptionsBuilder, key string, option any) error { typeErrFunc := func(t string) error { From 72245edfe62e511df5d4c0e2875df6200ab51ff9 Mon Sep 17 00:00:00 2001 From: Qingyang Hu Date: Fri, 1 Aug 2025 17:41:42 -0400 Subject: [PATCH 13/13] update test case --- x/mongo/driver/xoptions/options_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/mongo/driver/xoptions/options_test.go b/x/mongo/driver/xoptions/options_test.go index e56de6bdcc..4a4e1a371e 100644 --- a/x/mongo/driver/xoptions/options_test.go +++ b/x/mongo/driver/xoptions/options_test.go @@ -84,6 +84,6 @@ func TestSetInternalClientOptions(t *testing.T) { opts := options.Client() err := SetInternalClientOptions(opts, "unsupported", "unsupported") - require.EqualError(t, err, "unsupported option: unsupported") + require.EqualError(t, err, "unsupported option: \"unsupported\"") }) }