mongo 2.3.1 → 2.4.0.rc0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (170) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +2 -3
  4. data/lib/mongo/bulk_write.rb +8 -7
  5. data/lib/mongo/bulk_write/combineable.rb +4 -0
  6. data/lib/mongo/bulk_write/transformable.rb +17 -5
  7. data/lib/mongo/bulk_write/validatable.rb +1 -0
  8. data/lib/mongo/client.rb +3 -0
  9. data/lib/mongo/cluster.rb +8 -0
  10. data/lib/mongo/cluster/app_metadata.rb +135 -0
  11. data/lib/mongo/collection.rb +42 -10
  12. data/lib/mongo/collection/view.rb +15 -1
  13. data/lib/mongo/collection/view/aggregation.rb +5 -0
  14. data/lib/mongo/collection/view/builder/aggregation.rb +13 -3
  15. data/lib/mongo/collection/view/builder/find_command.rb +7 -21
  16. data/lib/mongo/collection/view/builder/map_reduce.rb +22 -5
  17. data/lib/mongo/collection/view/iterable.rb +1 -0
  18. data/lib/mongo/collection/view/map_reduce.rb +5 -0
  19. data/lib/mongo/collection/view/readable.rb +35 -14
  20. data/lib/mongo/collection/view/writable.rb +54 -23
  21. data/lib/mongo/cursor/builder/get_more_command.rb +2 -3
  22. data/lib/mongo/database.rb +10 -2
  23. data/lib/mongo/error.rb +2 -0
  24. data/lib/mongo/error/invalid_application_name.rb +38 -0
  25. data/lib/mongo/error/invalid_server_preference.rb +24 -3
  26. data/lib/mongo/error/unsupported_collation.rb +51 -0
  27. data/lib/mongo/index/view.rb +28 -15
  28. data/lib/mongo/operation.rb +6 -0
  29. data/lib/mongo/operation/commands.rb +3 -0
  30. data/lib/mongo/operation/commands/aggregate.rb +10 -10
  31. data/lib/mongo/operation/commands/create.rb +45 -0
  32. data/lib/mongo/operation/commands/drop.rb +45 -0
  33. data/lib/mongo/operation/commands/drop_database.rb +45 -0
  34. data/lib/mongo/operation/commands/map_reduce.rb +12 -1
  35. data/lib/mongo/operation/commands/parallel_scan.rb +1 -0
  36. data/lib/mongo/operation/read_preference.rb +9 -9
  37. data/lib/mongo/operation/specifiable.rb +34 -0
  38. data/lib/mongo/operation/takes_write_concern.rb +35 -0
  39. data/lib/mongo/operation/write/bulk/bulkable.rb +1 -1
  40. data/lib/mongo/operation/write/command/create_index.rb +6 -0
  41. data/lib/mongo/operation/write/command/drop_index.rb +6 -0
  42. data/lib/mongo/operation/write/command/insert.rb +1 -1
  43. data/lib/mongo/operation/write/command/update.rb +1 -0
  44. data/lib/mongo/operation/write/command/writable.rb +2 -2
  45. data/lib/mongo/operation/write/create_index.rb +2 -2
  46. data/lib/mongo/operation/write/create_user.rb +1 -1
  47. data/lib/mongo/operation/write/delete.rb +5 -1
  48. data/lib/mongo/operation/write/gle.rb +1 -1
  49. data/lib/mongo/operation/write/insert.rb +2 -2
  50. data/lib/mongo/operation/write/remove_user.rb +1 -1
  51. data/lib/mongo/operation/write/update.rb +5 -1
  52. data/lib/mongo/operation/write/update_user.rb +1 -1
  53. data/lib/mongo/operation/write/write_command_enabled.rb +10 -2
  54. data/lib/mongo/protocol/insert.rb +1 -2
  55. data/lib/mongo/protocol/query.rb +3 -7
  56. data/lib/mongo/server.rb +8 -3
  57. data/lib/mongo/server/connection.rb +17 -11
  58. data/lib/mongo/server/description.rb +22 -0
  59. data/lib/mongo/server/description/features.rb +2 -0
  60. data/lib/mongo/server/monitor.rb +5 -0
  61. data/lib/mongo/server/monitor/connection.rb +11 -0
  62. data/lib/mongo/server_selector/nearest.rb +9 -6
  63. data/lib/mongo/server_selector/primary.rb +4 -0
  64. data/lib/mongo/server_selector/primary_preferred.rb +7 -1
  65. data/lib/mongo/server_selector/secondary.rb +5 -0
  66. data/lib/mongo/server_selector/secondary_preferred.rb +7 -2
  67. data/lib/mongo/server_selector/selectable.rb +57 -10
  68. data/lib/mongo/socket/ssl.rb +1 -0
  69. data/lib/mongo/uri.rb +4 -0
  70. data/lib/mongo/version.rb +1 -1
  71. data/lib/mongo/write_concern.rb +1 -0
  72. data/mongo.gemspec +1 -1
  73. data/spec/mongo/auth/cr_spec.rb +7 -1
  74. data/spec/mongo/auth/ldap_spec.rb +7 -1
  75. data/spec/mongo/auth/scram_spec.rb +7 -1
  76. data/spec/mongo/auth/x509_spec.rb +7 -1
  77. data/spec/mongo/bulk_write_spec.rb +598 -5
  78. data/spec/mongo/client_spec.rb +47 -1
  79. data/spec/mongo/cluster/app_metadata_spec.rb +104 -0
  80. data/spec/mongo/cluster/topology/replica_set_spec.rb +14 -8
  81. data/spec/mongo/cluster/topology/sharded_spec.rb +9 -3
  82. data/spec/mongo/cluster/topology/single_spec.rb +10 -4
  83. data/spec/mongo/cluster_spec.rb +29 -0
  84. data/spec/mongo/collection/view/aggregation_spec.rb +139 -0
  85. data/spec/mongo/collection/view/builder/find_command_spec.rb +6 -243
  86. data/spec/mongo/collection/view/map_reduce_spec.rb +104 -0
  87. data/spec/mongo/collection/view/readable_spec.rb +83 -0
  88. data/spec/mongo/collection/view/writable_spec.rb +447 -1
  89. data/spec/mongo/collection/view_spec.rb +57 -0
  90. data/spec/mongo/collection_spec.rb +926 -101
  91. data/spec/mongo/crud_spec.rb +4 -5
  92. data/spec/mongo/database_spec.rb +99 -1
  93. data/spec/mongo/index/view_spec.rb +360 -31
  94. data/spec/mongo/max_staleness_spec.rb +108 -0
  95. data/spec/mongo/operation/read_preference_spec.rb +8 -8
  96. data/spec/mongo/operation/write/command/delete_spec.rb +1 -1
  97. data/spec/mongo/operation/write/command/insert_spec.rb +1 -1
  98. data/spec/mongo/operation/write/command/update_spec.rb +1 -1
  99. data/spec/mongo/server/connection_pool_spec.rb +3 -1
  100. data/spec/mongo/server/connection_spec.rb +17 -7
  101. data/spec/mongo/server/description/features_spec.rb +50 -0
  102. data/spec/mongo/server/description_spec.rb +9 -3
  103. data/spec/mongo/server_selection_spec.rb +5 -3
  104. data/spec/mongo/server_selector/nearest_spec.rb +73 -0
  105. data/spec/mongo/server_selector/primary_preferred_spec.rb +73 -0
  106. data/spec/mongo/server_selector/primary_spec.rb +36 -0
  107. data/spec/mongo/server_selector/secondary_preferred_spec.rb +73 -0
  108. data/spec/mongo/server_selector/secondary_spec.rb +73 -0
  109. data/spec/mongo/server_selector_spec.rb +53 -0
  110. data/spec/mongo/server_spec.rb +3 -1
  111. data/spec/mongo/uri_spec.rb +54 -0
  112. data/spec/mongo/write_concern_spec.rb +18 -0
  113. data/spec/spec_helper.rb +10 -0
  114. data/spec/support/authorization.rb +8 -1
  115. data/spec/support/crud.rb +15 -0
  116. data/spec/support/crud/read.rb +27 -19
  117. data/spec/support/crud/write.rb +28 -3
  118. data/spec/support/crud_tests/read/aggregate.yml +15 -3
  119. data/spec/support/crud_tests/read/count.yml +14 -3
  120. data/spec/support/crud_tests/read/distinct.yml +13 -1
  121. data/spec/support/crud_tests/read/find.yml +12 -2
  122. data/spec/support/crud_tests/write/deleteMany.yml +22 -1
  123. data/spec/support/crud_tests/write/deleteOne.yml +20 -1
  124. data/spec/support/crud_tests/write/findOneAndDelete.yml +27 -2
  125. data/spec/support/crud_tests/write/findOneAndReplace.yml +43 -14
  126. data/spec/support/crud_tests/write/findOneAndUpdate.yml +50 -8
  127. data/spec/support/crud_tests/write/replaceOne.yml +34 -10
  128. data/spec/support/crud_tests/write/updateMany.yml +42 -11
  129. data/spec/support/crud_tests/write/updateOne.yml +32 -7
  130. data/spec/support/max_staleness/ReplicaSetNoPrimary/DefaultNoMaxStaleness.yml +26 -0
  131. data/spec/support/max_staleness/ReplicaSetNoPrimary/Incompatible.yml +25 -0
  132. data/spec/support/max_staleness/ReplicaSetNoPrimary/LastUpdateTime.yml +33 -0
  133. data/spec/support/max_staleness/ReplicaSetNoPrimary/Nearest.yml +33 -0
  134. data/spec/support/max_staleness/ReplicaSetNoPrimary/Nearest2.yml +33 -0
  135. data/spec/support/max_staleness/ReplicaSetNoPrimary/PrimaryPreferred.yml +27 -0
  136. data/spec/support/max_staleness/ReplicaSetNoPrimary/PrimaryPreferred_tags.yml +36 -0
  137. data/spec/support/max_staleness/ReplicaSetNoPrimary/Secondary.yml +51 -0
  138. data/spec/support/max_staleness/ReplicaSetNoPrimary/SecondaryPreferred.yml +26 -0
  139. data/spec/support/max_staleness/ReplicaSetNoPrimary/SecondaryPreferred_tags.yml +51 -0
  140. data/spec/support/max_staleness/ReplicaSetWithPrimary/DefaultNoMaxStaleness.yml +26 -0
  141. data/spec/support/max_staleness/ReplicaSetWithPrimary/Incompatible.yml +25 -0
  142. data/spec/support/max_staleness/ReplicaSetWithPrimary/LastUpdateTime.yml +35 -0
  143. data/spec/support/max_staleness/ReplicaSetWithPrimary/MaxStalenessTooSmall.yml +25 -0
  144. data/spec/support/max_staleness/ReplicaSetWithPrimary/MaxStalenessWithModePrimary.yml +23 -0
  145. data/spec/support/max_staleness/ReplicaSetWithPrimary/Nearest.yml +33 -0
  146. data/spec/support/max_staleness/ReplicaSetWithPrimary/Nearest2.yml +33 -0
  147. data/spec/support/max_staleness/ReplicaSetWithPrimary/Nearest_tags.yml +36 -0
  148. data/spec/support/max_staleness/ReplicaSetWithPrimary/PrimaryPreferred.yml +27 -0
  149. data/spec/support/max_staleness/ReplicaSetWithPrimary/PrimaryPreferred_incompatible.yml +27 -0
  150. data/spec/support/max_staleness/ReplicaSetWithPrimary/SecondaryPreferred.yml +26 -0
  151. data/spec/support/max_staleness/ReplicaSetWithPrimary/SecondaryPreferred_tags.yml +59 -0
  152. data/spec/support/max_staleness/ReplicaSetWithPrimary/SecondaryPreferred_tags2.yml +43 -0
  153. data/spec/support/max_staleness/ReplicaSetWithPrimary/Secondary_tags.yml +59 -0
  154. data/spec/support/max_staleness/ReplicaSetWithPrimary/Secondary_tags2.yml +43 -0
  155. data/spec/support/max_staleness/ReplicaSetWithPrimary/ShortHeartbeartShortMaxStaleness.yml +29 -0
  156. data/spec/support/max_staleness/ReplicaSetWithPrimary/ShortHeartbeartShortMaxStaleness2.yml +29 -0
  157. data/spec/support/max_staleness/ReplicaSetWithPrimary/ZeroMaxStaleness.yml +27 -0
  158. data/spec/support/max_staleness/Sharded/Incompatible.yml +25 -0
  159. data/spec/support/max_staleness/Sharded/SmallMaxStaleness.yml +20 -0
  160. data/spec/support/max_staleness/Single/Incompatible.yml +18 -0
  161. data/spec/support/max_staleness/Single/SmallMaxStaleness.yml +20 -0
  162. data/spec/support/server_selection.rb +25 -0
  163. data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/Nearest_multiple.yml +27 -0
  164. data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/Secondary_multi_tags.yml +31 -0
  165. data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/Secondary_multi_tags2.yml +31 -0
  166. data/spec/support/server_selection/selection/ReplicaSetWithPrimary/read/Nearest_multiple.yml +34 -0
  167. data/spec/support/server_selection/selection/ReplicaSetWithPrimary/read/SecondaryPreferred_tags.yml +28 -0
  168. data/spec/support/shared/server_selector.rb +4 -3
  169. metadata +91 -6
  170. metadata.gz.sig +0 -0
