...

Source file src/go.mongodb.org/mongo-driver/mongo/integration/unified/crud_helpers.go

Documentation: go.mongodb.org/mongo-driver/mongo/integration/unified

     1  // Copyright (C) MongoDB, Inc. 2017-present.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License"); you may
     4  // not use this file except in compliance with the License. You may obtain
     5  // a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
     6  
     7  package unified
     8  
     9  import (
    10  	"fmt"
    11  
    12  	"go.mongodb.org/mongo-driver/bson"
    13  	"go.mongodb.org/mongo-driver/bson/bsontype"
    14  	"go.mongodb.org/mongo-driver/internal/bsonutil"
    15  	"go.mongodb.org/mongo-driver/mongo/options"
    16  )
    17  
    18  // newMissingArgumentError creates an error to convey that an argument that is required to run an operation is missing
    19  // from the operation's arguments document.
    20  func newMissingArgumentError(arg string) error {
    21  	return fmt.Errorf("operation arguments document is missing required field %q", arg)
    22  }
    23  
    24  type updateArguments struct {
    25  	filter bson.Raw
    26  	update interface{}
    27  	opts   *options.UpdateOptions
    28  }
    29  
    30  func createUpdateArguments(args bson.Raw) (*updateArguments, error) {
    31  	ua := &updateArguments{
    32  		opts: options.Update(),
    33  	}
    34  	var err error
    35  
    36  	elems, _ := args.Elements()
    37  	for _, elem := range elems {
    38  		key := elem.Key()
    39  		val := elem.Value()
    40  
    41  		switch key {
    42  		case "arrayFilters":
    43  			ua.opts.SetArrayFilters(options.ArrayFilters{
    44  				Filters: bsonutil.RawToInterfaces(bsonutil.RawToDocuments(val.Array())...),
    45  			})
    46  		case "bypassDocumentValidation":
    47  			ua.opts.SetBypassDocumentValidation(val.Boolean())
    48  		case "collation":
    49  			collation, err := createCollation(val.Document())
    50  			if err != nil {
    51  				return nil, fmt.Errorf("error creating collation: %w", err)
    52  			}
    53  			ua.opts.SetCollation(collation)
    54  		case "comment":
    55  			ua.opts.SetComment(val)
    56  		case "filter":
    57  			ua.filter = val.Document()
    58  		case "hint":
    59  			hint, err := createHint(val)
    60  			if err != nil {
    61  				return nil, fmt.Errorf("error creating hint: %w", err)
    62  			}
    63  			ua.opts.SetHint(hint)
    64  		case "let":
    65  			ua.opts.SetLet(val.Document())
    66  		case "update":
    67  			ua.update, err = createUpdateValue(val)
    68  			if err != nil {
    69  				return nil, fmt.Errorf("error processing update value: %w", err)
    70  			}
    71  		case "upsert":
    72  			ua.opts.SetUpsert(val.Boolean())
    73  		default:
    74  			return nil, fmt.Errorf("unrecognized update option %q", key)
    75  		}
    76  	}
    77  	if ua.filter == nil {
    78  		return nil, newMissingArgumentError("filter")
    79  	}
    80  	if ua.update == nil {
    81  		return nil, newMissingArgumentError("update")
    82  	}
    83  
    84  	return ua, nil
    85  }
    86  
    87  type listCollectionsArguments struct {
    88  	filter bson.Raw
    89  	opts   *options.ListCollectionsOptions
    90  }
    91  
    92  func createListCollectionsArguments(args bson.Raw) (*listCollectionsArguments, error) {
    93  	lca := &listCollectionsArguments{
    94  		opts: options.ListCollections(),
    95  	}
    96  
    97  	lca.filter = emptyDocument
    98  	elems, _ := args.Elements()
    99  	for _, elem := range elems {
   100  		key := elem.Key()
   101  		val := elem.Value()
   102  
   103  		switch key {
   104  		case "batchSize":
   105  			lca.opts.SetBatchSize(val.Int32())
   106  		case "filter":
   107  			lca.filter = val.Document()
   108  		case "nameOnly":
   109  			lca.opts.SetNameOnly(val.Boolean())
   110  		default:
   111  			return nil, fmt.Errorf("unrecognized listCollections option %q", key)
   112  		}
   113  	}
   114  
   115  	return lca, nil
   116  }
   117  
   118  func createCollation(args bson.Raw) (*options.Collation, error) {
   119  	var collation options.Collation
   120  	elems, _ := args.Elements()
   121  
   122  	for _, elem := range elems {
   123  		switch elem.Key() {
   124  		case "locale":
   125  			collation.Locale = elem.Value().StringValue()
   126  		case "caseLevel":
   127  			collation.CaseLevel = elem.Value().Boolean()
   128  		case "caseFirst":
   129  			collation.CaseFirst = elem.Value().StringValue()
   130  		case "strength":
   131  			collation.Strength = int(elem.Value().Int32())
   132  		case "numericOrdering":
   133  			collation.NumericOrdering = elem.Value().Boolean()
   134  		case "alternate":
   135  			collation.Alternate = elem.Value().StringValue()
   136  		case "maxVariable":
   137  			collation.MaxVariable = elem.Value().StringValue()
   138  		case "normalization":
   139  			collation.Normalization = elem.Value().Boolean()
   140  		case "backwards":
   141  			collation.Backwards = elem.Value().Boolean()
   142  		default:
   143  			return nil, fmt.Errorf("unrecognized collation option %q", elem.Key())
   144  		}
   145  	}
   146  	return &collation, nil
   147  }
   148  
   149  func createHint(val bson.RawValue) (interface{}, error) {
   150  	var hint interface{}
   151  
   152  	switch val.Type {
   153  	case bsontype.String:
   154  		hint = val.StringValue()
   155  	case bsontype.EmbeddedDocument:
   156  		hint = val.Document()
   157  	default:
   158  		return nil, fmt.Errorf("unrecognized hint value type %s", val.Type)
   159  	}
   160  	return hint, nil
   161  }
   162  
   163  func createCommentString(val bson.RawValue) (string, error) {
   164  	switch val.Type {
   165  	case bsontype.String:
   166  		return val.StringValue(), nil
   167  	case bsontype.EmbeddedDocument:
   168  		return val.String(), nil
   169  	default:
   170  		return "", fmt.Errorf("unrecognized 'comment' value type: %T", val)
   171  	}
   172  }
   173  

View as plain text