github.com/mdaxf/iac@v0.0.0-20240519030858-58a061660378/vendor_skip/go.mongodb.org/mongo-driver/mongo/single_result.go (about) 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 mongo 8 9 import ( 10 "context" 11 "errors" 12 "fmt" 13 14 "go.mongodb.org/mongo-driver/bson" 15 "go.mongodb.org/mongo-driver/bson/bsoncodec" 16 "go.mongodb.org/mongo-driver/mongo/options" 17 ) 18 19 // ErrNoDocuments is returned by SingleResult methods when the operation that created the SingleResult did not return 20 // any documents. 21 var ErrNoDocuments = errors.New("mongo: no documents in result") 22 23 // SingleResult represents a single document returned from an operation. If the operation resulted in an error, all 24 // SingleResult methods will return that error. If the operation did not return any documents, all SingleResult methods 25 // will return ErrNoDocuments. 26 type SingleResult struct { 27 ctx context.Context 28 err error 29 cur *Cursor 30 rdr bson.Raw 31 bsonOpts *options.BSONOptions 32 reg *bsoncodec.Registry 33 } 34 35 // NewSingleResultFromDocument creates a SingleResult with the provided error, registry, and an underlying Cursor pre-loaded with 36 // the provided document, error and registry. If no registry is provided, bson.DefaultRegistry will be used. If an error distinct 37 // from the one provided occurs during creation of the SingleResult, that error will be stored on the returned SingleResult. 38 // 39 // The document parameter must be a non-nil document. 40 func NewSingleResultFromDocument(document interface{}, err error, registry *bsoncodec.Registry) *SingleResult { 41 if document == nil { 42 return &SingleResult{err: ErrNilDocument} 43 } 44 if registry == nil { 45 registry = bson.DefaultRegistry 46 } 47 48 cur, createErr := NewCursorFromDocuments([]interface{}{document}, err, registry) 49 if createErr != nil { 50 return &SingleResult{err: createErr} 51 } 52 53 return &SingleResult{ 54 cur: cur, 55 err: err, 56 reg: registry, 57 } 58 } 59 60 // Decode will unmarshal the document represented by this SingleResult into v. If there was an error from the operation 61 // that created this SingleResult, that error will be returned. If the operation returned no documents, Decode will 62 // return ErrNoDocuments. 63 // 64 // If the operation was successful and returned a document, Decode will return any errors from the unmarshalling process 65 // without any modification. If v is nil or is a typed nil, an error will be returned. 66 func (sr *SingleResult) Decode(v interface{}) error { 67 if sr.err != nil { 68 return sr.err 69 } 70 if sr.reg == nil { 71 return bson.ErrNilRegistry 72 } 73 74 if sr.err = sr.setRdrContents(); sr.err != nil { 75 return sr.err 76 } 77 78 dec, err := getDecoder(sr.rdr, sr.bsonOpts, sr.reg) 79 if err != nil { 80 return fmt.Errorf("error configuring BSON decoder: %w", err) 81 } 82 83 return dec.Decode(v) 84 } 85 86 // DecodeBytes will return the document represented by this SingleResult as a bson.Raw. If there was an error from the 87 // operation that created this SingleResult, both the result and that error will be returned. If the operation returned 88 // no documents, this will return (nil, ErrNoDocuments). 89 func (sr *SingleResult) DecodeBytes() (bson.Raw, error) { 90 if sr.err != nil { 91 return sr.rdr, sr.err 92 } 93 94 if sr.err = sr.setRdrContents(); sr.err != nil { 95 return nil, sr.err 96 } 97 return sr.rdr, nil 98 } 99 100 // setRdrContents will set the contents of rdr by iterating the underlying cursor if necessary. 101 func (sr *SingleResult) setRdrContents() error { 102 switch { 103 case sr.err != nil: 104 return sr.err 105 case sr.rdr != nil: 106 return nil 107 case sr.cur != nil: 108 defer sr.cur.Close(sr.ctx) 109 110 if !sr.cur.Next(sr.ctx) { 111 if err := sr.cur.Err(); err != nil { 112 return err 113 } 114 115 return ErrNoDocuments 116 } 117 sr.rdr = sr.cur.Current 118 return nil 119 } 120 121 return ErrNoDocuments 122 } 123 124 // Err provides a way to check for query errors without calling Decode. Err returns the error, if 125 // any, that was encountered while running the operation. If the operation was successful but did 126 // not return any documents, Err returns ErrNoDocuments. If this error is not nil, this error will 127 // also be returned from Decode. 128 func (sr *SingleResult) Err() error { 129 sr.err = sr.setRdrContents() 130 131 return sr.err 132 }