@@ -56,7 +56,12 @@ module Mongo
56
56
  attr_reader :filter
57
57
 
58
58
  # Delegate necessary operations to the collection.
59
- def_delegators :collection, :client, :cluster, :database, :read_preference, :write_concern
59
+ def_delegators :collection,
60
+ :client,
61
+ :cluster,
62
+ :database,
63
+ :read_preference,
64
+ :write_concern
60
65
 
61
66
  # Delegate to the cluster for the next primary.
62
67
  def_delegators :cluster, :next_primary
@@ -127,6 +132,7 @@ module Mongo
127
132
  # once.
128
133
  # @option options :sort [ Hash ] The key and direction pairs used to sort the
129
134
  # results.
135
+ # @option options [ Hash ] :collation The collation to use.
130
136
  #
131
137
  # @since 2.0.0
132
138
  def initialize(collection, filter = {}, options = {})
@@ -150,6 +156,10 @@ module Mongo
150
156
 
151
157
  private
152
158
 
159
+ def write_concern
160
+ WriteConcern.get(options[:write] || options[:write_concern] || collection.write_concern)
161
+ end
162
+
153
163
  def initialize_copy(other)
154
164
  @collection = other.collection
155
165
  @options = other.options.dup
@@ -167,6 +177,10 @@ module Mongo
167
177
  View.new(collection, filter, options)
