mongo 2.3.1 → 2.4.0.rc0

Sign up to get free protection for your applications and to get access to all the features.
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