github.com/mdaxf/iac@v0.0.0-20240519030858-58a061660378/vendor_skip/go.mongodb.org/mongo-driver/x/mongo/driver/operation/aggregate.go (about) 1 // Copyright (C) MongoDB, Inc. 2019-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 operation 8 9 import ( 10 "context" 11 "errors" 12 "time" 13 14 "go.mongodb.org/mongo-driver/bson/bsontype" 15 "go.mongodb.org/mongo-driver/event" 16 "go.mongodb.org/mongo-driver/mongo/description" 17 "go.mongodb.org/mongo-driver/mongo/readconcern" 18 "go.mongodb.org/mongo-driver/mongo/readpref" 19 "go.mongodb.org/mongo-driver/mongo/writeconcern" 20 "go.mongodb.org/mongo-driver/x/bsonx/bsoncore" 21 "go.mongodb.org/mongo-driver/x/mongo/driver" 22 "go.mongodb.org/mongo-driver/x/mongo/driver/session" 23 ) 24 25 // Aggregate represents an aggregate operation. 26 type Aggregate struct { 27 allowDiskUse *bool 28 batchSize *int32 29 bypassDocumentValidation *bool 30 collation bsoncore.Document 31 comment *string 32 hint bsoncore.Value 33 maxTime *time.Duration 34 pipeline bsoncore.Document 35 session *session.Client 36 clock *session.ClusterClock 37 collection string 38 monitor *event.CommandMonitor 39 database string 40 deployment driver.Deployment 41 readConcern *readconcern.ReadConcern 42 readPreference *readpref.ReadPref 43 retry *driver.RetryMode 44 selector description.ServerSelector 45 writeConcern *writeconcern.WriteConcern 46 crypt driver.Crypt 47 serverAPI *driver.ServerAPIOptions 48 let bsoncore.Document 49 hasOutputStage bool 50 customOptions map[string]bsoncore.Value 51 timeout *time.Duration 52 53 result driver.CursorResponse 54 } 55 56 // NewAggregate constructs and returns a new Aggregate. 57 func NewAggregate(pipeline bsoncore.Document) *Aggregate { 58 return &Aggregate{ 59 pipeline: pipeline, 60 } 61 } 62 63 // Result returns the result of executing this operation. 64 func (a *Aggregate) Result(opts driver.CursorOptions) (*driver.BatchCursor, error) { 65 66 clientSession := a.session 67 68 clock := a.clock 69 opts.ServerAPI = a.serverAPI 70 return driver.NewBatchCursor(a.result, clientSession, clock, opts) 71 } 72 73 // ResultCursorResponse returns the underlying CursorResponse result of executing this 74 // operation. 75 func (a *Aggregate) ResultCursorResponse() driver.CursorResponse { 76 return a.result 77 } 78 79 func (a *Aggregate) processResponse(info driver.ResponseInfo) error { 80 var err error 81 82 a.result, err = driver.NewCursorResponse(info) 83 return err 84 85 } 86 87 // Execute runs this operations and returns an error if the operation did not execute successfully. 88 func (a *Aggregate) Execute(ctx context.Context) error { 89 if a.deployment == nil { 90 return errors.New("the Aggregate operation must have a Deployment set before Execute can be called") 91 } 92 93 return driver.Operation{ 94 CommandFn: a.command, 95 ProcessResponseFn: a.processResponse, 96 97 Client: a.session, 98 Clock: a.clock, 99 CommandMonitor: a.monitor, 100 Database: a.database, 101 Deployment: a.deployment, 102 ReadConcern: a.readConcern, 103 ReadPreference: a.readPreference, 104 Type: driver.Read, 105 RetryMode: a.retry, 106 Selector: a.selector, 107 WriteConcern: a.writeConcern, 108 Crypt: a.crypt, 109 MinimumWriteConcernWireVersion: 5, 110 ServerAPI: a.serverAPI, 111 IsOutputAggregate: a.hasOutputStage, 112 MaxTime: a.maxTime, 113 Timeout: a.timeout, 114 }.Execute(ctx) 115 116 } 117 118 func (a *Aggregate) command(dst []byte, desc description.SelectedServer) ([]byte, error) { 119 header := bsoncore.Value{Type: bsontype.String, Data: bsoncore.AppendString(nil, a.collection)} 120 if a.collection == "" { 121 header = bsoncore.Value{Type: bsontype.Int32, Data: []byte{0x01, 0x00, 0x00, 0x00}} 122 } 123 dst = bsoncore.AppendValueElement(dst, "aggregate", header) 124 125 cursorIdx, cursorDoc := bsoncore.AppendDocumentStart(nil) 126 if a.allowDiskUse != nil { 127 128 dst = bsoncore.AppendBooleanElement(dst, "allowDiskUse", *a.allowDiskUse) 129 } 130 if a.batchSize != nil { 131 cursorDoc = bsoncore.AppendInt32Element(cursorDoc, "batchSize", *a.batchSize) 132 } 133 if a.bypassDocumentValidation != nil { 134 135 dst = bsoncore.AppendBooleanElement(dst, "bypassDocumentValidation", *a.bypassDocumentValidation) 136 } 137 if a.collation != nil { 138 139 if desc.WireVersion == nil || !desc.WireVersion.Includes(5) { 140 return nil, errors.New("the 'collation' command parameter requires a minimum server wire version of 5") 141 } 142 dst = bsoncore.AppendDocumentElement(dst, "collation", a.collation) 143 } 144 if a.comment != nil { 145 146 dst = bsoncore.AppendStringElement(dst, "comment", *a.comment) 147 } 148 if a.hint.Type != bsontype.Type(0) { 149 150 dst = bsoncore.AppendValueElement(dst, "hint", a.hint) 151 } 152 if a.pipeline != nil { 153 154 dst = bsoncore.AppendArrayElement(dst, "pipeline", a.pipeline) 155 } 156 if a.let != nil { 157 dst = bsoncore.AppendDocumentElement(dst, "let", a.let) 158 } 159 for optionName, optionValue := range a.customOptions { 160 dst = bsoncore.AppendValueElement(dst, optionName, optionValue) 161 } 162 cursorDoc, _ = bsoncore.AppendDocumentEnd(cursorDoc, cursorIdx) 163 dst = bsoncore.AppendDocumentElement(dst, "cursor", cursorDoc) 164 165 return dst, nil 166 } 167 168 // AllowDiskUse enables writing to temporary files. When true, aggregation stages can write to the dbPath/_tmp directory. 169 func (a *Aggregate) AllowDiskUse(allowDiskUse bool) *Aggregate { 170 if a == nil { 171 a = new(Aggregate) 172 } 173 174 a.allowDiskUse = &allowDiskUse 175 return a 176 } 177 178 // BatchSize specifies the number of documents to return in every batch. 179 func (a *Aggregate) BatchSize(batchSize int32) *Aggregate { 180 if a == nil { 181 a = new(Aggregate) 182 } 183 184 a.batchSize = &batchSize 185 return a 186 } 187 188 // BypassDocumentValidation allows the write to opt-out of document level validation. This only applies when the $out stage is specified. 189 func (a *Aggregate) BypassDocumentValidation(bypassDocumentValidation bool) *Aggregate { 190 if a == nil { 191 a = new(Aggregate) 192 } 193 194 a.bypassDocumentValidation = &bypassDocumentValidation 195 return a 196 } 197 198 // Collation specifies a collation. This option is only valid for server versions 3.4 and above. 199 func (a *Aggregate) Collation(collation bsoncore.Document) *Aggregate { 200 if a == nil { 201 a = new(Aggregate) 202 } 203 204 a.collation = collation 205 return a 206 } 207 208 // Comment specifies an arbitrary string to help trace the operation through the database profiler, currentOp, and logs. 209 func (a *Aggregate) Comment(comment string) *Aggregate { 210 if a == nil { 211 a = new(Aggregate) 212 } 213 214 a.comment = &comment 215 return a 216 } 217 218 // Hint specifies the index to use. 219 func (a *Aggregate) Hint(hint bsoncore.Value) *Aggregate { 220 if a == nil { 221 a = new(Aggregate) 222 } 223 224 a.hint = hint 225 return a 226 } 227 228 // MaxTime specifies the maximum amount of time to allow the query to run on the server. 229 func (a *Aggregate) MaxTime(maxTime *time.Duration) *Aggregate { 230 if a == nil { 231 a = new(Aggregate) 232 } 233 234 a.maxTime = maxTime 235 return a 236 } 237 238 // Pipeline determines how data is transformed for an aggregation. 239 func (a *Aggregate) Pipeline(pipeline bsoncore.Document) *Aggregate { 240 if a == nil { 241 a = new(Aggregate) 242 } 243 244 a.pipeline = pipeline 245 return a 246 } 247 248 // Session sets the session for this operation. 249 func (a *Aggregate) Session(session *session.Client) *Aggregate { 250 if a == nil { 251 a = new(Aggregate) 252 } 253 254 a.session = session 255 return a 256 } 257 258 // ClusterClock sets the cluster clock for this operation. 259 func (a *Aggregate) ClusterClock(clock *session.ClusterClock) *Aggregate { 260 if a == nil { 261 a = new(Aggregate) 262 } 263 264 a.clock = clock 265 return a 266 } 267 268 // Collection sets the collection that this command will run against. 269 func (a *Aggregate) Collection(collection string) *Aggregate { 270 if a == nil { 271 a = new(Aggregate) 272 } 273 274 a.collection = collection 275 return a 276 } 277 278 // CommandMonitor sets the monitor to use for APM events. 279 func (a *Aggregate) CommandMonitor(monitor *event.CommandMonitor) *Aggregate { 280 if a == nil { 281 a = new(Aggregate) 282 } 283 284 a.monitor = monitor 285 return a 286 } 287 288 // Database sets the database to run this operation against. 289 func (a *Aggregate) Database(database string) *Aggregate { 290 if a == nil { 291 a = new(Aggregate) 292 } 293 294 a.database = database 295 return a 296 } 297 298 // Deployment sets the deployment to use for this operation. 299 func (a *Aggregate) Deployment(deployment driver.Deployment) *Aggregate { 300 if a == nil { 301 a = new(Aggregate) 302 } 303 304 a.deployment = deployment 305 return a 306 } 307 308 // ReadConcern specifies the read concern for this operation. 309 func (a *Aggregate) ReadConcern(readConcern *readconcern.ReadConcern) *Aggregate { 310 if a == nil { 311 a = new(Aggregate) 312 } 313 314 a.readConcern = readConcern 315 return a 316 } 317 318 // ReadPreference set the read preference used with this operation. 319 func (a *Aggregate) ReadPreference(readPreference *readpref.ReadPref) *Aggregate { 320 if a == nil { 321 a = new(Aggregate) 322 } 323 324 a.readPreference = readPreference 325 return a 326 } 327 328 // ServerSelector sets the selector used to retrieve a server. 329 func (a *Aggregate) ServerSelector(selector description.ServerSelector) *Aggregate { 330 if a == nil { 331 a = new(Aggregate) 332 } 333 334 a.selector = selector 335 return a 336 } 337 338 // WriteConcern sets the write concern for this operation. 339 func (a *Aggregate) WriteConcern(writeConcern *writeconcern.WriteConcern) *Aggregate { 340 if a == nil { 341 a = new(Aggregate) 342 } 343 344 a.writeConcern = writeConcern 345 return a 346 } 347 348 // Retry enables retryable writes for this operation. Retries are not handled automatically, 349 // instead a boolean is returned from Execute and SelectAndExecute that indicates if the 350 // operation can be retried. Retrying is handled by calling RetryExecute. 351 func (a *Aggregate) Retry(retry driver.RetryMode) *Aggregate { 352 if a == nil { 353 a = new(Aggregate) 354 } 355 356 a.retry = &retry 357 return a 358 } 359 360 // Crypt sets the Crypt object to use for automatic encryption and decryption. 361 func (a *Aggregate) Crypt(crypt driver.Crypt) *Aggregate { 362 if a == nil { 363 a = new(Aggregate) 364 } 365 366 a.crypt = crypt 367 return a 368 } 369 370 // ServerAPI sets the server API version for this operation. 371 func (a *Aggregate) ServerAPI(serverAPI *driver.ServerAPIOptions) *Aggregate { 372 if a == nil { 373 a = new(Aggregate) 374 } 375 376 a.serverAPI = serverAPI 377 return a 378 } 379 380 // Let specifies the let document to use. This option is only valid for server versions 5.0 and above. 381 func (a *Aggregate) Let(let bsoncore.Document) *Aggregate { 382 if a == nil { 383 a = new(Aggregate) 384 } 385 386 a.let = let 387 return a 388 } 389 390 // HasOutputStage specifies whether the aggregate contains an output stage. Used in determining when to 391 // append read preference at the operation level. 392 func (a *Aggregate) HasOutputStage(hos bool) *Aggregate { 393 if a == nil { 394 a = new(Aggregate) 395 } 396 397 a.hasOutputStage = hos 398 return a 399 } 400 401 // CustomOptions specifies extra options to use in the aggregate command. 402 func (a *Aggregate) CustomOptions(co map[string]bsoncore.Value) *Aggregate { 403 if a == nil { 404 a = new(Aggregate) 405 } 406 407 a.customOptions = co 408 return a 409 } 410 411 // Timeout sets the timeout for this operation. 412 func (a *Aggregate) Timeout(timeout *time.Duration) *Aggregate { 413 if a == nil { 414 a = new(Aggregate) 415 } 416 417 a.timeout = timeout 418 return a 419 }