168
178
  end
169
179
 
180
+ def validate_collation!(server, opts)
181
+ raise Error::UnsupportedCollation.new if opts[:collation] && !server.features.collation_enabled?
182
+ end
183
+
170
184
  def view; self; end
171
185
  end
172
186
  end
@@ -115,8 +115,13 @@ module Mongo
115
115
  log_warn(REROUTE)
116
116
  server = cluster.next_primary(false)
117
117
  end
118
+ validate_collation!(server)
118
119
  initial_query_op.execute(server)
119
120
  end
121
+
122
+ def validate_collation!(server)
123
+ raise Error::UnsupportedCollation.new if @options[:collation] && !server.features.collation_enabled?
124
+ end
120
125
  end
121
126
  end
122
127
  end
@@ -30,10 +30,11 @@ module Mongo
30
30
  :allow_disk_use => 'allowDiskUse',
31
31
  :max_time_ms => 'maxTimeMS',
32
32
  :explain => 'explain',
33
- :bypass_document_validation => 'bypassDocumentValidation'
33
+ :bypass_document_validation => 'bypassDocumentValidation',
34
+ :collation => 'collation'
34
35
  ).freeze
35
36
 
36
- def_delegators :@view, :collection, :database, :read
37
+ def_delegators :@view, :collection, :database, :read, :write_concern
37
38
 
