Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
qingyang-hu committed Sep 21, 2023
1 parent 0a66171 commit 5446a0d
Show file tree
Hide file tree
Showing 8 changed files with 165 additions and 204 deletions.
37 changes: 35 additions & 2 deletions mongo/client_encryption.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,25 @@ func NewClientEncryption(keyVaultClient *Client, opts ...*options.ClientEncrypti
ce := &ClientEncryption{
keyVaultClient: keyVaultClient,
}
ceo := options.MergeClientEncryptionOptions(opts...)
ceo := options.ClientEncryption()
for _, opt := range opts {
if opt == nil {
continue
}

if opt.KeyVaultNamespace != "" {
ceo.KeyVaultNamespace = opt.KeyVaultNamespace
}
if opt.KmsProviders != nil {
ceo.KmsProviders = opt.KmsProviders
}
if opt.TLSConfig != nil {
ceo.TLSConfig = opt.TLSConfig
}
if opt.HTTPClient != nil {
ceo.HTTPClient = opt.HTTPClient
}
}

// create keyVaultColl
db, coll := splitNamespace(ceo.KeyVaultNamespace)
Expand Down Expand Up @@ -144,7 +162,22 @@ func (ce *ClientEncryption) CreateDataKey(ctx context.Context, kmsProvider strin
opts ...*options.DataKeyOptions) (primitive.Binary, error) {

// translate opts to mcopts.DataKeyOptions
dko := options.MergeDataKeyOptions(opts...)
dko := options.DataKey()
for _, opt := range opts {
if opt == nil {
continue
}

if opt.MasterKey != nil {
dko.MasterKey = opt.MasterKey
}
if opt.KeyAltNames != nil {
dko.KeyAltNames = opt.KeyAltNames
}
if opt.KeyMaterial != nil {
dko.KeyMaterial = opt.KeyMaterial
}
}
co := mcopts.DataKey().SetKeyAltNames(dko.KeyAltNames)
if dko.MasterKey != nil {
keyDoc, err := marshal(
Expand Down
55 changes: 52 additions & 3 deletions mongo/collection.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,34 @@ func closeImplicitSession(sess *session.Client) {
}
}

// mergeCollectionOptions combines the given CollectionOptions instances into a single *CollectionOptions in a
// last-one-wins fashion.
func mergeCollectionOptions(opts ...*options.CollectionOptions) *options.CollectionOptions {
c := options.Collection()

for _, opt := range opts {
if opt == nil {
continue
}
if opt.ReadConcern != nil {
c.ReadConcern = opt.ReadConcern
}
if opt.WriteConcern != nil {
c.WriteConcern = opt.WriteConcern
}
if opt.ReadPreference != nil {
c.ReadPreference = opt.ReadPreference
}
if opt.Registry != nil {
c.Registry = opt.Registry
}
}

return c
}

func newCollection(db *Database, name string, opts ...*options.CollectionOptions) *Collection {
collOpt := options.MergeCollectionOptions(opts...)
collOpt := mergeCollectionOptions(opts...)

rc := db.readConcern
if collOpt.ReadConcern != nil {
Expand Down Expand Up @@ -141,7 +167,7 @@ func (coll *Collection) copy() *Collection {
// precedence.
func (coll *Collection) Clone(opts ...*options.CollectionOptions) (*Collection, error) {
copyColl := coll.copy()
optsColl := options.MergeCollectionOptions(opts...)
optsColl := mergeCollectionOptions(opts...)

if optsColl.ReadConcern != nil {
copyColl.readConcern = optsColl.ReadConcern
Expand Down Expand Up @@ -1018,7 +1044,30 @@ func (coll *Collection) CountDocuments(ctx context.Context, filter interface{},
ctx = context.Background()
}

countOpts := options.MergeCountOptions(opts...)
countOpts := options.Count()
for _, co := range opts {
if co == nil {
continue
}
if co.Collation != nil {
countOpts.Collation = co.Collation
}
if co.Comment != nil {
countOpts.Comment = co.Comment
}
if co.Hint != nil {
countOpts.Hint = co.Hint
}
if co.Limit != nil {
countOpts.Limit = co.Limit
}
if co.MaxTime != nil {
countOpts.MaxTime = co.MaxTime
}
if co.Skip != nil {
countOpts.Skip = co.Skip
}
}

pipelineArr, err := countDocumentsAggregatePipeline(filter, coll.bsonOpts, coll.registry, countOpts)
if err != nil {
Expand Down
81 changes: 78 additions & 3 deletions mongo/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -523,6 +523,63 @@ func (db *Database) Watch(ctx context.Context, pipeline interface{},
return newChangeStream(ctx, csConfig, pipeline, opts...)
}

// mergeCreateCollectionOptions combines the given CreateCollectionOptions instances into a single
// CreateCollectionOptions in a last-one-wins fashion.
func mergeCreateCollectionOptions(opts ...*options.CreateCollectionOptions) *options.CreateCollectionOptions {
cc := options.CreateCollection()

for _, opt := range opts {
if opt == nil {
continue
}

if opt.Capped != nil {
cc.Capped = opt.Capped
}
if opt.Collation != nil {
cc.Collation = opt.Collation
}
if opt.ChangeStreamPreAndPostImages != nil {
cc.ChangeStreamPreAndPostImages = opt.ChangeStreamPreAndPostImages
}
if opt.DefaultIndexOptions != nil {
cc.DefaultIndexOptions = opt.DefaultIndexOptions
}
if opt.MaxDocuments != nil {
cc.MaxDocuments = opt.MaxDocuments
}
if opt.SizeInBytes != nil {
cc.SizeInBytes = opt.SizeInBytes
}
if opt.StorageEngine != nil {
cc.StorageEngine = opt.StorageEngine
}
if opt.ValidationAction != nil {
cc.ValidationAction = opt.ValidationAction
}
if opt.ValidationLevel != nil {
cc.ValidationLevel = opt.ValidationLevel
}
if opt.Validator != nil {
cc.Validator = opt.Validator
}
if opt.ExpireAfterSeconds != nil {
cc.ExpireAfterSeconds = opt.ExpireAfterSeconds
}
if opt.TimeSeriesOptions != nil {
cc.TimeSeriesOptions = opt.TimeSeriesOptions
}
if opt.EncryptedFields != nil {
cc.EncryptedFields = opt.EncryptedFields
}
if opt.ClusteredIndex != nil {
cc.ClusteredIndex = opt.ClusteredIndex
}
}

return cc
}

// CreateCollection executes a create command to explicitly create a new collection with the specified name on the
// server. If the collection being created already exists, this method will return a mongo.CommandError. This method
// requires driver version 1.4.0 or higher.
Expand All @@ -532,7 +589,7 @@ func (db *Database) Watch(ctx context.Context, pipeline interface{},
//
// For more information about the command, see https://www.mongodb.com/docs/manual/reference/command/create/.
func (db *Database) CreateCollection(ctx context.Context, name string, opts ...*options.CreateCollectionOptions) error {
cco := options.MergeCreateCollectionOptions(opts...)
cco := mergeCreateCollectionOptions(opts...)
// Follow Client-Side Encryption specification to check for encryptedFields.
// Check for encryptedFields from create options.
ef := cco.EncryptedFields
Expand Down Expand Up @@ -675,7 +732,7 @@ func (db *Database) createCollection(ctx context.Context, name string, opts ...*
}

func (db *Database) createCollectionOperation(name string, opts ...*options.CreateCollectionOptions) (*operation.Create, error) {
cco := options.MergeCreateCollectionOptions(opts...)
cco := mergeCreateCollectionOptions(opts...)
op := operation.NewCreate(name).ServerAPI(db.client.serverAPI)

if cco.Capped != nil {
Expand Down Expand Up @@ -778,6 +835,24 @@ func (db *Database) createCollectionOperation(name string, opts ...*options.Crea
return op, nil
}

// mergeCreateViewOptions combines the given CreateViewOptions instances into a single CreateViewOptions in a
// last-one-wins fashion.
func mergeCreateViewOptions(opts ...*options.CreateViewOptions) *options.CreateViewOptions {
cv := options.CreateView()

for _, opt := range opts {
if opt == nil {
continue
}

if opt.Collation != nil {
cv.Collation = opt.Collation
}
}

return cv
}

// CreateView executes a create command to explicitly create a view on the server. See
// https://www.mongodb.com/docs/manual/core/views/ for more information about views. This method requires driver version >=
// 1.4.0 and MongoDB version >= 3.4.
Expand All @@ -803,7 +878,7 @@ func (db *Database) CreateView(ctx context.Context, viewName, viewOn string, pip
ViewOn(viewOn).
Pipeline(pipelineArray).
ServerAPI(db.client.serverAPI)
cvo := options.MergeCreateViewOptions(opts...)
cvo := mergeCreateViewOptions(opts...)
if cvo.Collation != nil {
op.Collation(bsoncore.Document(cvo.Collation.ToDocument()))
}
Expand Down
28 changes: 0 additions & 28 deletions mongo/options/clientencryptionoptions.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,31 +120,3 @@ func BuildTLSConfig(tlsOpts map[string]interface{}) (*tls.Config, error) {

return cfg, nil
}

// MergeClientEncryptionOptions combines the argued ClientEncryptionOptions in a last-one wins fashion.
//
// Deprecated: Merging options structs will not be supported in Go Driver 2.0. Users should create a
// single options struct instead.
func MergeClientEncryptionOptions(opts ...*ClientEncryptionOptions) *ClientEncryptionOptions {
ceo := ClientEncryption()
for _, opt := range opts {
if opt == nil {
continue
}

if opt.KeyVaultNamespace != "" {
ceo.KeyVaultNamespace = opt.KeyVaultNamespace
}
if opt.KmsProviders != nil {
ceo.KmsProviders = opt.KmsProviders
}
if opt.TLSConfig != nil {
ceo.TLSConfig = opt.TLSConfig
}
if opt.HTTPClient != nil {
ceo.HTTPClient = opt.HTTPClient
}
}

return ceo
}
29 changes: 0 additions & 29 deletions mongo/options/collectionoptions.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,32 +70,3 @@ func (c *CollectionOptions) SetRegistry(r *bsoncodec.Registry) *CollectionOption
c.Registry = r
return c
}

// MergeCollectionOptions combines the given CollectionOptions instances into a single *CollectionOptions in a
// last-one-wins fashion.
//
// Deprecated: Merging options structs will not be supported in Go Driver 2.0. Users should create a
// single options struct instead.
func MergeCollectionOptions(opts ...*CollectionOptions) *CollectionOptions {
c := Collection()

for _, opt := range opts {
if opt == nil {
continue
}
if opt.ReadConcern != nil {
c.ReadConcern = opt.ReadConcern
}
if opt.WriteConcern != nil {
c.WriteConcern = opt.WriteConcern
}
if opt.ReadPreference != nil {
c.ReadPreference = opt.ReadPreference
}
if opt.Registry != nil {
c.Registry = opt.Registry
}
}

return c
}
33 changes: 0 additions & 33 deletions mongo/options/countoptions.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,36 +87,3 @@ func (co *CountOptions) SetSkip(i int64) *CountOptions {
co.Skip = &i
return co
}

// MergeCountOptions combines the given CountOptions instances into a single CountOptions in a last-one-wins fashion.
//
// Deprecated: Merging options structs will not be supported in Go Driver 2.0. Users should create a
// single options struct instead.
func MergeCountOptions(opts ...*CountOptions) *CountOptions {
countOpts := Count()
for _, co := range opts {
if co == nil {
continue
}
if co.Collation != nil {
countOpts.Collation = co.Collation
}
if co.Comment != nil {
countOpts.Comment = co.Comment
}
if co.Hint != nil {
countOpts.Hint = co.Hint
}
if co.Limit != nil {
countOpts.Limit = co.Limit
}
if co.MaxTime != nil {
countOpts.MaxTime = co.MaxTime
}
if co.Skip != nil {
countOpts.Skip = co.Skip
}
}

return countOpts
}
Loading

0 comments on commit 5446a0d

Please sign in to comment.