github.com/mdaxf/iac@v0.0.0-20240519030858-58a061660378/vendor_skip/go.mongodb.org/mongo-driver/x/mongo/driver/operation/command.go (about)

     1  // Copyright (C) MongoDB, Inc. 2021-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/event"
    15  	"go.mongodb.org/mongo-driver/internal/logger"
    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/x/bsonx/bsoncore"
    20  	"go.mongodb.org/mongo-driver/x/mongo/driver"
    21  	"go.mongodb.org/mongo-driver/x/mongo/driver/session"
    22  )
    23  
    24  // Command is used to run a generic operation.
    25  type Command struct {
    26  	command        bsoncore.Document
    27  	readConcern    *readconcern.ReadConcern
    28  	database       string
    29  	deployment     driver.Deployment
    30  	selector       description.ServerSelector
    31  	readPreference *readpref.ReadPref
    32  	clock          *session.ClusterClock
    33  	session        *session.Client
    34  	monitor        *event.CommandMonitor
    35  	resultResponse bsoncore.Document
    36  	resultCursor   *driver.BatchCursor
    37  	crypt          driver.Crypt
    38  	serverAPI      *driver.ServerAPIOptions
    39  	createCursor   bool
    40  	cursorOpts     driver.CursorOptions
    41  	timeout        *time.Duration
    42  	logger         *logger.Logger
    43  }
    44  
    45  // NewCommand constructs and returns a new Command. Once the operation is executed, the result may only be accessed via
    46  // the Result() function.
    47  func NewCommand(command bsoncore.Document) *Command {
    48  	return &Command{
    49  		command: command,
    50  	}
    51  }
    52  
    53  // NewCursorCommand constructs a new Command. Once the operation is executed, the server response will be used to
    54  // construct a cursor, which can be accessed via the ResultCursor() function.
    55  func NewCursorCommand(command bsoncore.Document, cursorOpts driver.CursorOptions) *Command {
    56  	return &Command{
    57  		command:      command,
    58  		cursorOpts:   cursorOpts,
    59  		createCursor: true,
    60  	}
    61  }
    62  
    63  // Result returns the result of executing this operation.
    64  func (c *Command) Result() bsoncore.Document { return c.resultResponse }
    65  
    66  // ResultCursor returns the BatchCursor that was constructed using the command response. If the operation was not
    67  // configured to create a cursor (i.e. it was created using NewCommand rather than NewCursorCommand), this function
    68  // will return nil and an error.
    69  func (c *Command) ResultCursor() (*driver.BatchCursor, error) {
    70  	if !c.createCursor {
    71  		return nil, errors.New("command operation was not configured to create a cursor, but a result cursor was requested")
    72  	}
    73  	return c.resultCursor, nil
    74  }
    75  
    76  // Execute runs this operations and returns an error if the operation did not execute successfully.
    77  func (c *Command) Execute(ctx context.Context) error {
    78  	if c.deployment == nil {
    79  		return errors.New("the Command operation must have a Deployment set before Execute can be called")
    80  	}
    81  
    82  	// TODO(GODRIVER-2649): Actually pass readConcern to underlying driver.Operation.
    83  	return driver.Operation{
    84  		CommandFn: func(dst []byte, desc description.SelectedServer) ([]byte, error) {
    85  			return append(dst, c.command[4:len(c.command)-1]...), nil
    86  		},
    87  		ProcessResponseFn: func(info driver.ResponseInfo) error {
    88  			c.resultResponse = info.ServerResponse
    89  
    90  			if c.createCursor {
    91  				cursorRes, err := driver.NewCursorResponse(info)
    92  				if err != nil {
    93  					return err
    94  				}
    95  
    96  				c.resultCursor, err = driver.NewBatchCursor(cursorRes, c.session, c.clock, c.cursorOpts)
    97  				return err
    98  			}
    99  
   100  			return nil
   101  		},
   102  		Client:         c.session,
   103  		Clock:          c.clock,
   104  		CommandMonitor: c.monitor,
   105  		Database:       c.database,
   106  		Deployment:     c.deployment,
   107  		ReadPreference: c.readPreference,
   108  		Selector:       c.selector,
   109  		Crypt:          c.crypt,
   110  		ServerAPI:      c.serverAPI,
   111  		Timeout:        c.timeout,
   112  		Logger:         c.logger,
   113  	}.Execute(ctx)
   114  }
   115  
   116  // Session sets the session for this operation.
   117  func (c *Command) Session(session *session.Client) *Command {
   118  	if c == nil {
   119  		c = new(Command)
   120  	}
   121  
   122  	c.session = session
   123  	return c
   124  }
   125  
   126  // ClusterClock sets the cluster clock for this operation.
   127  func (c *Command) ClusterClock(clock *session.ClusterClock) *Command {
   128  	if c == nil {
   129  		c = new(Command)
   130  	}
   131  
   132  	c.clock = clock
   133  	return c
   134  }
   135  
   136  // CommandMonitor sets the monitor to use for APM events.
   137  func (c *Command) CommandMonitor(monitor *event.CommandMonitor) *Command {
   138  	if c == nil {
   139  		c = new(Command)
   140  	}
   141  
   142  	c.monitor = monitor
   143  	return c
   144  }
   145  
   146  // Database sets the database to run this operation against.
   147  func (c *Command) Database(database string) *Command {
   148  	if c == nil {
   149  		c = new(Command)
   150  	}
   151  
   152  	c.database = database
   153  	return c
   154  }
   155  
   156  // Deployment sets the deployment to use for this operation.
   157  func (c *Command) Deployment(deployment driver.Deployment) *Command {
   158  	if c == nil {
   159  		c = new(Command)
   160  	}
   161  
   162  	c.deployment = deployment
   163  	return c
   164  }
   165  
   166  // ReadConcern specifies the read concern for this operation.
   167  func (c *Command) ReadConcern(readConcern *readconcern.ReadConcern) *Command {
   168  	if c == nil {
   169  		c = new(Command)
   170  	}
   171  
   172  	c.readConcern = readConcern
   173  	return c
   174  }
   175  
   176  // ReadPreference set the read preference used with this operation.
   177  func (c *Command) ReadPreference(readPreference *readpref.ReadPref) *Command {
   178  	if c == nil {
   179  		c = new(Command)
   180  	}
   181  
   182  	c.readPreference = readPreference
   183  	return c
   184  }
   185  
   186  // ServerSelector sets the selector used to retrieve a server.
   187  func (c *Command) ServerSelector(selector description.ServerSelector) *Command {
   188  	if c == nil {
   189  		c = new(Command)
   190  	}
   191  
   192  	c.selector = selector
   193  	return c
   194  }
   195  
   196  // Crypt sets the Crypt object to use for automatic encryption and decryption.
   197  func (c *Command) Crypt(crypt driver.Crypt) *Command {
   198  	if c == nil {
   199  		c = new(Command)
   200  	}
   201  
   202  	c.crypt = crypt
   203  	return c
   204  }
   205  
   206  // ServerAPI sets the server API version for this operation.
   207  func (c *Command) ServerAPI(serverAPI *driver.ServerAPIOptions) *Command {
   208  	if c == nil {
   209  		c = new(Command)
   210  	}
   211  
   212  	c.serverAPI = serverAPI
   213  	return c
   214  }
   215  
   216  // Timeout sets the timeout for this operation.
   217  func (c *Command) Timeout(timeout *time.Duration) *Command {
   218  	if c == nil {
   219  		c = new(Command)
   220  	}
   221  
   222  	c.timeout = timeout
   223  	return c
   224  }
   225  
   226  // Logger sets the logger for this operation.
   227  func (c *Command) Logger(logger *logger.Logger) *Command {
   228  	if c == nil {
   229  		c = new(Command)
   230  	}
   231  
   232  	c.logger = logger
   233  	return c
   234  }