38
39
  # @return [ Array<Hash> ] pipeline The pipeline.
39
40
  attr_reader :pipeline
@@ -69,11 +70,20 @@ module Mongo
69
70
  #
70
71
  # @since 2.2.0
71
72
  def specification
72
- { selector: aggregation_command, db_name: database.name, read: read }
73
+ spec = {
74
+ selector: aggregation_command,
75
+ db_name: database.name,
76
+ read: read
77
+ }
78
+ write? ? spec.merge!(write_concern: write_concern) : spec
73
79
  end
74
80
 
75
81
  private
76
82
 
83
+ def write?
84
+ pipeline.any? { |operator| operator[:$out] || operator['$out'] }
85
+ end
86
+
77
87
  def aggregation_command
78
88
  command = BSON::Document.new(:aggregate => collection.name, :pipeline => pipeline)
79
89
  command[:cursor] = cursor if cursor
@@ -48,7 +48,8 @@ module Mongo
48
48
  no_cursor_timeout: 'noCursorTimeout',
49
49
  await_data: 'awaitData',
50
50
  allow_partial_results: 'allowPartialResults',
51
- read_concern: 'readConcern'
51
+ read_concern: 'readConcern',
52
+ collation: 'collation'
52
53
  ).freeze
53
54
 
54
55
  def_delegators :@view, :collection, :database, :filter, :options, :read
