You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

single_result.go 2.6 kB

4 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  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. package mongo
  7. import (
  8. "context"
  9. "errors"
  10. "go.mongodb.org/mongo-driver/bson"
  11. "go.mongodb.org/mongo-driver/bson/bsoncodec"
  12. )
  13. // ErrNoDocuments is returned by Decode when an operation that returns a
  14. // SingleResult doesn't return any documents.
  15. var ErrNoDocuments = errors.New("mongo: no documents in result")
  16. // SingleResult represents a single document returned from an operation. If
  17. // the operation returned an error, the Err method of SingleResult will
  18. // return that error.
  19. type SingleResult struct {
  20. err error
  21. cur *Cursor
  22. rdr bson.Raw
  23. reg *bsoncodec.Registry
  24. }
  25. // Decode will attempt to decode the first document into v. If there was an
  26. // error from the operation that created this SingleResult then the error
  27. // will be returned. If there were no returned documents, ErrNoDocuments is
  28. // returned. If v is nil or is a typed nil, an error will be returned.
  29. func (sr *SingleResult) Decode(v interface{}) error {
  30. if sr.err != nil {
  31. return sr.err
  32. }
  33. if sr.reg == nil {
  34. return bson.ErrNilRegistry
  35. }
  36. if sr.err = sr.setRdrContents(); sr.err != nil {
  37. return sr.err
  38. }
  39. return bson.UnmarshalWithRegistry(sr.reg, sr.rdr, v)
  40. }
  41. // DecodeBytes will return a copy of the document as a bson.Raw. If there was an
  42. // error from the operation that created this SingleResult then the error
  43. // will be returned along with the result. If there were no returned documents, ErrNoDocuments is
  44. // returned.
  45. func (sr *SingleResult) DecodeBytes() (bson.Raw, error) {
  46. if sr.err != nil {
  47. return sr.rdr, sr.err
  48. }
  49. if sr.err = sr.setRdrContents(); sr.err != nil {
  50. return nil, sr.err
  51. }
  52. return sr.rdr, nil
  53. }
  54. // setRdrContents will set the contents of rdr by iterating the underlying cursor if necessary.
  55. func (sr *SingleResult) setRdrContents() error {
  56. switch {
  57. case sr.err != nil:
  58. return sr.err
  59. case sr.rdr != nil:
  60. return nil
  61. case sr.cur != nil:
  62. defer sr.cur.Close(context.TODO())
  63. if !sr.cur.Next(context.TODO()) {
  64. if err := sr.cur.Err(); err != nil {
  65. return err
  66. }
  67. return ErrNoDocuments
  68. }
  69. sr.rdr = sr.cur.Current
  70. return nil
  71. }
  72. return ErrNoDocuments
  73. }
  74. // Err will return the error from the operation that created this SingleResult.
  75. // If there was no error, nil is returned.
  76. func (sr *SingleResult) Err() error {
  77. sr.err = sr.setRdrContents()
  78. return sr.err
  79. }