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.

mongooptions.go 5.8 kB

5 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  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 options
  7. import (
  8. "fmt"
  9. "reflect"
  10. "strconv"
  11. "go.mongodb.org/mongo-driver/bson"
  12. "go.mongodb.org/mongo-driver/bson/bsoncodec"
  13. "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
  14. )
  15. // Collation allows users to specify language-specific rules for string comparison, such as
  16. // rules for lettercase and accent marks.
  17. type Collation struct {
  18. Locale string `bson:",omitempty"` // The locale
  19. CaseLevel bool `bson:",omitempty"` // The case level
  20. CaseFirst string `bson:",omitempty"` // The case ordering
  21. Strength int `bson:",omitempty"` // The number of comparision levels to use
  22. NumericOrdering bool `bson:",omitempty"` // Whether to order numbers based on numerical order and not collation order
  23. Alternate string `bson:",omitempty"` // Whether spaces and punctuation are considered base characters
  24. MaxVariable string `bson:",omitempty"` // Which characters are affected by alternate: "shifted"
  25. Normalization bool `bson:",omitempty"` // Causes text to be normalized into Unicode NFD
  26. Backwards bool `bson:",omitempty"` // Causes secondary differences to be considered in reverse order, as it is done in the French language
  27. }
  28. // ToDocument converts the Collation to a bson.Raw.
  29. func (co *Collation) ToDocument() bson.Raw {
  30. idx, doc := bsoncore.AppendDocumentStart(nil)
  31. if co.Locale != "" {
  32. doc = bsoncore.AppendStringElement(doc, "locale", co.Locale)
  33. }
  34. if co.CaseLevel {
  35. doc = bsoncore.AppendBooleanElement(doc, "caseLevel", true)
  36. }
  37. if co.CaseFirst != "" {
  38. doc = bsoncore.AppendStringElement(doc, "caseFirst", co.CaseFirst)
  39. }
  40. if co.Strength != 0 {
  41. doc = bsoncore.AppendInt32Element(doc, "strength", int32(co.Strength))
  42. }
  43. if co.NumericOrdering {
  44. doc = bsoncore.AppendBooleanElement(doc, "numericOrdering", true)
  45. }
  46. if co.Alternate != "" {
  47. doc = bsoncore.AppendStringElement(doc, "alternate", co.Alternate)
  48. }
  49. if co.MaxVariable != "" {
  50. doc = bsoncore.AppendStringElement(doc, "maxVariable", co.MaxVariable)
  51. }
  52. if co.Normalization {
  53. doc = bsoncore.AppendBooleanElement(doc, "normalization", true)
  54. }
  55. if co.Backwards {
  56. doc = bsoncore.AppendBooleanElement(doc, "backwards", true)
  57. }
  58. doc, _ = bsoncore.AppendDocumentEnd(doc, idx)
  59. return doc
  60. }
  61. // CursorType specifies whether a cursor should close when the last data is retrieved. See
  62. // NonTailable, Tailable, and TailableAwait.
  63. type CursorType int8
  64. const (
  65. // NonTailable specifies that a cursor should close after retrieving the last data.
  66. NonTailable CursorType = iota
  67. // Tailable specifies that a cursor should not close when the last data is retrieved and can be resumed later.
  68. Tailable
  69. // TailableAwait specifies that a cursor should not close when the last data is retrieved and
  70. // that it should block for a certain amount of time for new data before returning no data.
  71. TailableAwait
  72. )
  73. // ReturnDocument specifies whether a findAndUpdate operation should return the document as it was
  74. // before the update or as it is after the update.
  75. type ReturnDocument int8
  76. const (
  77. // Before specifies that findAndUpdate should return the document as it was before the update.
  78. Before ReturnDocument = iota
  79. // After specifies that findAndUpdate should return the document as it is after the update.
  80. After
  81. )
  82. // FullDocument specifies whether a change stream should include a copy of the entire document that was changed from
  83. // some time after the change occurred.
  84. type FullDocument string
  85. const (
  86. // Default does not include a document copy
  87. Default FullDocument = "default"
  88. // UpdateLookup includes a delta describing the changes to the document and a copy of the entire document that
  89. // was changed
  90. UpdateLookup FullDocument = "updateLookup"
  91. )
  92. // ArrayFilters is used to hold filters for the array filters CRUD option. If a registry is nil, bson.DefaultRegistry
  93. // will be used when converting the filter interfaces to BSON.
  94. type ArrayFilters struct {
  95. Registry *bsoncodec.Registry // The registry to use for converting filters. Defaults to bson.DefaultRegistry.
  96. Filters []interface{} // The filters to apply
  97. }
  98. // ToArray builds a []bson.Raw from the provided ArrayFilters.
  99. func (af *ArrayFilters) ToArray() ([]bson.Raw, error) {
  100. registry := af.Registry
  101. if registry == nil {
  102. registry = bson.DefaultRegistry
  103. }
  104. filters := make([]bson.Raw, 0, len(af.Filters))
  105. for _, f := range af.Filters {
  106. filter, err := bson.MarshalWithRegistry(registry, f)
  107. if err != nil {
  108. return nil, err
  109. }
  110. filters = append(filters, filter)
  111. }
  112. return filters, nil
  113. }
  114. // ToArrayDocument builds a BSON array for the array filters CRUD option. If the registry for af is nil,
  115. // bson.DefaultRegistry will be used when converting the filter interfaces to BSON.
  116. func (af *ArrayFilters) ToArrayDocument() (bson.Raw, error) {
  117. registry := af.Registry
  118. if registry == nil {
  119. registry = bson.DefaultRegistry
  120. }
  121. idx, arr := bsoncore.AppendArrayStart(nil)
  122. for i, f := range af.Filters {
  123. filter, err := bson.MarshalWithRegistry(registry, f)
  124. if err != nil {
  125. return nil, err
  126. }
  127. arr = bsoncore.AppendDocumentElement(arr, strconv.Itoa(i), filter)
  128. }
  129. arr, _ = bsoncore.AppendArrayEnd(arr, idx)
  130. return arr, nil
  131. }
  132. // MarshalError is returned when attempting to transform a value into a document
  133. // results in an error.
  134. type MarshalError struct {
  135. Value interface{}
  136. Err error
  137. }
  138. // Error implements the error interface.
  139. func (me MarshalError) Error() string {
  140. return fmt.Sprintf("cannot transform type %s to a bson.Raw", reflect.TypeOf(me.Value))
  141. }
  142. var defaultRegistry = bson.DefaultRegistry