// Copyright (C) MongoDB, Inc. 2019-present. // // Licensed under the Apache License, Version 2.0 (the "License"); you may // not use this file except in compliance with the License. You may obtain // a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 // Code generated by operationgen. DO NOT EDIT. package operation import ( "context" "errors" "fmt" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/bson/bsontype" "go.mongodb.org/mongo-driver/event" "go.mongodb.org/mongo-driver/mongo/writeconcern" "go.mongodb.org/mongo-driver/x/bsonx/bsoncore" "go.mongodb.org/mongo-driver/x/mongo/driver" "go.mongodb.org/mongo-driver/x/mongo/driver/description" "go.mongodb.org/mongo-driver/x/mongo/driver/session" ) // FindAndModify performs a findAndModify operation. type FindAndModify struct { arrayFilters bsoncore.Document bypassDocumentValidation *bool collation bsoncore.Document fields bsoncore.Document maxTimeMS *int64 newDocument *bool query bsoncore.Document remove *bool sort bsoncore.Document update bsoncore.Value upsert *bool session *session.Client clock *session.ClusterClock collection string monitor *event.CommandMonitor database string deployment driver.Deployment selector description.ServerSelector writeConcern *writeconcern.WriteConcern retry *driver.RetryMode crypt *driver.Crypt hint bsoncore.Value result FindAndModifyResult } type LastErrorObject struct { // True if an update modified an existing document UpdatedExisting bool // Object ID of the upserted document. Upserted interface{} } type FindAndModifyResult struct { // Either the old or modified document, depending on the value of the new parameter. Value bsoncore.Document // Contains information about updates and upserts. LastErrorObject LastErrorObject } func buildFindAndModifyResult(response bsoncore.Document, srvr driver.Server) (FindAndModifyResult, error) { elements, err := response.Elements() if err != nil { return FindAndModifyResult{}, err } famr := FindAndModifyResult{} for _, element := range elements { switch element.Key() { case "value": var ok bool famr.Value, ok = element.Value().DocumentOK() if !ok { err = fmt.Errorf("response field 'value' is type document, but received BSON type %s", element.Value().Type) } case "lastErrorObject": valDoc, ok := element.Value().DocumentOK() if !ok { err = fmt.Errorf("response field 'lastErrorObject' is type document, but received BSON type %s", element.Value().Type) break } var leo LastErrorObject if err = bson.Unmarshal(valDoc, &leo); err != nil { break } famr.LastErrorObject = leo } } return famr, nil } // NewFindAndModify constructs and returns a new FindAndModify. func NewFindAndModify(query bsoncore.Document) *FindAndModify { return &FindAndModify{ query: query, } } // Result returns the result of executing this operation. func (fam *FindAndModify) Result() FindAndModifyResult { return fam.result } func (fam *FindAndModify) processResponse(response bsoncore.Document, srvr driver.Server, desc description.Server, _ int) error { var err error fam.result, err = buildFindAndModifyResult(response, srvr) return err } // Execute runs this operations and returns an error if the operaiton did not execute successfully. func (fam *FindAndModify) Execute(ctx context.Context) error { if fam.deployment == nil { return errors.New("the FindAndModify operation must have a Deployment set before Execute can be called") } return driver.Operation{ CommandFn: fam.command, ProcessResponseFn: fam.processResponse, RetryMode: fam.retry, Type: driver.Write, Client: fam.session, Clock: fam.clock, CommandMonitor: fam.monitor, Database: fam.database, Deployment: fam.deployment, Selector: fam.selector, WriteConcern: fam.writeConcern, Crypt: fam.crypt, }.Execute(ctx, nil) } func (fam *FindAndModify) command(dst []byte, desc description.SelectedServer) ([]byte, error) { dst = bsoncore.AppendStringElement(dst, "findAndModify", fam.collection) if fam.arrayFilters != nil { if desc.WireVersion == nil || !desc.WireVersion.Includes(6) { return nil, errors.New("the 'arrayFilters' command parameter requires a minimum server wire version of 6") } dst = bsoncore.AppendArrayElement(dst, "arrayFilters", fam.arrayFilters) } if fam.bypassDocumentValidation != nil { dst = bsoncore.AppendBooleanElement(dst, "bypassDocumentValidation", *fam.bypassDocumentValidation) } if fam.collation != nil { if desc.WireVersion == nil || !desc.WireVersion.Includes(5) { return nil, errors.New("the 'collation' command parameter requires a minimum server wire version of 5") } dst = bsoncore.AppendDocumentElement(dst, "collation", fam.collation) } if fam.fields != nil { dst = bsoncore.AppendDocumentElement(dst, "fields", fam.fields) } if fam.maxTimeMS != nil { dst = bsoncore.AppendInt64Element(dst, "maxTimeMS", *fam.maxTimeMS) } if fam.newDocument != nil { dst = bsoncore.AppendBooleanElement(dst, "new", *fam.newDocument) } if fam.query != nil { dst = bsoncore.AppendDocumentElement(dst, "query", fam.query) } if fam.remove != nil { dst = bsoncore.AppendBooleanElement(dst, "remove", *fam.remove) } if fam.sort != nil { dst = bsoncore.AppendDocumentElement(dst, "sort", fam.sort) } if fam.update.Data != nil { dst = bsoncore.AppendValueElement(dst, "update", fam.update) } if fam.upsert != nil { dst = bsoncore.AppendBooleanElement(dst, "upsert", *fam.upsert) } if fam.hint.Type != bsontype.Type(0) { if desc.WireVersion == nil || !desc.WireVersion.Includes(8) { return nil, errors.New("the 'hint' command parameter requires a minimum server wire version of 8") } if !fam.writeConcern.Acknowledged() { return nil, errUnacknowledgedHint } dst = bsoncore.AppendValueElement(dst, "hint", fam.hint) } return dst, nil } // ArrayFilters specifies an array of filter documents that determines which array elements to modify for an update operation on an array field. func (fam *FindAndModify) ArrayFilters(arrayFilters bsoncore.Document) *FindAndModify { if fam == nil { fam = new(FindAndModify) } fam.arrayFilters = arrayFilters return fam } // BypassDocumentValidation specifies if document validation can be skipped when executing the operation. func (fam *FindAndModify) BypassDocumentValidation(bypassDocumentValidation bool) *FindAndModify { if fam == nil { fam = new(FindAndModify) } fam.bypassDocumentValidation = &bypassDocumentValidation return fam } // Collation specifies a collation to be used. func (fam *FindAndModify) Collation(collation bsoncore.Document) *FindAndModify { if fam == nil { fam = new(FindAndModify) } fam.collation = collation return fam } // Fields specifies a subset of fields to return. func (fam *FindAndModify) Fields(fields bsoncore.Document) *FindAndModify { if fam == nil { fam = new(FindAndModify) } fam.fields = fields return fam } // MaxTimeMS specifies the maximum amount of time to allow the operation to run. func (fam *FindAndModify) MaxTimeMS(maxTimeMS int64) *FindAndModify { if fam == nil { fam = new(FindAndModify) } fam.maxTimeMS = &maxTimeMS return fam } // NewDocument specifies whether to return the modified document or the original. Defaults to false (return original). func (fam *FindAndModify) NewDocument(newDocument bool) *FindAndModify { if fam == nil { fam = new(FindAndModify) } fam.newDocument = &newDocument return fam } // Query specifies the selection criteria for the modification. func (fam *FindAndModify) Query(query bsoncore.Document) *FindAndModify { if fam == nil { fam = new(FindAndModify) } fam.query = query return fam } // Remove specifies that the matched document should be removed. Defaults to false. func (fam *FindAndModify) Remove(remove bool) *FindAndModify { if fam == nil { fam = new(FindAndModify) } fam.remove = &remove return fam } // Sort determines which document the operation modifies if the query matches multiple documents.The first document matched by the sort order will be modified. // func (fam *FindAndModify) Sort(sort bsoncore.Document) *FindAndModify { if fam == nil { fam = new(FindAndModify) } fam.sort = sort return fam } // Update specifies the update document to perform on the matched document. func (fam *FindAndModify) Update(update bsoncore.Value) *FindAndModify { if fam == nil { fam = new(FindAndModify) } fam.update = update return fam } // Upsert specifies whether or not to create a new document if no documents match the query when doing an update. Defaults to false. func (fam *FindAndModify) Upsert(upsert bool) *FindAndModify { if fam == nil { fam = new(FindAndModify) } fam.upsert = &upsert return fam } // Session sets the session for this operation. func (fam *FindAndModify) Session(session *session.Client) *FindAndModify { if fam == nil { fam = new(FindAndModify) } fam.session = session return fam } // ClusterClock sets the cluster clock for this operation. func (fam *FindAndModify) ClusterClock(clock *session.ClusterClock) *FindAndModify { if fam == nil { fam = new(FindAndModify) } fam.clock = clock return fam } // Collection sets the collection that this command will run against. func (fam *FindAndModify) Collection(collection string) *FindAndModify { if fam == nil { fam = new(FindAndModify) } fam.collection = collection return fam } // CommandMonitor sets the monitor to use for APM events. func (fam *FindAndModify) CommandMonitor(monitor *event.CommandMonitor) *FindAndModify { if fam == nil { fam = new(FindAndModify) } fam.monitor = monitor return fam } // Database sets the database to run this operation against. func (fam *FindAndModify) Database(database string) *FindAndModify { if fam == nil { fam = new(FindAndModify) } fam.database = database return fam } // Deployment sets the deployment to use for this operation. func (fam *FindAndModify) Deployment(deployment driver.Deployment) *FindAndModify { if fam == nil { fam = new(FindAndModify) } fam.deployment = deployment return fam } // ServerSelector sets the selector used to retrieve a server. func (fam *FindAndModify) ServerSelector(selector description.ServerSelector) *FindAndModify { if fam == nil { fam = new(FindAndModify) } fam.selector = selector return fam } // WriteConcern sets the write concern for this operation. func (fam *FindAndModify) WriteConcern(writeConcern *writeconcern.WriteConcern) *FindAndModify { if fam == nil { fam = new(FindAndModify) } fam.writeConcern = writeConcern return fam } // Retry enables retryable writes for this operation. Retries are not handled automatically, // instead a boolean is returned from Execute and SelectAndExecute that indicates if the // operation can be retried. Retrying is handled by calling RetryExecute. func (fam *FindAndModify) Retry(retry driver.RetryMode) *FindAndModify { if fam == nil { fam = new(FindAndModify) } fam.retry = &retry return fam } // Crypt sets the Crypt object to use for automatic encryption and decryption. func (fam *FindAndModify) Crypt(crypt *driver.Crypt) *FindAndModify { if fam == nil { fam = new(FindAndModify) } fam.crypt = crypt return fam } // Hint specifies the index to use. func (fam *FindAndModify) Hint(hint bsoncore.Value) *FindAndModify { if fam == nil { fam = new(FindAndModify) } fam.hint = hint return fam }