@@ -95,30 +96,15 @@ module Mongo
95
96
  def find_command
96
97
  document = BSON::Document.new('find' => collection.name, 'filter' => filter)
97
98
  command = Options::Mapper.transform_documents(convert_flags(options), MAPPINGS, document)
98
- convert_limit_and_batch_size(command)
99
- command
99
+ convert_negative_limit(command)
100
100
  end
101
101
 
102
- def convert_limit_and_batch_size(command)
103
- if command[:limit] && command[:limit] < 0 &&
104
- command[:batchSize] && command[:batchSize] < 0
105
-
106
- command[:limit] = command[:limit].abs
107
- command[:batchSize] = command[:limit].abs
102
+ def convert_negative_limit(command)
103
+ if command[:limit] && command[:limit] < 0
104
+ command['limit'] = command['limit'].abs
108
105
  command[:singleBatch] = true
109
-
110
- else
111
- [:limit, :batchSize].each do |opt|
112
- if command[opt]
113
- if command[opt] < 0
114
- command[opt] = command[opt].abs
115
- command[:singleBatch] = true
116
- elsif command[opt] == 0
117
- command.delete(opt)
118
- end
119
- end
120
- end
121
106
  end
107
+ command
122
108
  end
123
109
 
124
110
  def convert_flags(options)
@@ -32,10 +32,11 @@ module Mongo
32
32
  out: 'out',
33
33
  scope: 'scope',
34
34
  verbose: 'verbose',
35
- bypass_document_validation: 'bypassDocumentValidation'
35
+ bypass_document_validation: 'bypassDocumentValidation',
36
+ collation: 'collation'
36
37
  ).freeze
37
38
 
38
- def_delegators :@view, :collection, :database, :filter, :read
39
+ def_delegators :@view, :collection, :database, :filter, :read, :write_concern
39
40
 
40
41
  # @return [ String ] map The map function.
41
42
  attr_reader :map
@@ -77,7 +78,11 @@ module Mongo
77
78
  #
78
79
  # @since 2.2.0
79
80
  def command_specification
80
- { selector: find_command, db_name: database.name, read: read }
81
+ {
82
+ selector: find_command,
83
+ db_name: database.name,
84
+ read: read
85
+ }
81
86
  end
82
87
 
83
88
  # Get the specification for the document query after a map/reduce.
@@ -101,11 +106,23 @@ module Mongo
101
106
  #
102
107
  # @since 2.2.0
103
108
  def specification
104
- { selector: map_reduce_command, db_name: database.name, read: read }
109
+ spec = {
110
+ selector: map_reduce_command,
111
+ db_name: database.name,
112
+ read: read
113
+ }
114
+ write?(spec) ? spec.merge!(write_concern: write_concern) : spec
105
115
  end
106
116
 
107
117
  private
108
118
 
119
+ def write?(spec)
120
+ if out = spec[:selector][:out]
121
+ out.is_a?(String) ||
122
+ (out.respond_to?(:keys) && out.keys.first.to_s.downcase != View::MapReduce::INLINE)
123
+ end
124
+ end
125
+
109
126
  def find_command
