...
1
2
3
4
5
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
19
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