110
127
  BSON::Document.new('find' => query_collection, 'filter' => {})
111
128
  end
@@ -119,8 +136,8 @@ module Mongo
119
136
  :out => { inline: 1 }
120
137
  )
121
138
  command[:readConcern] = collection.read_concern if collection.read_concern
122
- command.merge!(Options::Mapper.transform_documents(options, MAPPINGS))
123
139
  command.merge!(view.options)
140
+ command.merge!(Options::Mapper.transform_documents(options, MAPPINGS))
124
141
  command
125
142
  end
126
143
 
@@ -77,6 +77,7 @@ module Mongo
77
77
  end
78
78
 
79
79
  def send_initial_query(server)
80
+ validate_collation!(server, options)
80
81
  initial_query_op(server).execute(server)
81
82
  end
82
83
  end
@@ -211,6 +211,7 @@ module Mongo
211
211
  log_warn(REROUTE)
212
212
  server = cluster.next_primary(false)
213
213
  end
214
+ validate_collation!(server)
214
215
  result = initial_query_op.execute(server)
215
216
  inline? ? result : send_fetch_query(server)
216
217
  end
@@ -234,6 +235,10 @@ module Mongo
234
235
  def send_fetch_query(server)
235
236
  fetch_query_op(server).execute(server)
236
237
  end
238
+
239
+ def validate_collation!(server)
240
+ raise Error::UnsupportedCollation.new if options[:collation] && !server.features.collation_enabled?
241
+ end
237
242
  end
238
243
  end
239
244
  end
@@ -121,6 +121,7 @@ module Mongo
121
121
  # @option options :max_time_ms [ Integer ] The maximum amount of time to allow the
122
122
  # command to run.
123
123
  # @option options [ Hash ] :read The read preference options.
124
+ # @option options [ Hash ] :collation The collation to use.
124
125
  #
125
126
  # @return [ Integer ] The document count.
126
127
  #
@@ -132,9 +133,18 @@ module Mongo
132
133
  cmd[:limit] = options[:limit] if options[:limit]
133
134
  cmd[:maxTimeMS] = options[:max_time_ms] if options[:max_time_ms]
134
135
  cmd[:readConcern] = collection.read_concern if collection.read_concern
136
+ preference = ServerSelector.get(options[:read] || read_preference)
137
+ server = preference.select_server(cluster)
138
+ validate_collation!(server, options)
139
+ cmd[:collation] = options[:collation] if options[:collation]
135
140
  read_with_retry do
136
- options = options.merge(read: read) unless options[:read]
137
- database.command(cmd, options).n.to_i
141
+ Operation::Commands::Command.new({
142
+ :selector => cmd,
143
+ :db_name => database.name,
144
+ :options => { :limit => -1 },
145
+ :read => preference,
146
+ }).execute(server).n.to_i
147
+
138
148
  end
139
149
  end
140
150
 
@@ -149,6 +159,7 @@ module Mongo
149
159
  # @option options :max_time_ms [ Integer ] The maximum amount of time to allow the
150
160
  # command to run.
151
161
  # @option options [ Hash ] :read The read preference options.
162
+ # @option options [ Hash ] :collation The collation to use.
152
163
  #
153
164
  # @return [ Array<Object> ] The list of distinct values.
154
165
  #
@@ -159,9 +170,18 @@ module Mongo
159
170
  :query => filter }
160
171
  cmd[:maxTimeMS] = options[:max_time_ms] if options[:max_time_ms]
161
172
  cmd[:readConcern] = collection.read_concern if collection.read_concern
173
+ preference = ServerSelector.get(options[:read] || read_preference)
174
+ server = preference.select_server(cluster)
175
+ validate_collation!(server, options)
176
+ cmd[:collation] = options[:collation] if options[:collation]
162
177
  read_with_retry do
163
- options = options.merge(read: read) unless options[:read]
164
- database.command(cmd, options).first['values']
178
+ Operation::Commands::Command.new({
179
+ :selector => cmd,
180
+ :db_name => database.name,
181
+ :options => { :limit => -1 },
182
+ :read => preference
183
+ }).execute(server).first['values']
184
+
165
185
  end
166
186
  end
167
187
 
@@ -439,21 +459,22 @@ module Mongo
439
459
  options[:read] || read_preference
440
460
  end
441
461
 
442
- def parallel_scan(cursor_count)
462
+ def parallel_scan(cursor_count, options = {})
443
463
  server = read.select_server(cluster, false)
444
- Operation::Commands::ParallelScan.new(
445
- :coll_name => collection.name,
446
- :db_name => database.name,
447
- :cursor_count => cursor_count,
448
- :read_concern => collection.read_concern
449
- ).execute(server).cursor_ids.map do |cursor_id|
464
+ cmd = Operation::Commands::ParallelScan.new({
465
+ :coll_name => collection.name,
466
+ :db_name => database.name,
467
+ :cursor_count => cursor_count,
468
+ :read_concern => collection.read_concern
469
+ }.merge!(options))
470
+ cmd.execute(server).cursor_ids.map do |cursor_id|
450
471
  result = if server.features.find_command_enabled?
451
- Operation::Commands::GetMore.new({
472
+ Operation::Commands::GetMore.new({
452
473
  :selector => { :getMore => cursor_id, :collection => collection.name },
453
474
  :db_name => database.name
454
475
  }).execute(server)
455
- else
456
- Operation::Read::GetMore.new({
476
+ else
477
+ Operation::Read::GetMore.new({
457
478
  :to_return => 0,
458
479
  :cursor_id => cursor_id,
459
480
  :db_name => database.name,
@@ -35,11 +35,17 @@ module Mongo
35
35
  cmd[:fields] = projection if projection
36
36
  cmd[:sort] = sort if sort
37
37
  cmd[:maxTimeMS] = max_time_ms if max_time_ms
38
- wc = options[:write_concern] || (collection.write_concern &&
39
- collection.write_concern.options)
40
- cmd[:writeConcern] = wc if wc
38
+ cmd[:writeConcern] = write_concern.options if write_concern
39
+
40
+ server = next_primary
41
+ validate_collation!(server, options)
42
+ cmd[:collation] = options[:collation] if options[:collation]
43
+
41
44
  write_with_retry do
42
- database.command(cmd).first['value']
45
+ Operation::Commands::Command.new({
46
+ :selector => cmd,
47
+ :db_name => database.name
48
+ }).execute(server).first['value']
43
49
  end
44
50
  end
45
51
 
@@ -80,7 +86,7 @@ module Mongo
80
86
  # @option opts [ true, false ] :upsert Whether to upsert if the document doesn't exist.
81
87
  # @option opts [ true, false ] :bypass_document_validation Whether or
82
88
  # not to skip document level validation.
83
- # @option options [ Hash ] :write_concern The write concern options.
89
+ # @option opts [ Hash ] :write_concern The write concern options.
84
90
  # Defaults to the collection's write concern.
85
91
  #
86
92
  # @return [ BSON::Document ] The document.
@@ -95,13 +101,19 @@ module Mongo
95
101
  cmd[:upsert] = opts[:upsert] if opts[:upsert]
96
102
  cmd[:maxTimeMS] = max_time_ms if max_time_ms
97
103
  cmd[:bypassDocumentValidation] = !!opts[:bypass_document_validation]
98
- wc = options[:write_concern] || (collection.write_concern &&
99
- collection.write_concern.options)
100
- cmd[:writeConcern] = wc if wc
101
- write_with_retry do
102
- value = database.command(cmd).first['value']
103
- value unless value.nil? || value.empty?
104
+ cmd[:writeConcern] = write_concern.options if write_concern
105
+
106
+ server = next_primary
107
+ validate_collation!(server, options)
108
+ cmd[:collation] = options[:collation] if options[:collation]
109
+
110
+ value = write_with_retry do
111
+ Operation::Commands::Command.new({
112
+ :selector => cmd,
113
+ :db_name => database.name
114
+ }).execute(server).first['value']
104
115
  end
116
+ value unless value.nil? || value.empty?
105
117
  end
106
118
 
107
119
  # Remove documents from the collection.
@@ -109,11 +121,15 @@ module Mongo
109
121
  # @example Remove multiple documents from the collection.
110
122
  # collection_view.delete_many
111
123
  #
124
+ # @param [ Hash ] opts The options.
125
+ #
126
+ # @option opts [ Hash ] :collation The collation to use.
127
+ #
112
128
  # @return [ Result ] The response from the database.
113
129
  #
114
130
  # @since 2.0.0
115
- def delete_many
116
- remove(0)
131
+ def delete_many(opts = {})
132
+ remove(0, opts)
117
133
  end
118
134
 
119
135
  # Remove a document from the collection.
@@ -121,11 +137,15 @@ module Mongo
121
137
  # @example Remove a single document from the collection.
122
138
  # collection_view.delete_one
123
139
  #
140
+ # @param [ Hash ] opts The options.
141
+ #
142
+ # @option opts [ Hash ] :collation The collation to use.
143
+ #
124
144
  # @return [ Result ] The response from the database.
125
145
  #
126
146
  # @since 2.0.0
127
- def delete_one
128
- remove(1)
147
+ def delete_one(opts = {})
148
+ remove(1, opts)
129
149
  end
130
150
 
131
151
  # Replaces a single document in the database with the new document.
@@ -138,6 +158,7 @@ module Mongo
138
158
  #
139
159
  # @option opts [ true, false ] :upsert Whether to upsert if the
140
160
  # document doesn't exist.
161
+ # @option opts [ Hash ] :collation The collation to use.
141
162
  #
142
163
  # @return [ Result ] The response from the database.
143
164
  #
@@ -156,6 +177,7 @@ module Mongo
156
177
  #
157
178
  # @option opts [ true, false ] :upsert Whether to upsert if the
158
179
  # document doesn't exist.
180
+ # @option opts [ Hash ] :collation The collation to use.
159
181
  #
160
182
  # @return [ Result ] The response from the database.
161
183
  #
@@ -174,6 +196,7 @@ module Mongo
174
196
  #
175
197
  # @option opts [ true, false ] :upsert Whether to upsert if the
176
198
  # document doesn't exist.
199
+ # @option opts [ Hash ] :collation The collation to use.
177
200
  #
178
201
  # @return [ Result ] The response from the database.
179
202
  #
@@ -184,29 +207,37 @@ module Mongo
184
207
 
185
208
  private
186
209
 
187
- def remove(value)
210
+ def remove(value, opts)
211
+ server = next_primary
212
+ validate_collation!(server, opts)
213
+ delete_doc = { Operation::Q => filter, Operation::LIMIT => value }
214
+ delete_doc[:collation] = opts[:collation] if opts[:collation]
188
215
  write_with_retry do
189
216
  Operation::Write::Delete.new(
190
- :delete => { Operation::Q => filter, Operation::LIMIT => value },
217
+ :delete => delete_doc,
191
218
  :db_name => collection.database.name,
192
219
  :coll_name => collection.name,
193
220
  :write_concern => collection.write_concern
194
- ).execute(next_primary)
221
+ ).execute(server)
195
222
  end
196
223
  end
197
224
 
198
225
  def update(spec, multi, opts)
226
+ server = next_primary
227
+ validate_collation!(server, opts)
228
+ update_doc = { Operation::Q => filter,
229
+ Operation::U => spec,
230
+ Operation::MULTI => multi,
231
+ Operation::UPSERT => !!opts[:upsert] }
232
+ update_doc[:collation] = opts[:collation] if opts[:collation]
199
233
  write_with_retry do
200
234
  Operation::Write::Update.new(
201
- :update => { Operation::Q => filter,
202
- Operation::U => spec,
203
- Operation::MULTI => multi,
204
- Operation::UPSERT => !!opts[:upsert] },
235
+ :update => update_doc,
205
236
  :db_name => collection.database.name,
206
237
  :coll_name => collection.name,
207
238
  :write_concern => collection.write_concern,
208
239
  :bypass_document_validation => !!opts[:bypass_document_validation]
209
- ).execute(next_primary)
240
+ ).execute(server)
210
241
  end
211
242
  end
212
243
  end