mongo 2.4.3 → 2.5.0.beta
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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +3 -2
- data.tar.gz.sig +0 -0
- data/lib/mongo.rb +3 -2
- data/lib/mongo/auth/cr.rb +6 -4
- data/lib/mongo/auth/cr/conversation.rb +33 -17
- data/lib/mongo/auth/ldap.rb +4 -2
- data/lib/mongo/auth/ldap/conversation.rb +19 -9
- data/lib/mongo/auth/scram.rb +7 -4
- data/lib/mongo/auth/scram/conversation.rb +62 -24
- data/lib/mongo/auth/user.rb +10 -0
- data/lib/mongo/auth/user/view.rb +44 -22
- data/lib/mongo/auth/x509.rb +4 -2
- data/lib/mongo/auth/x509/conversation.rb +19 -9
- data/lib/mongo/bulk_write.rb +33 -27
- data/lib/mongo/bulk_write/combineable.rb +5 -0
- data/lib/mongo/bulk_write/transformable.rb +2 -0
- data/lib/mongo/bulk_write/validatable.rb +4 -0
- data/lib/mongo/client.rb +123 -12
- data/lib/mongo/cluster.rb +52 -11
- data/lib/mongo/cluster/app_metadata.rb +8 -2
- data/lib/mongo/cluster/cursor_reaper.rb +0 -1
- data/lib/mongo/cluster/topology.rb +1 -1
- data/lib/mongo/collection.rb +114 -27
- data/lib/mongo/collection/view.rb +8 -2
- data/lib/mongo/collection/view/aggregation.rb +11 -7
- data/lib/mongo/collection/view/builder/aggregation.rb +5 -1
- data/lib/mongo/collection/view/builder/find_command.rb +5 -3
- data/lib/mongo/collection/view/builder/map_reduce.rb +11 -3
- data/lib/mongo/collection/view/builder/op_query.rb +1 -1
- data/lib/mongo/collection/view/change_stream.rb +160 -0
- data/lib/mongo/collection/view/change_stream/retryable.rb +57 -0
- data/lib/mongo/collection/view/iterable.rb +11 -10
- data/lib/mongo/collection/view/map_reduce.rb +22 -18
- data/lib/mongo/collection/view/readable.rb +51 -37
- data/lib/mongo/collection/view/writable.rb +72 -40
- data/lib/mongo/cursor.rb +25 -4
- data/lib/mongo/cursor/builder/get_more_command.rb +4 -2
- data/lib/mongo/database.rb +22 -11
- data/lib/mongo/database/view.rb +16 -12
- data/lib/mongo/error.rb +5 -0
- data/lib/mongo/error/invalid_session.rb +36 -0
- data/lib/mongo/error/missing_resume_token.rb +39 -0
- data/lib/mongo/error/operation_failure.rb +17 -0
- data/lib/mongo/error/parser.rb +3 -2
- data/lib/mongo/error/unknown_payload_type.rb +41 -0
- data/lib/mongo/error/unsupported_array_filters.rb +51 -0
- data/lib/mongo/error/unsupported_message_type.rb +23 -0
- data/lib/mongo/grid/fs_bucket.rb +5 -4
- data/lib/mongo/grid/stream/read.rb +3 -2
- data/lib/mongo/grid/stream/write.rb +2 -2
- data/lib/mongo/index/view.rb +35 -25
- data/lib/mongo/monitoring/event/secure.rb +14 -0
- data/lib/mongo/operation.rb +16 -0
- data/lib/mongo/operation/commands.rb +1 -0
- data/lib/mongo/operation/commands/aggregate.rb +9 -5
- data/lib/mongo/operation/commands/aggregate/result.rb +1 -1
- data/lib/mongo/operation/commands/collections_info.rb +6 -6
- data/lib/mongo/operation/commands/command.rb +2 -1
- data/lib/mongo/operation/commands/create.rb +6 -2
- data/lib/mongo/operation/commands/drop.rb +6 -2
- data/lib/mongo/operation/commands/drop_database.rb +6 -2
- data/lib/mongo/operation/commands/explain.rb +27 -0
- data/lib/mongo/operation/commands/explain/result.rb +52 -0
- data/lib/mongo/operation/commands/indexes.rb +1 -1
- data/lib/mongo/operation/commands/list_collections.rb +1 -1
- data/lib/mongo/operation/commands/list_collections/result.rb +1 -1
- data/lib/mongo/operation/commands/list_indexes.rb +1 -1
- data/lib/mongo/operation/commands/list_indexes/result.rb +1 -1
- data/lib/mongo/operation/commands/map_reduce.rb +8 -4
- data/lib/mongo/operation/commands/map_reduce/result.rb +13 -1
- data/lib/mongo/operation/commands/user_query.rb +1 -1
- data/lib/mongo/operation/commands/users_info.rb +6 -2
- data/lib/mongo/operation/executable.rb +4 -1
- data/lib/mongo/operation/read_preference.rb +10 -5
- data/lib/mongo/operation/result.rb +26 -2
- data/lib/mongo/operation/specifiable.rb +13 -1
- data/lib/mongo/operation/uses_command_op_msg.rb +47 -0
- data/lib/mongo/operation/write/bulk/bulkable.rb +4 -1
- data/lib/mongo/operation/write/bulk/insert/result.rb +4 -4
- data/lib/mongo/operation/write/command/create_index.rb +6 -1
- data/lib/mongo/operation/write/command/delete.rb +28 -4
- data/lib/mongo/operation/write/command/drop_index.rb +6 -1
- data/lib/mongo/operation/write/command/insert.rb +22 -18
- data/lib/mongo/operation/write/command/update.rb +24 -9
- data/lib/mongo/operation/write/command/writable.rb +14 -1
- data/lib/mongo/operation/write/insert.rb +4 -1
- data/lib/mongo/operation/write/insert/result.rb +2 -2
- data/lib/mongo/operation/write/update.rb +7 -1
- data/lib/mongo/operation/write/write_command_enabled.rb +20 -3
- data/lib/mongo/protocol.rb +3 -0
- data/lib/mongo/protocol/bit_vector.rb +2 -2
- data/lib/mongo/protocol/compressed.rb +135 -0
- data/lib/mongo/protocol/delete.rb +8 -6
- data/lib/mongo/protocol/get_more.rb +8 -6
- data/lib/mongo/protocol/insert.rb +8 -6
- data/lib/mongo/protocol/kill_cursors.rb +8 -6
- data/lib/mongo/protocol/message.rb +31 -3
- data/lib/mongo/protocol/msg.rb +172 -0
- data/lib/mongo/protocol/query.rb +26 -6
- data/lib/mongo/protocol/registry.rb +76 -0
- data/lib/mongo/protocol/reply.rb +10 -5
- data/lib/mongo/protocol/serializers.rb +224 -0
- data/lib/mongo/protocol/update.rb +8 -6
- data/lib/mongo/retryable.rb +4 -2
- data/lib/mongo/server.rb +6 -3
- data/lib/mongo/server/connectable.rb +1 -1
- data/lib/mongo/server/connection.rb +30 -8
- data/lib/mongo/server/description.rb +25 -1
- data/lib/mongo/server/description/features.rb +4 -1
- data/lib/mongo/server/monitor.rb +5 -0
- data/lib/mongo/server/monitor/connection.rb +50 -2
- data/lib/mongo/server_selector/nearest.rb +10 -4
- data/lib/mongo/server_selector/primary.rb +20 -0
- data/lib/mongo/server_selector/primary_preferred.rb +10 -4
- data/lib/mongo/server_selector/secondary.rb +10 -4
- data/lib/mongo/server_selector/secondary_preferred.rb +24 -4
- data/lib/mongo/session.rb +180 -0
- data/lib/mongo/session/server_session.rb +73 -0
- data/lib/mongo/session/session_pool.rb +161 -0
- data/lib/mongo/uri.rb +11 -0
- data/lib/mongo/version.rb +1 -1
- data/mongo.gemspec +2 -1
- data/spec/mongo/auth/cr_spec.rb +12 -0
- data/spec/mongo/auth/ldap_spec.rb +2 -0
- data/spec/mongo/auth/scram/conversation_spec.rb +6 -6
- data/spec/mongo/auth/scram_spec.rb +25 -1
- data/spec/mongo/auth/user/view_spec.rb +268 -76
- data/spec/mongo/auth/x509_spec.rb +2 -0
- data/spec/mongo/bulk_write_spec.rb +435 -5
- data/spec/mongo/client_spec.rb +356 -39
- data/spec/mongo/cluster/app_metadata_spec.rb +2 -2
- data/spec/mongo/cluster_spec.rb +176 -0
- data/spec/mongo/collection/view/aggregation_spec.rb +33 -12
- data/spec/mongo/collection/view/builder/find_command_spec.rb +46 -6
- data/spec/mongo/collection/view/change_stream_spec.rb +814 -0
- data/spec/mongo/collection/view/map_reduce_spec.rb +94 -17
- data/spec/mongo/collection/view/readable_spec.rb +3 -12
- data/spec/mongo/collection_spec.rb +1048 -42
- data/spec/mongo/cursor/builder/get_more_command_spec.rb +19 -0
- data/spec/mongo/cursor_spec.rb +2 -2
- data/spec/mongo/database_spec.rb +50 -1
- data/spec/mongo/grid/fs_bucket_spec.rb +225 -137
- data/spec/mongo/grid/stream/read_spec.rb +2 -2
- data/spec/mongo/index/view_spec.rb +146 -8
- data/spec/mongo/monitoring/event/secure_spec.rb +42 -0
- data/spec/mongo/operation/read/query_spec.rb +2 -1
- data/spec/mongo/operation/specifiable_spec.rb +2 -2
- data/spec/mongo/operation/write/command/delete_spec.rb +96 -13
- data/spec/mongo/operation/write/command/insert_spec.rb +111 -12
- data/spec/mongo/operation/write/command/update_spec.rb +93 -10
- data/spec/mongo/operation/write/delete_spec.rb +1 -1
- data/spec/mongo/operation/write/insert_spec.rb +1 -1
- data/spec/mongo/operation/write/update_spec.rb +1 -1
- data/spec/mongo/protocol/compressed_spec.rb +66 -0
- data/spec/mongo/protocol/delete_spec.rb +14 -0
- data/spec/mongo/protocol/get_more_spec.rb +14 -0
- data/spec/mongo/protocol/insert_spec.rb +14 -0
- data/spec/mongo/protocol/kill_cursors_spec.rb +14 -0
- data/spec/mongo/protocol/msg_spec.rb +499 -0
- data/spec/mongo/protocol/query_spec.rb +45 -0
- data/spec/mongo/protocol/registry_spec.rb +31 -0
- data/spec/mongo/protocol/reply_spec.rb +14 -0
- data/spec/mongo/protocol/update_spec.rb +14 -0
- data/spec/mongo/retryable_spec.rb +6 -2
- data/spec/mongo/sdam_spec.rb +4 -0
- data/spec/mongo/server/connection_spec.rb +4 -2
- data/spec/mongo/server/description_spec.rb +28 -1
- data/spec/mongo/session/server_session_spec.rb +16 -0
- data/spec/mongo/session/session_pool_spec.rb +194 -0
- data/spec/mongo/uri_spec.rb +31 -2
- data/spec/spec_helper.rb +104 -0
- data/spec/support/authorization.rb +6 -1
- data/spec/support/crud.rb +3 -1
- data/spec/support/crud/write.rb +6 -1
- data/spec/support/crud_tests/write/findOneAndUpdate-arrayFilters.yml +69 -0
- data/spec/support/crud_tests/write/updateMany-arrayFilters.yml +63 -0
- data/spec/support/crud_tests/write/updateOne-arrayFilters.yml +109 -0
- data/spec/support/sdam/rs/discover_arbiters.yml +1 -1
- data/spec/support/sdam/rs/discover_passives.yml +2 -2
- data/spec/support/sdam/rs/discover_primary.yml +1 -1
- data/spec/support/sdam/rs/discover_secondary.yml +1 -1
- data/spec/support/sdam/rs/discovery.yml +4 -4
- data/spec/support/sdam/rs/equal_electionids.yml +1 -0
- data/spec/support/sdam/rs/ghost_discovered.yml +1 -1
- data/spec/support/sdam/rs/hosts_differ_from_seeds.yml +1 -1
- data/spec/support/sdam/rs/ls_timeout.yml +88 -0
- data/spec/support/sdam/rs/member_reconfig.yml +2 -2
- data/spec/support/sdam/rs/member_standalone.yml +2 -2
- data/spec/support/sdam/rs/new_primary.yml +2 -2
- data/spec/support/sdam/rs/new_primary_new_electionid.yml +3 -0
- data/spec/support/sdam/rs/new_primary_new_setversion.yml +3 -0
- data/spec/support/sdam/rs/new_primary_wrong_set_name.yml +2 -2
- data/spec/support/sdam/rs/non_rs_member.yml +1 -1
- data/spec/support/sdam/rs/normalize_case.yml +1 -1
- data/spec/support/sdam/rs/null_election_id.yml +4 -0
- data/spec/support/sdam/rs/primary_becomes_standalone.yml +2 -2
- data/spec/support/sdam/rs/primary_changes_set_name.yml +2 -2
- data/spec/support/sdam/rs/primary_disconnect.yml +2 -2
- data/spec/support/sdam/rs/primary_disconnect_electionid.yml +5 -0
- data/spec/support/sdam/rs/primary_disconnect_setversion.yml +5 -0
- data/spec/support/sdam/rs/primary_hint_from_secondary_with_mismatched_me.yml +58 -0
- data/spec/support/sdam/rs/primary_reports_new_member.yml +4 -4
- data/spec/support/sdam/rs/primary_to_no_primary_mismatched_me.yml +2 -2
- data/spec/support/sdam/rs/primary_wrong_set_name.yml +1 -1
- data/spec/support/sdam/rs/response_from_removed.yml +2 -2
- data/spec/support/sdam/rs/rsother_discovered.yml +1 -1
- data/spec/support/sdam/rs/sec_not_auth.yml +1 -1
- data/spec/support/sdam/rs/secondary_wrong_set_name.yml +1 -1
- data/spec/support/sdam/rs/secondary_wrong_set_name_with_primary.yml +2 -2
- data/spec/support/sdam/rs/setversion_without_electionid.yml +2 -0
- data/spec/support/sdam/rs/stepdown_change_set_name.yml +2 -2
- data/spec/support/sdam/rs/unexpected_mongos.yml +1 -1
- data/spec/support/sdam/rs/use_setversion_without_electionid.yml +3 -0
- data/spec/support/sdam/rs/wrong_set_name.yml +1 -1
- data/spec/support/sdam/sharded/ls_timeout_mongos.yml +97 -0
- data/spec/support/sdam/sharded/mongos_disconnect.yml +3 -3
- data/spec/support/sdam/sharded/multiple_mongoses.yml +1 -1
- data/spec/support/sdam/sharded/non_mongos_removed.yml +1 -1
- data/spec/support/sdam/sharded/normalize_uri_case.yml +1 -1
- data/spec/support/sdam/single/direct_connection_external_ip.yml +1 -1
- data/spec/support/sdam/single/direct_connection_mongos.yml +1 -1
- data/spec/support/sdam/single/direct_connection_rsarbiter.yml +1 -1
- data/spec/support/sdam/single/direct_connection_rsprimary.yml +1 -1
- data/spec/support/sdam/single/direct_connection_rssecondary.yml +1 -1
- data/spec/support/sdam/single/direct_connection_slave.yml +1 -1
- data/spec/support/sdam/single/direct_connection_standalone.yml +1 -1
- data/spec/support/sdam/single/ls_timeout_standalone.yml +35 -0
- data/spec/support/sdam/single/not_ok_response.yml +1 -1
- data/spec/support/sdam/single/standalone_removed.yml +1 -1
- data/spec/support/sdam/single/unavailable_seed.yml +1 -1
- data/spec/support/server_discovery_and_monitoring.rb +4 -0
- data/spec/support/shared/session.rb +236 -0
- metadata +53 -15
- metadata.gz.sig +0 -0
@@ -43,6 +43,10 @@ describe Mongo::Collection::View::MapReduce do
|
|
43
43
|
{}
|
44
44
|
end
|
45
45
|
|
46
|
+
let(:map_reduce_spec) do
|
47
|
+
map_reduce.send(:map_reduce_spec, double('session'))
|
48
|
+
end
|
49
|
+
|
46
50
|
before do
|
47
51
|
authorized_collection.insert_many(documents)
|
48
52
|
end
|
@@ -66,6 +70,23 @@ describe Mongo::Collection::View::MapReduce do
|
|
66
70
|
end
|
67
71
|
end
|
68
72
|
|
73
|
+
context 'when provided a session' do
|
74
|
+
|
75
|
+
let(:view_options) do
|
76
|
+
{ session: session }
|
77
|
+
end
|
78
|
+
|
79
|
+
let(:operation) do
|
80
|
+
map_reduce.to_a
|
81
|
+
end
|
82
|
+
|
83
|
+
let(:client) do
|
84
|
+
authorized_client
|
85
|
+
end
|
86
|
+
|
87
|
+
it_behaves_like 'an operation using a session'
|
88
|
+
end
|
89
|
+
|
69
90
|
context 'when out is in the options' do
|
70
91
|
|
71
92
|
after do
|
@@ -134,19 +155,75 @@ describe Mongo::Collection::View::MapReduce do
|
|
134
155
|
expect(new_map_reduce.count).to eq(2)
|
135
156
|
end
|
136
157
|
|
137
|
-
context 'when
|
158
|
+
context 'when provided a session' do
|
159
|
+
|
160
|
+
let(:view_options) do
|
161
|
+
{ session: session }
|
162
|
+
end
|
163
|
+
|
164
|
+
let(:operation) do
|
165
|
+
new_map_reduce.to_a
|
166
|
+
end
|
167
|
+
|
168
|
+
let(:client) do
|
169
|
+
authorized_client
|
170
|
+
end
|
171
|
+
|
172
|
+
it_behaves_like 'an operation using a session'
|
173
|
+
end
|
174
|
+
|
175
|
+
context 'when the output collection is iterated' do
|
176
|
+
|
177
|
+
let(:view_options) do
|
178
|
+
{ session: session }
|
179
|
+
end
|
180
|
+
|
181
|
+
let(:session) do
|
182
|
+
client.start_session
|
183
|
+
end
|
184
|
+
|
185
|
+
let(:view) do
|
186
|
+
Mongo::Collection::View.new(client[TEST_COLL], selector, view_options)
|
187
|
+
end
|
188
|
+
|
189
|
+
let(:client) do
|
190
|
+
authorized_client.with(monitoring: true).tap do |cl|
|
191
|
+
cl.subscribe(Mongo::Monitoring::COMMAND, subscriber)
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
let(:subscriber) do
|
196
|
+
EventSubscriber.new
|
197
|
+
end
|
198
|
+
|
199
|
+
let(:find_command) do
|
200
|
+
subscriber.started_events[-1].command
|
201
|
+
end
|
202
|
+
|
203
|
+
before do
|
204
|
+
begin; client[TEST_COLL].create; rescue; end
|
205
|
+
begin; client.use('another-db')[TEST_COLL].create; rescue; end
|
206
|
+
end
|
207
|
+
|
208
|
+
it 'uses the session when iterating over the output collection', if: sessions_enabled? do
|
209
|
+
new_map_reduce.to_a
|
210
|
+
expect(find_command["lsid"]).to eq(BSON::Document.new(session.session_id))
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
context 'when another db is specified', if: (sessions_enabled? && !sharded? && !auth_enabled?) do
|
138
215
|
|
139
216
|
let(:new_map_reduce) do
|
140
217
|
map_reduce.out(db: 'another-db', replace: 'output_collection')
|
141
218
|
end
|
142
219
|
|
143
|
-
it 'iterates over the documents in the result' do
|
220
|
+
it 'iterates over the documents in the result', if: (sessions_enabled? && !sharded? && !auth_enabled?) do
|
144
221
|
new_map_reduce.each do |document|
|
145
222
|
expect(document[:value]).to_not be_nil
|
146
223
|
end
|
147
224
|
end
|
148
225
|
|
149
|
-
it 'fetches the results from the collection' do
|
226
|
+
it 'fetches the results from the collection', if: (sessions_enabled? && !sharded? && !auth_enabled?) do
|
150
227
|
expect(new_map_reduce.count).to eq(2)
|
151
228
|
end
|
152
229
|
end
|
@@ -168,7 +245,7 @@ describe Mongo::Collection::View::MapReduce do
|
|
168
245
|
expect(new_map_reduce.count).to eq(2)
|
169
246
|
end
|
170
247
|
|
171
|
-
context 'when another db is specified', if: (!auth_enabled? && list_command_enabled?) do
|
248
|
+
context 'when another db is specified', if: (!auth_enabled? && !sharded? && list_command_enabled?) do
|
172
249
|
|
173
250
|
let(:new_map_reduce) do
|
174
251
|
map_reduce.out(db: 'another-db', merge: 'output_collection')
|
@@ -202,7 +279,7 @@ describe Mongo::Collection::View::MapReduce do
|
|
202
279
|
expect(new_map_reduce.count).to eq(2)
|
203
280
|
end
|
204
281
|
|
205
|
-
context 'when another db is specified', if: (!auth_enabled? && list_command_enabled?) do
|
282
|
+
context 'when another db is specified', if: (!auth_enabled? && list_command_enabled? && !sharded?) do
|
206
283
|
|
207
284
|
let(:new_map_reduce) do
|
208
285
|
map_reduce.out(db: 'another-db', reduce: 'output_collection')
|
@@ -247,7 +324,7 @@ describe Mongo::Collection::View::MapReduce do
|
|
247
324
|
end
|
248
325
|
|
249
326
|
it 'includes the selector in the operation spec' do
|
250
|
-
expect(
|
327
|
+
expect(map_reduce_spec[:selector][:query]).to eq(selector)
|
251
328
|
end
|
252
329
|
end
|
253
330
|
|
@@ -264,7 +341,7 @@ describe Mongo::Collection::View::MapReduce do
|
|
264
341
|
end
|
265
342
|
|
266
343
|
it 'includes the selector in the operation spec' do
|
267
|
-
expect(
|
344
|
+
expect(map_reduce_spec[:selector][:query]).to eq(selector[:$query])
|
268
345
|
end
|
269
346
|
end
|
270
347
|
end
|
@@ -302,7 +379,7 @@ describe Mongo::Collection::View::MapReduce do
|
|
302
379
|
end
|
303
380
|
|
304
381
|
it 'includes the finalize function in the operation spec' do
|
305
|
-
expect(new_map_reduce.send(:map_reduce_spec)[:selector][:finalize]).to eq(finalize)
|
382
|
+
expect(new_map_reduce.send(:map_reduce_spec, double('session'))[:selector][:finalize]).to eq(finalize)
|
306
383
|
end
|
307
384
|
end
|
308
385
|
|
@@ -317,7 +394,7 @@ describe Mongo::Collection::View::MapReduce do
|
|
317
394
|
end
|
318
395
|
|
319
396
|
it 'includes the js mode value in the operation spec' do
|
320
|
-
expect(new_map_reduce.send(:map_reduce_spec)[:selector][:jsMode]).to be(true)
|
397
|
+
expect(new_map_reduce.send(:map_reduce_spec, double('session'))[:selector][:jsMode]).to be(true)
|
321
398
|
end
|
322
399
|
end
|
323
400
|
|
@@ -336,13 +413,13 @@ describe Mongo::Collection::View::MapReduce do
|
|
336
413
|
end
|
337
414
|
|
338
415
|
it 'includes the out value in the operation spec' do
|
339
|
-
expect(new_map_reduce.send(:map_reduce_spec)[:selector][:out]).to eq(location)
|
416
|
+
expect(new_map_reduce.send(:map_reduce_spec, double('session'))[:selector][:out]).to eq(location)
|
340
417
|
end
|
341
418
|
|
342
419
|
context 'when out is not defined' do
|
343
420
|
|
344
421
|
it 'defaults to inline' do
|
345
|
-
expect(
|
422
|
+
expect(map_reduce_spec[:selector][:out]).to eq('inline' => 1)
|
346
423
|
end
|
347
424
|
end
|
348
425
|
|
@@ -361,7 +438,7 @@ describe Mongo::Collection::View::MapReduce do
|
|
361
438
|
end
|
362
439
|
|
363
440
|
it 'includes the out value in the operation spec' do
|
364
|
-
expect(
|
441
|
+
expect(map_reduce_spec[:selector][:out]).to eq(location)
|
365
442
|
end
|
366
443
|
end
|
367
444
|
|
@@ -472,7 +549,7 @@ describe Mongo::Collection::View::MapReduce do
|
|
472
549
|
end
|
473
550
|
|
474
551
|
it 'includes the scope object in the operation spec' do
|
475
|
-
expect(new_map_reduce.send(:map_reduce_spec)[:selector][:scope]).to eq(object)
|
552
|
+
expect(new_map_reduce.send(:map_reduce_spec, double('session'))[:selector][:scope]).to eq(object)
|
476
553
|
end
|
477
554
|
end
|
478
555
|
|
@@ -491,7 +568,7 @@ describe Mongo::Collection::View::MapReduce do
|
|
491
568
|
end
|
492
569
|
|
493
570
|
it 'includes the verbose option in the operation spec' do
|
494
|
-
expect(new_map_reduce.send(:map_reduce_spec)[:selector][:verbose]).to eq(verbose)
|
571
|
+
expect(new_map_reduce.send(:map_reduce_spec, double('session'))[:selector][:verbose]).to eq(verbose)
|
495
572
|
end
|
496
573
|
end
|
497
574
|
|
@@ -506,7 +583,7 @@ describe Mongo::Collection::View::MapReduce do
|
|
506
583
|
end
|
507
584
|
|
508
585
|
it 'includes the limit in the operation spec' do
|
509
|
-
expect(
|
586
|
+
expect(map_reduce_spec[:selector][:limit]).to be(limit)
|
510
587
|
end
|
511
588
|
end
|
512
589
|
|
@@ -521,7 +598,7 @@ describe Mongo::Collection::View::MapReduce do
|
|
521
598
|
end
|
522
599
|
|
523
600
|
it 'includes the sort object in the operation spec' do
|
524
|
-
expect(
|
601
|
+
expect(map_reduce_spec[:selector][:sort][:name]).to eq(sort[:name])
|
525
602
|
end
|
526
603
|
end
|
527
604
|
|
@@ -533,7 +610,7 @@ describe Mongo::Collection::View::MapReduce do
|
|
533
610
|
|
534
611
|
it 'includes the read preference in the spec' do
|
535
612
|
allow(authorized_collection).to receive(:read_preference).and_return(read_preference)
|
536
|
-
expect(
|
613
|
+
expect(map_reduce_spec[:read]).to eq(read_preference)
|
537
614
|
end
|
538
615
|
end
|
539
616
|
|
@@ -1134,28 +1134,19 @@ describe Mongo::Collection::View::Readable do
|
|
1134
1134
|
|
1135
1135
|
describe '#read' do
|
1136
1136
|
|
1137
|
-
context 'when providing a hash' do
|
1138
|
-
|
1139
|
-
it 'converts to a read preference' do
|
1140
|
-
expect(view.read(:mode => :primary_preferred).read).to be_a(
|
1141
|
-
Mongo::ServerSelector::PrimaryPreferred
|
1142
|
-
)
|
1143
|
-
end
|
1144
|
-
end
|
1145
|
-
|
1146
1137
|
context 'when a read pref is specified' do
|
1147
1138
|
|
1148
1139
|
let(:options) do
|
1149
|
-
{ :read =>
|
1140
|
+
{ :read => { :mode => :secondary } }
|
1150
1141
|
end
|
1151
1142
|
|
1152
1143
|
let(:new_read) do
|
1153
|
-
|
1144
|
+
{ :mode => :secondary_preferred }
|
1154
1145
|
end
|
1155
1146
|
|
1156
1147
|
it 'sets the read preference' do
|
1157
1148
|
new_view = view.read(new_read)
|
1158
|
-
expect(new_view.read).to eq(new_read)
|
1149
|
+
expect(new_view.read).to eq(BSON::Document.new(new_read))
|
1159
1150
|
end
|
1160
1151
|
|
1161
1152
|
it 'returns a new View' do
|
@@ -123,7 +123,7 @@ describe Mongo::Collection do
|
|
123
123
|
end
|
124
124
|
|
125
125
|
it 'sets the new read options on the new collection' do
|
126
|
-
expect(new_collection.read_preference).to eq(
|
126
|
+
expect(new_collection.read_preference).to eq(new_options[:read])
|
127
127
|
end
|
128
128
|
|
129
129
|
context 'when the client has a server selection timeout setting' do
|
@@ -144,7 +144,7 @@ describe Mongo::Collection do
|
|
144
144
|
end
|
145
145
|
|
146
146
|
it 'sets the new read options on the new collection' do
|
147
|
-
expect(new_collection.read_preference).to eq(
|
147
|
+
expect(new_collection.read_preference).to eq(new_options[:read])
|
148
148
|
expect(new_collection.read_preference).not_to eq(client.read_preference)
|
149
149
|
end
|
150
150
|
end
|
@@ -156,7 +156,7 @@ describe Mongo::Collection do
|
|
156
156
|
end
|
157
157
|
|
158
158
|
it 'sets the new read options on the new collection' do
|
159
|
-
expect(new_collection.read_preference).to eq(
|
159
|
+
expect(new_collection.read_preference).to eq(new_options[:read])
|
160
160
|
end
|
161
161
|
|
162
162
|
it 'passes the server_selection_timeout setting to the cluster' do
|
@@ -182,7 +182,7 @@ describe Mongo::Collection do
|
|
182
182
|
context 'when the client has a write concern set' do
|
183
183
|
|
184
184
|
let(:client) do
|
185
|
-
Mongo::Client.new(ADDRESSES, TEST_OPTIONS.merge(write:
|
185
|
+
Mongo::Client.new(ADDRESSES, TEST_OPTIONS.merge(write: INVALID_WRITE_CONCERN))
|
186
186
|
end
|
187
187
|
|
188
188
|
it 'sets the new write options on the new collection' do
|
@@ -205,7 +205,7 @@ describe Mongo::Collection do
|
|
205
205
|
end
|
206
206
|
|
207
207
|
it 'sets the new read options on the new collection' do
|
208
|
-
expect(new_collection.read_preference).to eq(
|
208
|
+
expect(new_collection.read_preference).to eq(new_options[:read])
|
209
209
|
end
|
210
210
|
|
211
211
|
it 'sets the new write options on the new collection' do
|
@@ -230,7 +230,7 @@ describe Mongo::Collection do
|
|
230
230
|
end
|
231
231
|
|
232
232
|
it 'sets the new read options on the new collection' do
|
233
|
-
expect(new_collection.read_preference).to eq(
|
233
|
+
expect(new_collection.read_preference).to eq(new_options[:read])
|
234
234
|
expect(new_collection.read_preference).not_to be(client.read_preference)
|
235
235
|
end
|
236
236
|
end
|
@@ -250,6 +250,96 @@ describe Mongo::Collection do
|
|
250
250
|
end
|
251
251
|
end
|
252
252
|
|
253
|
+
describe '#read_preference' do
|
254
|
+
|
255
|
+
let(:collection) do
|
256
|
+
described_class.new(authorized_client.database, :users, options)
|
257
|
+
end
|
258
|
+
|
259
|
+
let(:options) { {} }
|
260
|
+
|
261
|
+
context 'when a read preference is set in the options' do
|
262
|
+
|
263
|
+
let(:options) do
|
264
|
+
{ read: { mode: :secondary } }
|
265
|
+
end
|
266
|
+
|
267
|
+
it 'returns the read preference' do
|
268
|
+
expect(collection.read_preference).to eq(options[:read])
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
context 'when a read preference is not set in the options' do
|
273
|
+
|
274
|
+
context 'when the database has a read preference set' do
|
275
|
+
|
276
|
+
let(:client) do
|
277
|
+
authorized_client.with(read: { mode: :secondary_preferred })
|
278
|
+
end
|
279
|
+
|
280
|
+
let(:collection) do
|
281
|
+
described_class.new(client.database, :users, options)
|
282
|
+
end
|
283
|
+
|
284
|
+
it 'returns the database read preference' do
|
285
|
+
expect(collection.read_preference).to eq(BSON::Document.new({ mode: :secondary_preferred }))
|
286
|
+
end
|
287
|
+
end
|
288
|
+
|
289
|
+
context 'when the database does not have a read preference' do
|
290
|
+
|
291
|
+
it 'returns nil' do
|
292
|
+
expect(collection.read_preference).to be_nil
|
293
|
+
end
|
294
|
+
end
|
295
|
+
end
|
296
|
+
end
|
297
|
+
|
298
|
+
describe '#server_selector' do
|
299
|
+
|
300
|
+
let(:collection) do
|
301
|
+
described_class.new(authorized_client.database, :users, options)
|
302
|
+
end
|
303
|
+
|
304
|
+
let(:options) { {} }
|
305
|
+
|
306
|
+
context 'when a read preference is set in the options' do
|
307
|
+
|
308
|
+
let(:options) do
|
309
|
+
{ read: { mode: :secondary } }
|
310
|
+
end
|
311
|
+
|
312
|
+
it 'returns the server selector for that read preference' do
|
313
|
+
expect(collection.server_selector).to be_a(Mongo::ServerSelector::Secondary)
|
314
|
+
end
|
315
|
+
end
|
316
|
+
|
317
|
+
context 'when a read preference is not set in the options' do
|
318
|
+
|
319
|
+
context 'when the database has a read preference set' do
|
320
|
+
|
321
|
+
let(:client) do
|
322
|
+
authorized_client.with(read: { mode: :secondary_preferred })
|
323
|
+
end
|
324
|
+
|
325
|
+
let(:collection) do
|
326
|
+
described_class.new(client.database, :users, options)
|
327
|
+
end
|
328
|
+
|
329
|
+
it 'returns the server selector for that read preference' do
|
330
|
+
expect(collection.server_selector).to be_a(Mongo::ServerSelector::SecondaryPreferred)
|
331
|
+
end
|
332
|
+
end
|
333
|
+
|
334
|
+
context 'when the database does not have a read preference' do
|
335
|
+
|
336
|
+
it 'returns a primary server selector' do
|
337
|
+
expect(collection.server_selector).to be_a(Mongo::ServerSelector::Primary)
|
338
|
+
end
|
339
|
+
end
|
340
|
+
end
|
341
|
+
end
|
342
|
+
|
253
343
|
describe '#capped?' do
|
254
344
|
|
255
345
|
let(:database) do
|
@@ -525,9 +615,40 @@ describe Mongo::Collection do
|
|
525
615
|
it_behaves_like 'a collection command with a collation option'
|
526
616
|
end
|
527
617
|
end
|
618
|
+
|
619
|
+
context 'when a session is provided' do
|
620
|
+
|
621
|
+
let(:collection) do
|
622
|
+
authorized_client[:specs]
|
623
|
+
end
|
624
|
+
|
625
|
+
let(:operation) do
|
626
|
+
collection.create(session: session)
|
627
|
+
end
|
628
|
+
|
629
|
+
let(:session) do
|
630
|
+
authorized_client.start_session
|
631
|
+
end
|
632
|
+
|
633
|
+
let(:client) do
|
634
|
+
authorized_client
|
635
|
+
end
|
636
|
+
|
637
|
+
let(:failed_operation) do
|
638
|
+
authorized_client[:specs, invalid: true].create(session: session)
|
639
|
+
end
|
640
|
+
|
641
|
+
after do
|
642
|
+
collection.drop
|
643
|
+
end
|
644
|
+
|
645
|
+
it_behaves_like 'an operation using a session'
|
646
|
+
it_behaves_like 'a failed operation using a session'
|
647
|
+
end
|
528
648
|
end
|
529
649
|
end
|
530
650
|
|
651
|
+
|
531
652
|
describe '#drop' do
|
532
653
|
|
533
654
|
let(:database) do
|
@@ -539,10 +660,37 @@ describe Mongo::Collection do
|
|
539
660
|
end
|
540
661
|
|
541
662
|
context 'when the collection exists' do
|
663
|
+
|
542
664
|
before do
|
543
665
|
collection.create
|
544
666
|
end
|
545
667
|
|
668
|
+
context 'when a session is provided' do
|
669
|
+
|
670
|
+
let(:operation) do
|
671
|
+
collection.drop(session: session)
|
672
|
+
end
|
673
|
+
|
674
|
+
let(:failed_operation) do
|
675
|
+
collection.with(write: INVALID_WRITE_CONCERN).drop(session: session)
|
676
|
+
end
|
677
|
+
|
678
|
+
let(:session) do
|
679
|
+
authorized_client.start_session
|
680
|
+
end
|
681
|
+
|
682
|
+
let(:client) do
|
683
|
+
authorized_client
|
684
|
+
end
|
685
|
+
|
686
|
+
after do
|
687
|
+
collection.drop
|
688
|
+
end
|
689
|
+
|
690
|
+
it_behaves_like 'an operation using a session'
|
691
|
+
it_behaves_like 'a failed operation using a session'
|
692
|
+
end
|
693
|
+
|
546
694
|
context 'when the collection does not have a write concern set' do
|
547
695
|
|
548
696
|
let!(:response) do
|
@@ -609,6 +757,19 @@ describe Mongo::Collection do
|
|
609
757
|
|
610
758
|
describe '#find' do
|
611
759
|
|
760
|
+
describe 'updating cluster time' do
|
761
|
+
|
762
|
+
let(:operation) do
|
763
|
+
client[TEST_COLL].find.first
|
764
|
+
end
|
765
|
+
|
766
|
+
let(:second_operation) do
|
767
|
+
client[TEST_COLL].find.first
|
768
|
+
end
|
769
|
+
|
770
|
+
it_behaves_like 'an operation updating cluster time'
|
771
|
+
end
|
772
|
+
|
612
773
|
context 'when provided a filter' do
|
613
774
|
|
614
775
|
let(:view) do
|
@@ -707,6 +868,28 @@ describe Mongo::Collection do
|
|
707
868
|
authorized_collection.find({}, options)
|
708
869
|
end
|
709
870
|
|
871
|
+
context 'when a session is provided' do
|
872
|
+
|
873
|
+
let(:operation) do
|
874
|
+
authorized_collection.find({}, session: session).to_a
|
875
|
+
end
|
876
|
+
|
877
|
+
let(:session) do
|
878
|
+
authorized_client.start_session
|
879
|
+
end
|
880
|
+
|
881
|
+
let(:failed_operation) do
|
882
|
+
authorized_collection.find({ '$._id' => 1 }, session: session).to_a
|
883
|
+
end
|
884
|
+
|
885
|
+
let(:client) do
|
886
|
+
authorized_client
|
887
|
+
end
|
888
|
+
|
889
|
+
it_behaves_like 'an operation using a session'
|
890
|
+
it_behaves_like 'a failed operation using a session'
|
891
|
+
end
|
892
|
+
|
710
893
|
context 'when provided :allow_partial_results' do
|
711
894
|
|
712
895
|
let(:options) do
|
@@ -859,6 +1042,28 @@ describe Mongo::Collection do
|
|
859
1042
|
expect(result.inserted_ids.size).to eq(2)
|
860
1043
|
end
|
861
1044
|
|
1045
|
+
context 'when a session is provided' do
|
1046
|
+
|
1047
|
+
let(:session) do
|
1048
|
+
authorized_client.start_session
|
1049
|
+
end
|
1050
|
+
|
1051
|
+
let(:operation) do
|
1052
|
+
authorized_collection.insert_many([{ name: 'test1' }, { name: 'test2' }], session: session)
|
1053
|
+
end
|
1054
|
+
|
1055
|
+
let(:failed_operation) do
|
1056
|
+
authorized_collection.insert_many([{ _id: 'test1' }, { _id: 'test1' }], session: session)
|
1057
|
+
end
|
1058
|
+
|
1059
|
+
let(:client) do
|
1060
|
+
authorized_client
|
1061
|
+
end
|
1062
|
+
|
1063
|
+
it_behaves_like 'an operation using a session'
|
1064
|
+
it_behaves_like 'a failed operation using a session'
|
1065
|
+
end
|
1066
|
+
|
862
1067
|
context 'when a document contains invalid keys' do
|
863
1068
|
|
864
1069
|
let(:docs) do
|
@@ -929,6 +1134,40 @@ describe Mongo::Collection do
|
|
929
1134
|
end
|
930
1135
|
end
|
931
1136
|
|
1137
|
+
context 'when the documents are sent with OP_MSG', if: op_msg_enabled? do
|
1138
|
+
|
1139
|
+
let(:client) do
|
1140
|
+
authorized_client.with(heartbeat_frequency: 100).tap do |cl|
|
1141
|
+
cl.subscribe(Mongo::Monitoring::COMMAND, subscriber)
|
1142
|
+
end
|
1143
|
+
end
|
1144
|
+
|
1145
|
+
let(:subscriber) do
|
1146
|
+
EventSubscriber.new
|
1147
|
+
end
|
1148
|
+
|
1149
|
+
let(:documents) do
|
1150
|
+
[{ '_id' => 1, 'name' => '1'*16777191 }, { '_id' => 'y' }]
|
1151
|
+
end
|
1152
|
+
|
1153
|
+
before do
|
1154
|
+
client[TEST_COLL].insert_many(documents)
|
1155
|
+
end
|
1156
|
+
|
1157
|
+
after do
|
1158
|
+
client.close
|
1159
|
+
end
|
1160
|
+
|
1161
|
+
let(:insert_events) do
|
1162
|
+
subscriber.started_events.select { |e| e.command_name == :insert }
|
1163
|
+
end
|
1164
|
+
|
1165
|
+
it 'sends the documents in one OP_MSG' do
|
1166
|
+
expect(insert_events.size).to eq(1)
|
1167
|
+
expect(insert_events[0].command['documents']).to eq(documents)
|
1168
|
+
end
|
1169
|
+
end
|
1170
|
+
|
932
1171
|
context 'when collection has a validator', if: find_command_enabled? do
|
933
1172
|
|
934
1173
|
around(:each) do |spec|
|
@@ -970,7 +1209,7 @@ describe Mongo::Collection do
|
|
970
1209
|
|
971
1210
|
let(:result3) do
|
972
1211
|
collection_with_validator.insert_many(
|
973
|
-
|
1212
|
+
[{ x: 1 }, { x: 2 }], :bypass_document_validation => true)
|
974
1213
|
end
|
975
1214
|
|
976
1215
|
it 'inserts successfully' do
|
@@ -983,6 +1222,19 @@ describe Mongo::Collection do
|
|
983
1222
|
|
984
1223
|
describe '#insert_one' do
|
985
1224
|
|
1225
|
+
describe 'updating cluster time' do
|
1226
|
+
|
1227
|
+
let(:operation) do
|
1228
|
+
client[TEST_COLL].insert_one({ name: 'testing' })
|
1229
|
+
end
|
1230
|
+
|
1231
|
+
let(:second_operation) do
|
1232
|
+
client[TEST_COLL].insert_one({ name: 'testing' })
|
1233
|
+
end
|
1234
|
+
|
1235
|
+
it_behaves_like 'an operation updating cluster time'
|
1236
|
+
end
|
1237
|
+
|
986
1238
|
let(:result) do
|
987
1239
|
authorized_collection.insert_one({ name: 'testing' })
|
988
1240
|
end
|
@@ -999,6 +1251,29 @@ describe Mongo::Collection do
|
|
999
1251
|
expect(result.inserted_id).to_not be_nil
|
1000
1252
|
end
|
1001
1253
|
|
1254
|
+
context 'when a session is provided' do
|
1255
|
+
|
1256
|
+
let(:session) do
|
1257
|
+
authorized_client.start_session
|
1258
|
+
end
|
1259
|
+
|
1260
|
+
let(:operation) do
|
1261
|
+
authorized_collection.insert_one({ name: 'testing' }, session: session)
|
1262
|
+
end
|
1263
|
+
|
1264
|
+
let(:failed_operation) do
|
1265
|
+
authorized_collection.insert_one({ _id: 'testing' })
|
1266
|
+
authorized_collection.insert_one({ _id: 'testing' }, session: session)
|
1267
|
+
end
|
1268
|
+
|
1269
|
+
let(:client) do
|
1270
|
+
authorized_client
|
1271
|
+
end
|
1272
|
+
|
1273
|
+
it_behaves_like 'an operation using a session'
|
1274
|
+
it_behaves_like 'a failed operation using a session'
|
1275
|
+
end
|
1276
|
+
|
1002
1277
|
context 'when the document contains invalid keys' do
|
1003
1278
|
|
1004
1279
|
let(:doc) do
|
@@ -1098,7 +1373,7 @@ describe Mongo::Collection do
|
|
1098
1373
|
|
1099
1374
|
let(:result3) do
|
1100
1375
|
collection_with_validator.insert_one(
|
1101
|
-
|
1376
|
+
{ x: 1 }, :bypass_document_validation => true)
|
1102
1377
|
end
|
1103
1378
|
|
1104
1379
|
it 'inserts successfully' do
|
@@ -1144,6 +1419,28 @@ describe Mongo::Collection do
|
|
1144
1419
|
expect(index_names).to include(*'name_1', '_id_')
|
1145
1420
|
end
|
1146
1421
|
|
1422
|
+
context 'when a session is provided' do
|
1423
|
+
|
1424
|
+
let(:session) do
|
1425
|
+
authorized_client.start_session
|
1426
|
+
end
|
1427
|
+
|
1428
|
+
let(:operation) do
|
1429
|
+
authorized_collection.indexes(batch_size: batch_size, session: session).collect { |i| i['name'] }
|
1430
|
+
end
|
1431
|
+
|
1432
|
+
let(:failed_operation) do
|
1433
|
+
authorized_collection.indexes(batch_size: -100, session: session).collect { |i| i['name'] }
|
1434
|
+
end
|
1435
|
+
|
1436
|
+
let(:client) do
|
1437
|
+
authorized_client
|
1438
|
+
end
|
1439
|
+
|
1440
|
+
it_behaves_like 'an operation using a session'
|
1441
|
+
it_behaves_like 'a failed operation using a session'
|
1442
|
+
end
|
1443
|
+
|
1147
1444
|
context 'when batch size is specified' do
|
1148
1445
|
|
1149
1446
|
let(:batch_size) { 1 }
|
@@ -1156,6 +1453,19 @@ describe Mongo::Collection do
|
|
1156
1453
|
|
1157
1454
|
describe '#aggregate' do
|
1158
1455
|
|
1456
|
+
describe 'updating cluster time' do
|
1457
|
+
|
1458
|
+
let(:operation) do
|
1459
|
+
client[TEST_COLL].aggregate([]).first
|
1460
|
+
end
|
1461
|
+
|
1462
|
+
let(:second_operation) do
|
1463
|
+
client[TEST_COLL].aggregate([]).first
|
1464
|
+
end
|
1465
|
+
|
1466
|
+
it_behaves_like 'an operation updating cluster time'
|
1467
|
+
end
|
1468
|
+
|
1159
1469
|
it 'returns an Aggregation object' do
|
1160
1470
|
expect(authorized_collection.aggregate([])).to be_a(Mongo::Collection::View::Aggregation)
|
1161
1471
|
end
|
@@ -1170,6 +1480,28 @@ describe Mongo::Collection do
|
|
1170
1480
|
expect(authorized_collection.aggregate([], options).options).to eq(BSON::Document.new(options))
|
1171
1481
|
end
|
1172
1482
|
|
1483
|
+
context 'when a session is provided' do
|
1484
|
+
|
1485
|
+
let(:session) do
|
1486
|
+
authorized_client.start_session
|
1487
|
+
end
|
1488
|
+
|
1489
|
+
let(:operation) do
|
1490
|
+
authorized_collection.aggregate([], session: session).to_a
|
1491
|
+
end
|
1492
|
+
|
1493
|
+
let(:failed_operation) do
|
1494
|
+
authorized_collection.aggregate([ { '$invalid' => 1 }], session: session).to_a
|
1495
|
+
end
|
1496
|
+
|
1497
|
+
let(:client) do
|
1498
|
+
authorized_client
|
1499
|
+
end
|
1500
|
+
|
1501
|
+
it_behaves_like 'an operation using a session'
|
1502
|
+
it_behaves_like 'a failed operation using a session'
|
1503
|
+
end
|
1504
|
+
|
1173
1505
|
context 'when a hint is provided' do
|
1174
1506
|
|
1175
1507
|
let(:options) do
|
@@ -1251,6 +1583,28 @@ describe Mongo::Collection do
|
|
1251
1583
|
expect(authorized_collection.count({}, limit: 5)).to eq(5)
|
1252
1584
|
end
|
1253
1585
|
|
1586
|
+
context 'when a session is provided' do
|
1587
|
+
|
1588
|
+
let(:session) do
|
1589
|
+
authorized_client.start_session
|
1590
|
+
end
|
1591
|
+
|
1592
|
+
let(:operation) do
|
1593
|
+
authorized_collection.count({}, session: session)
|
1594
|
+
end
|
1595
|
+
|
1596
|
+
let(:failed_operation) do
|
1597
|
+
authorized_collection.count({ '$._id' => 1 }, session: session)
|
1598
|
+
end
|
1599
|
+
|
1600
|
+
let(:client) do
|
1601
|
+
authorized_client
|
1602
|
+
end
|
1603
|
+
|
1604
|
+
it_behaves_like 'an operation using a session'
|
1605
|
+
it_behaves_like 'a failed operation using a session'
|
1606
|
+
end
|
1607
|
+
|
1254
1608
|
context 'when a collation is specified' do
|
1255
1609
|
|
1256
1610
|
let(:selector) do
|
@@ -1327,6 +1681,28 @@ describe Mongo::Collection do
|
|
1327
1681
|
it 'passes the options to the distinct command' do
|
1328
1682
|
expect(authorized_collection.distinct(:field, {}, max_time_ms: 100).sort).to eq([ 'test1', 'test2', 'test3' ])
|
1329
1683
|
end
|
1684
|
+
|
1685
|
+
context 'when a session is provided' do
|
1686
|
+
|
1687
|
+
let(:session) do
|
1688
|
+
authorized_client.start_session
|
1689
|
+
end
|
1690
|
+
|
1691
|
+
let(:operation) do
|
1692
|
+
authorized_collection.distinct(:field, {}, session: session)
|
1693
|
+
end
|
1694
|
+
|
1695
|
+
let(:failed_operation) do
|
1696
|
+
authorized_collection.distinct(:field, { '$._id' => 1 }, session: session)
|
1697
|
+
end
|
1698
|
+
|
1699
|
+
let(:client) do
|
1700
|
+
authorized_client
|
1701
|
+
end
|
1702
|
+
|
1703
|
+
it_behaves_like 'an operation using a session'
|
1704
|
+
it_behaves_like 'a failed operation using a session'
|
1705
|
+
end
|
1330
1706
|
end
|
1331
1707
|
|
1332
1708
|
context 'when a collation is specified' do
|
@@ -1401,9 +1777,9 @@ describe Mongo::Collection do
|
|
1401
1777
|
|
1402
1778
|
before do
|
1403
1779
|
authorized_collection.insert_many([
|
1404
|
-
|
1405
|
-
|
1406
|
-
|
1780
|
+
{ field: 'test1' },
|
1781
|
+
{ field: 'test1' },
|
1782
|
+
{ field: 'test1' }
|
1407
1783
|
])
|
1408
1784
|
end
|
1409
1785
|
|
@@ -1444,6 +1820,28 @@ describe Mongo::Collection do
|
|
1444
1820
|
end
|
1445
1821
|
end
|
1446
1822
|
|
1823
|
+
context 'when a session is provided' do
|
1824
|
+
|
1825
|
+
let(:session) do
|
1826
|
+
authorized_client.start_session
|
1827
|
+
end
|
1828
|
+
|
1829
|
+
let(:operation) do
|
1830
|
+
authorized_collection.delete_one({}, session: session)
|
1831
|
+
end
|
1832
|
+
|
1833
|
+
let(:failed_operation) do
|
1834
|
+
authorized_collection.delete_one({ '$._id' => 1}, session: session)
|
1835
|
+
end
|
1836
|
+
|
1837
|
+
let(:client) do
|
1838
|
+
authorized_client
|
1839
|
+
end
|
1840
|
+
|
1841
|
+
it_behaves_like 'an operation using a session'
|
1842
|
+
it_behaves_like 'a failed operation using a session'
|
1843
|
+
end
|
1844
|
+
|
1447
1845
|
context 'when a collation is provided' do
|
1448
1846
|
|
1449
1847
|
let(:selector) do
|
@@ -1581,6 +1979,28 @@ describe Mongo::Collection do
|
|
1581
1979
|
end
|
1582
1980
|
end
|
1583
1981
|
|
1982
|
+
context 'when a session is provided' do
|
1983
|
+
|
1984
|
+
let(:session) do
|
1985
|
+
authorized_client.start_session
|
1986
|
+
end
|
1987
|
+
|
1988
|
+
let(:operation) do
|
1989
|
+
authorized_collection.delete_many({}, session: session)
|
1990
|
+
end
|
1991
|
+
|
1992
|
+
let(:failed_operation) do
|
1993
|
+
authorized_collection.delete_many({ '$._id' => 1}, session: session)
|
1994
|
+
end
|
1995
|
+
|
1996
|
+
let(:client) do
|
1997
|
+
authorized_client
|
1998
|
+
end
|
1999
|
+
|
2000
|
+
it_behaves_like 'an operation using a session'
|
2001
|
+
it_behaves_like 'a failed operation using a session'
|
2002
|
+
end
|
2003
|
+
|
1584
2004
|
context 'when a collation is specified' do
|
1585
2005
|
|
1586
2006
|
let(:selector) do
|
@@ -1717,16 +2137,42 @@ describe Mongo::Collection do
|
|
1717
2137
|
}.to raise_error(Mongo::Error::OperationFailure)
|
1718
2138
|
end
|
1719
2139
|
|
1720
|
-
context 'when a
|
2140
|
+
context 'when a session is provided' do
|
1721
2141
|
|
1722
|
-
let(:
|
1723
|
-
authorized_collection.
|
2142
|
+
let(:cursors) do
|
2143
|
+
authorized_collection.parallel_scan(2, session: session)
|
1724
2144
|
end
|
1725
2145
|
|
1726
|
-
|
2146
|
+
let(:session) do
|
2147
|
+
authorized_client.start_session
|
2148
|
+
end
|
1727
2149
|
|
1728
|
-
|
1729
|
-
|
2150
|
+
let(:operation) do
|
2151
|
+
cursors.reduce(0) { |total, cursor| total + cursor.to_a.size }
|
2152
|
+
end
|
2153
|
+
|
2154
|
+
let(:failed_operation) do
|
2155
|
+
authorized_collection.parallel_scan(-2, session: session)
|
2156
|
+
end
|
2157
|
+
|
2158
|
+
let(:client) do
|
2159
|
+
authorized_client
|
2160
|
+
end
|
2161
|
+
|
2162
|
+
it_behaves_like 'an operation using a session'
|
2163
|
+
it_behaves_like 'a failed operation using a session'
|
2164
|
+
end
|
2165
|
+
|
2166
|
+
context 'when a read concern is provided', if: find_command_enabled? do
|
2167
|
+
|
2168
|
+
let(:result) do
|
2169
|
+
authorized_collection.with(options).parallel_scan(2)
|
2170
|
+
end
|
2171
|
+
|
2172
|
+
context 'when the read concern is valid' do
|
2173
|
+
|
2174
|
+
let(:options) do
|
2175
|
+
{ read_concern: { level: 'local' }}
|
1730
2176
|
end
|
1731
2177
|
|
1732
2178
|
it 'sends the read concern' do
|
@@ -1787,7 +2233,7 @@ describe Mongo::Collection do
|
|
1787
2233
|
context 'when the read concern is valid' do
|
1788
2234
|
|
1789
2235
|
let(:options) do
|
1790
|
-
{ max_time_ms:
|
2236
|
+
{ max_time_ms: 5 }
|
1791
2237
|
end
|
1792
2238
|
|
1793
2239
|
it 'sends the max time ms value' do
|
@@ -1966,7 +2412,7 @@ describe Mongo::Collection do
|
|
1966
2412
|
|
1967
2413
|
let(:result3) do
|
1968
2414
|
collection_with_validator.replace_one(
|
1969
|
-
|
2415
|
+
{ a: 1 }, { x: 1 }, :bypass_document_validation => true)
|
1970
2416
|
end
|
1971
2417
|
|
1972
2418
|
it 'replaces successfully' do
|
@@ -2074,6 +2520,36 @@ describe Mongo::Collection do
|
|
2074
2520
|
expect(authorized_collection.find(name: 'bang').count).to eq(1)
|
2075
2521
|
end
|
2076
2522
|
end
|
2523
|
+
|
2524
|
+
context 'when a session is provided' do
|
2525
|
+
|
2526
|
+
let(:selector) do
|
2527
|
+
{ name: 'BANG' }
|
2528
|
+
end
|
2529
|
+
|
2530
|
+
before do
|
2531
|
+
authorized_collection.insert_one(name: 'bang')
|
2532
|
+
end
|
2533
|
+
|
2534
|
+
let(:session) do
|
2535
|
+
authorized_client.start_session
|
2536
|
+
end
|
2537
|
+
|
2538
|
+
let(:operation) do
|
2539
|
+
authorized_collection.replace_one(selector, { name: 'doink' }, session: session)
|
2540
|
+
end
|
2541
|
+
|
2542
|
+
let(:failed_operation) do
|
2543
|
+
authorized_collection.replace_one({ '$._id' => 1 }, { name: 'doink' }, session: session)
|
2544
|
+
end
|
2545
|
+
|
2546
|
+
let(:client) do
|
2547
|
+
authorized_client
|
2548
|
+
end
|
2549
|
+
|
2550
|
+
it_behaves_like 'an operation using a session'
|
2551
|
+
it_behaves_like 'a failed operation using a session'
|
2552
|
+
end
|
2077
2553
|
end
|
2078
2554
|
|
2079
2555
|
describe '#update_many' do
|
@@ -2113,7 +2589,7 @@ describe Mongo::Collection do
|
|
2113
2589
|
|
2114
2590
|
let(:response) do
|
2115
2591
|
authorized_collection.update_many(selector, { '$set'=> { field: 'testing' } },
|
2116
|
-
|
2592
|
+
upsert: false)
|
2117
2593
|
end
|
2118
2594
|
|
2119
2595
|
let(:updated) do
|
@@ -2137,7 +2613,7 @@ describe Mongo::Collection do
|
|
2137
2613
|
|
2138
2614
|
let!(:response) do
|
2139
2615
|
authorized_collection.update_many(selector, { '$set'=> { field: 'testing' } },
|
2140
|
-
|
2616
|
+
upsert: true)
|
2141
2617
|
end
|
2142
2618
|
|
2143
2619
|
let(:updated) do
|
@@ -2176,6 +2652,106 @@ describe Mongo::Collection do
|
|
2176
2652
|
end
|
2177
2653
|
end
|
2178
2654
|
|
2655
|
+
context 'when arrayFilters is provided' do
|
2656
|
+
|
2657
|
+
let(:selector) do
|
2658
|
+
{ '$or' => [{ _id: 0 }, { _id: 1 }]}
|
2659
|
+
end
|
2660
|
+
|
2661
|
+
context 'when the server supports arrayFilters', if: array_filters_enabled? do
|
2662
|
+
|
2663
|
+
before do
|
2664
|
+
authorized_collection.insert_many([{
|
2665
|
+
_id: 0, x: [
|
2666
|
+
{ y: 1 },
|
2667
|
+
{ y: 2 },
|
2668
|
+
{ y: 3 }
|
2669
|
+
]
|
2670
|
+
},
|
2671
|
+
{
|
2672
|
+
_id: 1,
|
2673
|
+
x: [
|
2674
|
+
{ y: 3 },
|
2675
|
+
{ y: 2 },
|
2676
|
+
{ y: 1 }
|
2677
|
+
]
|
2678
|
+
}])
|
2679
|
+
end
|
2680
|
+
|
2681
|
+
let(:result) do
|
2682
|
+
authorized_collection.update_many(selector,
|
2683
|
+
{ '$set' => { 'x.$[i].y' => 5 } },
|
2684
|
+
options)
|
2685
|
+
end
|
2686
|
+
|
2687
|
+
context 'when a Symbol key is used' do
|
2688
|
+
|
2689
|
+
let(:options) do
|
2690
|
+
{ array_filters: [{ 'i.y' => 3 }] }
|
2691
|
+
end
|
2692
|
+
|
2693
|
+
it 'applies the arrayFilters' do
|
2694
|
+
expect(result.matched_count).to eq(2)
|
2695
|
+
expect(result.modified_count).to eq(2)
|
2696
|
+
|
2697
|
+
docs = authorized_collection.find(selector, sort: { _id: 1 }).to_a
|
2698
|
+
expect(docs[0]['x']).to eq ([{ 'y' => 1 }, { 'y' => 2 }, { 'y' => 5 }])
|
2699
|
+
expect(docs[1]['x']).to eq ([{ 'y' => 5 }, { 'y' => 2 }, { 'y' => 1 }])
|
2700
|
+
end
|
2701
|
+
end
|
2702
|
+
|
2703
|
+
context 'when a String key is used' do
|
2704
|
+
let(:options) do
|
2705
|
+
{ 'array_filters' => [{ 'i.y' => 3 }] }
|
2706
|
+
end
|
2707
|
+
|
2708
|
+
it 'applies the arrayFilters' do
|
2709
|
+
expect(result.matched_count).to eq(2)
|
2710
|
+
expect(result.modified_count).to eq(2)
|
2711
|
+
|
2712
|
+
docs = authorized_collection.find({}, sort: { _id: 1 }).to_a
|
2713
|
+
expect(docs[0]['x']).to eq ([{ 'y' => 1 }, { 'y' => 2 }, { 'y' => 5 }])
|
2714
|
+
expect(docs[1]['x']).to eq ([{ 'y' => 5 }, { 'y' => 2 }, { 'y' => 1 }])
|
2715
|
+
end
|
2716
|
+
end
|
2717
|
+
end
|
2718
|
+
|
2719
|
+
context 'when the server does not support arrayFilters', unless: array_filters_enabled? do
|
2720
|
+
|
2721
|
+
let(:result) do
|
2722
|
+
authorized_collection.update_many(selector,
|
2723
|
+
{ '$set' => { 'x.$[i].y' => 5 } },
|
2724
|
+
options)
|
2725
|
+
end
|
2726
|
+
|
2727
|
+
context 'when a Symbol key is used' do
|
2728
|
+
|
2729
|
+
let(:options) do
|
2730
|
+
{ array_filters: [{ 'i.y' => 3 }] }
|
2731
|
+
end
|
2732
|
+
|
2733
|
+
it 'raises an exception' do
|
2734
|
+
expect {
|
2735
|
+
result
|
2736
|
+
}.to raise_exception(Mongo::Error::UnsupportedArrayFilters)
|
2737
|
+
end
|
2738
|
+
end
|
2739
|
+
|
2740
|
+
context 'when a String key is used' do
|
2741
|
+
|
2742
|
+
let(:options) do
|
2743
|
+
{ 'array_filters' => [{ 'i.y' => 3 }] }
|
2744
|
+
end
|
2745
|
+
|
2746
|
+
it 'raises an exception' do
|
2747
|
+
expect {
|
2748
|
+
result
|
2749
|
+
}.to raise_exception(Mongo::Error::UnsupportedArrayFilters)
|
2750
|
+
end
|
2751
|
+
end
|
2752
|
+
end
|
2753
|
+
end
|
2754
|
+
|
2179
2755
|
context 'when the updates fail' do
|
2180
2756
|
|
2181
2757
|
let(:result) do
|
@@ -2208,7 +2784,7 @@ describe Mongo::Collection do
|
|
2208
2784
|
|
2209
2785
|
let(:result) do
|
2210
2786
|
collection_with_validator.update_many(
|
2211
|
-
|
2787
|
+
{ :a => { '$gt' => 0 } }, '$inc' => { :a => 1 } )
|
2212
2788
|
end
|
2213
2789
|
|
2214
2790
|
it 'updates successfully' do
|
@@ -2222,7 +2798,7 @@ describe Mongo::Collection do
|
|
2222
2798
|
|
2223
2799
|
let(:result2) do
|
2224
2800
|
collection_with_validator.update_many(
|
2225
|
-
|
2801
|
+
{ :a => { '$gt' => 0 } }, '$unset' => { :a => '' })
|
2226
2802
|
end
|
2227
2803
|
|
2228
2804
|
it 'raises OperationFailure' do
|
@@ -2236,8 +2812,8 @@ describe Mongo::Collection do
|
|
2236
2812
|
|
2237
2813
|
let(:result3) do
|
2238
2814
|
collection_with_validator.update_many(
|
2239
|
-
|
2240
|
-
|
2815
|
+
{ :a => { '$gt' => 0 } }, { '$unset' => { :a => '' } },
|
2816
|
+
:bypass_document_validation => true)
|
2241
2817
|
end
|
2242
2818
|
|
2243
2819
|
it 'updates successfully' do
|
@@ -2346,6 +2922,37 @@ describe Mongo::Collection do
|
|
2346
2922
|
expect(result.written_count).to eq(0)
|
2347
2923
|
end
|
2348
2924
|
end
|
2925
|
+
|
2926
|
+
context 'when a session is provided' do
|
2927
|
+
|
2928
|
+
let(:selector) do
|
2929
|
+
{ name: 'BANG' }
|
2930
|
+
end
|
2931
|
+
|
2932
|
+
let(:operation) do
|
2933
|
+
authorized_collection.update_many(selector, { '$set' => {other: 'doink'} }, session: session)
|
2934
|
+
end
|
2935
|
+
|
2936
|
+
before do
|
2937
|
+
authorized_collection.insert_one(name: 'bang')
|
2938
|
+
authorized_collection.insert_one(name: 'baNG')
|
2939
|
+
end
|
2940
|
+
|
2941
|
+
let(:session) do
|
2942
|
+
authorized_client.start_session
|
2943
|
+
end
|
2944
|
+
|
2945
|
+
let(:failed_operation) do
|
2946
|
+
authorized_collection.update_many({ '$._id' => 1 }, { '$set' => {other: 'doink'} }, session: session)
|
2947
|
+
end
|
2948
|
+
|
2949
|
+
let(:client) do
|
2950
|
+
authorized_client
|
2951
|
+
end
|
2952
|
+
|
2953
|
+
it_behaves_like 'an operation using a session'
|
2954
|
+
it_behaves_like 'a failed operation using a session'
|
2955
|
+
end
|
2349
2956
|
end
|
2350
2957
|
|
2351
2958
|
describe '#update_one' do
|
@@ -2385,7 +2992,7 @@ describe Mongo::Collection do
|
|
2385
2992
|
|
2386
2993
|
let(:response) do
|
2387
2994
|
authorized_collection.update_one(selector, { '$set'=> { field: 'testing' } },
|
2388
|
-
|
2995
|
+
upsert: false)
|
2389
2996
|
end
|
2390
2997
|
|
2391
2998
|
let(:updated) do
|
@@ -2409,7 +3016,7 @@ describe Mongo::Collection do
|
|
2409
3016
|
|
2410
3017
|
let!(:response) do
|
2411
3018
|
authorized_collection.update_one(selector, { '$set'=> { field: 'testing' } },
|
2412
|
-
|
3019
|
+
upsert: true)
|
2413
3020
|
end
|
2414
3021
|
|
2415
3022
|
let(:updated) do
|
@@ -2480,7 +3087,7 @@ describe Mongo::Collection do
|
|
2480
3087
|
|
2481
3088
|
let(:result) do
|
2482
3089
|
collection_with_validator.update_one(
|
2483
|
-
|
3090
|
+
{ :a => { '$gt' => 0 } }, '$inc' => { :a => 1 } )
|
2484
3091
|
end
|
2485
3092
|
|
2486
3093
|
it 'updates successfully' do
|
@@ -2494,7 +3101,7 @@ describe Mongo::Collection do
|
|
2494
3101
|
|
2495
3102
|
let(:result2) do
|
2496
3103
|
collection_with_validator.update_one(
|
2497
|
-
|
3104
|
+
{ :a => { '$gt' => 0 } }, '$unset' => { :a => '' })
|
2498
3105
|
end
|
2499
3106
|
|
2500
3107
|
it 'raises OperationFailure' do
|
@@ -2508,8 +3115,8 @@ describe Mongo::Collection do
|
|
2508
3115
|
|
2509
3116
|
let(:result3) do
|
2510
3117
|
collection_with_validator.update_one(
|
2511
|
-
|
2512
|
-
|
3118
|
+
{ :a => { '$gt' => 0 } }, { '$unset' => { :a => '' } },
|
3119
|
+
:bypass_document_validation => true)
|
2513
3120
|
end
|
2514
3121
|
|
2515
3122
|
it 'updates successfully' do
|
@@ -2616,6 +3223,148 @@ describe Mongo::Collection do
|
|
2616
3223
|
expect(result.written_count).to eq(0)
|
2617
3224
|
end
|
2618
3225
|
end
|
3226
|
+
|
3227
|
+
|
3228
|
+
context 'when arrayFilters is provided' do
|
3229
|
+
|
3230
|
+
let(:selector) do
|
3231
|
+
{ _id: 0}
|
3232
|
+
end
|
3233
|
+
|
3234
|
+
context 'when the server supports arrayFilters', if: array_filters_enabled? do
|
3235
|
+
|
3236
|
+
before do
|
3237
|
+
authorized_collection.insert_one(_id: 0, x: [{ y: 1 }, { y: 2 }, {y: 3 }])
|
3238
|
+
end
|
3239
|
+
|
3240
|
+
let(:result) do
|
3241
|
+
authorized_collection.update_one(selector,
|
3242
|
+
{ '$set' => { 'x.$[i].y' => 5 } },
|
3243
|
+
options)
|
3244
|
+
end
|
3245
|
+
|
3246
|
+
context 'when a Symbol key is used' do
|
3247
|
+
|
3248
|
+
let(:options) do
|
3249
|
+
{ array_filters: [{ 'i.y' => 3 }] }
|
3250
|
+
end
|
3251
|
+
|
3252
|
+
it 'applies the arrayFilters' do
|
3253
|
+
expect(result.matched_count).to eq(1)
|
3254
|
+
expect(result.modified_count).to eq(1)
|
3255
|
+
expect(authorized_collection.find(selector).first['x'].last['y']).to eq(5)
|
3256
|
+
end
|
3257
|
+
end
|
3258
|
+
|
3259
|
+
context 'when a String key is used' do
|
3260
|
+
|
3261
|
+
let(:options) do
|
3262
|
+
{ 'array_filters' => [{ 'i.y' => 3 }] }
|
3263
|
+
end
|
3264
|
+
|
3265
|
+
it 'applies the arrayFilters' do
|
3266
|
+
expect(result.matched_count).to eq(1)
|
3267
|
+
expect(result.modified_count).to eq(1)
|
3268
|
+
expect(authorized_collection.find(selector).first['x'].last['y']).to eq(5)
|
3269
|
+
end
|
3270
|
+
end
|
3271
|
+
end
|
3272
|
+
|
3273
|
+
context 'when the server does not support arrayFilters', unless: array_filters_enabled? do
|
3274
|
+
|
3275
|
+
let(:result) do
|
3276
|
+
authorized_collection.update_one(selector,
|
3277
|
+
{ '$set' => { 'x.$[i].y' => 5 } },
|
3278
|
+
options)
|
3279
|
+
end
|
3280
|
+
|
3281
|
+
context 'when a Symbol key is used' do
|
3282
|
+
|
3283
|
+
let(:options) do
|
3284
|
+
{ array_filters: [{ 'i.y' => 3 }] }
|
3285
|
+
end
|
3286
|
+
|
3287
|
+
it 'raises an exception' do
|
3288
|
+
expect {
|
3289
|
+
result
|
3290
|
+
}.to raise_exception(Mongo::Error::UnsupportedArrayFilters)
|
3291
|
+
end
|
3292
|
+
end
|
3293
|
+
|
3294
|
+
context 'when a String key is used' do
|
3295
|
+
|
3296
|
+
let(:options) do
|
3297
|
+
{ 'array_filters' => [{ 'i.y' => 3 }] }
|
3298
|
+
end
|
3299
|
+
|
3300
|
+
it 'raises an exception' do
|
3301
|
+
expect {
|
3302
|
+
result
|
3303
|
+
}.to raise_exception(Mongo::Error::UnsupportedArrayFilters)
|
3304
|
+
end
|
3305
|
+
end
|
3306
|
+
end
|
3307
|
+
end
|
3308
|
+
|
3309
|
+
context 'when the documents are sent with OP_MSG', if: op_msg_enabled? do
|
3310
|
+
|
3311
|
+
let(:client) do
|
3312
|
+
authorized_client.with(heartbeat_frequency: 100).tap do |cl|
|
3313
|
+
cl.subscribe(Mongo::Monitoring::COMMAND, subscriber)
|
3314
|
+
end
|
3315
|
+
end
|
3316
|
+
|
3317
|
+
let(:subscriber) do
|
3318
|
+
EventSubscriber.new
|
3319
|
+
end
|
3320
|
+
|
3321
|
+
let(:documents) do
|
3322
|
+
[{ '_id' => 1, 'name' => '1'*16777191 }, { '_id' => 'y' }]
|
3323
|
+
end
|
3324
|
+
|
3325
|
+
before do
|
3326
|
+
authorized_collection.insert_many([{ field: 'test1' }, { field: 'test1' }])
|
3327
|
+
client[TEST_COLL].update_one({ a: 1 }, {'$set' => { 'name' => '1'*16777149 }})
|
3328
|
+
end
|
3329
|
+
|
3330
|
+
after do
|
3331
|
+
client.close
|
3332
|
+
end
|
3333
|
+
|
3334
|
+
let(:update_events) do
|
3335
|
+
subscriber.started_events.select { |e| e.command_name == :update }
|
3336
|
+
end
|
3337
|
+
|
3338
|
+
it 'sends the documents in one OP_MSG' do
|
3339
|
+
expect(update_events.size).to eq(1)
|
3340
|
+
end
|
3341
|
+
end
|
3342
|
+
|
3343
|
+
context 'when a session is provided' do
|
3344
|
+
|
3345
|
+
before do
|
3346
|
+
authorized_collection.insert_many([{ field: 'test1' }, { field: 'test1' }])
|
3347
|
+
end
|
3348
|
+
|
3349
|
+
let(:session) do
|
3350
|
+
authorized_client.start_session
|
3351
|
+
end
|
3352
|
+
|
3353
|
+
let(:operation) do
|
3354
|
+
authorized_collection.update_one({ field: 'test' }, { '$set'=> { field: 'testing' } }, session: session)
|
3355
|
+
end
|
3356
|
+
|
3357
|
+
let(:failed_operation) do
|
3358
|
+
authorized_collection.update_one({ '$._id' => 1 }, { '$set'=> { field: 'testing' } }, session: session)
|
3359
|
+
end
|
3360
|
+
|
3361
|
+
let(:client) do
|
3362
|
+
authorized_client
|
3363
|
+
end
|
3364
|
+
|
3365
|
+
it_behaves_like 'an operation using a session'
|
3366
|
+
it_behaves_like 'a failed operation using a session'
|
3367
|
+
end
|
2619
3368
|
end
|
2620
3369
|
|
2621
3370
|
describe '#find_one_and_delete' do
|
@@ -2630,6 +3379,28 @@ describe Mongo::Collection do
|
|
2630
3379
|
|
2631
3380
|
context 'when a matching document is found' do
|
2632
3381
|
|
3382
|
+
context 'when a session is provided' do
|
3383
|
+
|
3384
|
+
let(:operation) do
|
3385
|
+
authorized_collection.find_one_and_delete(selector, session: session)
|
3386
|
+
end
|
3387
|
+
|
3388
|
+
let(:failed_operation) do
|
3389
|
+
authorized_collection.find_one_and_delete({ '$._id' => 1 }, session: session)
|
3390
|
+
end
|
3391
|
+
|
3392
|
+
let(:session) do
|
3393
|
+
authorized_client.start_session
|
3394
|
+
end
|
3395
|
+
|
3396
|
+
let(:client) do
|
3397
|
+
authorized_client
|
3398
|
+
end
|
3399
|
+
|
3400
|
+
it_behaves_like 'an operation using a session'
|
3401
|
+
it_behaves_like 'a failed operation using a session'
|
3402
|
+
end
|
3403
|
+
|
2633
3404
|
context 'when no options are provided' do
|
2634
3405
|
|
2635
3406
|
let!(:document) do
|
@@ -2830,6 +3601,28 @@ describe Mongo::Collection do
|
|
2830
3601
|
end
|
2831
3602
|
end
|
2832
3603
|
|
3604
|
+
context 'when a session is provided' do
|
3605
|
+
|
3606
|
+
let(:operation) do
|
3607
|
+
authorized_collection.find_one_and_update(selector, { '$set' => { field: 'testing' }}, session: session)
|
3608
|
+
end
|
3609
|
+
|
3610
|
+
let(:failed_operation) do
|
3611
|
+
authorized_collection.find_one_and_update({ '$._id' => 1 }, { '$set' => { field: 'testing' }}, session: session)
|
3612
|
+
end
|
3613
|
+
|
3614
|
+
let(:session) do
|
3615
|
+
authorized_client.start_session
|
3616
|
+
end
|
3617
|
+
|
3618
|
+
let(:client) do
|
3619
|
+
authorized_client
|
3620
|
+
end
|
3621
|
+
|
3622
|
+
it_behaves_like 'an operation using a session'
|
3623
|
+
it_behaves_like 'a failed operation using a session'
|
3624
|
+
end
|
3625
|
+
|
2833
3626
|
context 'when no options are provided' do
|
2834
3627
|
|
2835
3628
|
let(:document) do
|
@@ -2979,7 +3772,7 @@ describe Mongo::Collection do
|
|
2979
3772
|
|
2980
3773
|
let(:result) do
|
2981
3774
|
collection_with_validator.find_one_and_update(
|
2982
|
-
|
3775
|
+
{ a: 1 }, { '$inc' => { :a => 1 } }, :return_document => :after)
|
2983
3776
|
end
|
2984
3777
|
|
2985
3778
|
it 'updates successfully' do
|
@@ -2993,7 +3786,7 @@ describe Mongo::Collection do
|
|
2993
3786
|
|
2994
3787
|
let(:result2) do
|
2995
3788
|
collection_with_validator.find_one_and_update(
|
2996
|
-
|
3789
|
+
{ a: 1 }, { '$unset' => { :a => '' } }, :return_document => :after)
|
2997
3790
|
end
|
2998
3791
|
|
2999
3792
|
it 'raises OperationFailure' do
|
@@ -3007,9 +3800,9 @@ describe Mongo::Collection do
|
|
3007
3800
|
|
3008
3801
|
let(:result3) do
|
3009
3802
|
collection_with_validator.find_one_and_update(
|
3010
|
-
|
3011
|
-
|
3012
|
-
|
3803
|
+
{ a: 1 }, { '$unset' => { :a => '' } },
|
3804
|
+
:bypass_document_validation => true,
|
3805
|
+
:return_document => :after)
|
3013
3806
|
end
|
3014
3807
|
|
3015
3808
|
it 'updates successfully' do
|
@@ -3024,8 +3817,8 @@ describe Mongo::Collection do
|
|
3024
3817
|
it 'uses the write concern' do
|
3025
3818
|
expect {
|
3026
3819
|
authorized_collection.find_one_and_update(selector,
|
3027
|
-
|
3028
|
-
|
3820
|
+
{ '$set' => { field: 'testing' }},
|
3821
|
+
write_concern: { w: 2 })
|
3029
3822
|
}.to raise_error(Mongo::Error::OperationFailure)
|
3030
3823
|
end
|
3031
3824
|
end
|
@@ -3114,6 +3907,86 @@ describe Mongo::Collection do
|
|
3114
3907
|
expect(result).to be_nil
|
3115
3908
|
end
|
3116
3909
|
end
|
3910
|
+
|
3911
|
+
context 'when arrayFilters is provided' do
|
3912
|
+
|
3913
|
+
let(:selector) do
|
3914
|
+
{ _id: 0 }
|
3915
|
+
end
|
3916
|
+
|
3917
|
+
context 'when the server supports arrayFilters', if: array_filters_enabled? do
|
3918
|
+
|
3919
|
+
before do
|
3920
|
+
authorized_collection.insert_one(_id: 0, x: [{ y: 1 }, { y: 2 }, { y: 3 }])
|
3921
|
+
end
|
3922
|
+
|
3923
|
+
let(:result) do
|
3924
|
+
authorized_collection.find_one_and_update(selector,
|
3925
|
+
{ '$set' => { 'x.$[i].y' => 5 } },
|
3926
|
+
options)
|
3927
|
+
end
|
3928
|
+
|
3929
|
+
context 'when a Symbol key is used' do
|
3930
|
+
|
3931
|
+
let(:options) do
|
3932
|
+
{ array_filters: [{ 'i.y' => 3 }] }
|
3933
|
+
end
|
3934
|
+
|
3935
|
+
|
3936
|
+
it 'applies the arrayFilters' do
|
3937
|
+
expect(result['x']).to eq([{ 'y' => 1 }, { 'y' => 2 }, { 'y' => 3 }])
|
3938
|
+
expect(authorized_collection.find(selector).first['x'].last['y']).to eq(5)
|
3939
|
+
end
|
3940
|
+
end
|
3941
|
+
|
3942
|
+
context 'when a String key is used' do
|
3943
|
+
|
3944
|
+
let(:options) do
|
3945
|
+
{ 'array_filters' => [{ 'i.y' => 3 }] }
|
3946
|
+
end
|
3947
|
+
|
3948
|
+
it 'applies the arrayFilters' do
|
3949
|
+
expect(result['x']).to eq([{ 'y' => 1 }, { 'y' => 2 }, { 'y' => 3 }])
|
3950
|
+
expect(authorized_collection.find(selector).first['x'].last['y']).to eq(5)
|
3951
|
+
end
|
3952
|
+
end
|
3953
|
+
end
|
3954
|
+
|
3955
|
+
context 'when the server selected does not support arrayFilters', unless: array_filters_enabled? do
|
3956
|
+
|
3957
|
+
let(:result) do
|
3958
|
+
authorized_collection.find_one_and_update(selector,
|
3959
|
+
{ '$set' => { 'x.$[i].y' => 5 } },
|
3960
|
+
options)
|
3961
|
+
end
|
3962
|
+
|
3963
|
+
context 'when a Symbol key is used' do
|
3964
|
+
|
3965
|
+
let(:options) do
|
3966
|
+
{ array_filters: [{ 'i.y' => 3 }] }
|
3967
|
+
end
|
3968
|
+
|
3969
|
+
it 'raises an exception' do
|
3970
|
+
expect {
|
3971
|
+
result
|
3972
|
+
}.to raise_exception(Mongo::Error::UnsupportedArrayFilters)
|
3973
|
+
end
|
3974
|
+
end
|
3975
|
+
|
3976
|
+
context 'when a String key is used' do
|
3977
|
+
|
3978
|
+
let(:options) do
|
3979
|
+
{ 'array_filters' => [{ 'i.y' => 3 }] }
|
3980
|
+
end
|
3981
|
+
|
3982
|
+
it 'raises an exception' do
|
3983
|
+
expect {
|
3984
|
+
result
|
3985
|
+
}.to raise_exception(Mongo::Error::UnsupportedArrayFilters)
|
3986
|
+
end
|
3987
|
+
end
|
3988
|
+
end
|
3989
|
+
end
|
3117
3990
|
end
|
3118
3991
|
|
3119
3992
|
describe '#find_one_and_replace' do
|
@@ -3139,6 +4012,28 @@ describe Mongo::Collection do
|
|
3139
4012
|
end
|
3140
4013
|
end
|
3141
4014
|
|
4015
|
+
context 'when a session is provided' do
|
4016
|
+
|
4017
|
+
let(:operation) do
|
4018
|
+
authorized_collection.find_one_and_replace(selector, { field: 'testing' }, session: session)
|
4019
|
+
end
|
4020
|
+
|
4021
|
+
let(:failed_operation) do
|
4022
|
+
authorized_collection.find_one_and_replace({ '$._id' => 1}, { field: 'testing' }, session: session)
|
4023
|
+
end
|
4024
|
+
|
4025
|
+
let(:session) do
|
4026
|
+
authorized_client.start_session
|
4027
|
+
end
|
4028
|
+
|
4029
|
+
let(:client) do
|
4030
|
+
authorized_client
|
4031
|
+
end
|
4032
|
+
|
4033
|
+
it_behaves_like 'an operation using a session'
|
4034
|
+
it_behaves_like 'a failed operation using a session'
|
4035
|
+
end
|
4036
|
+
|
3142
4037
|
context 'when return_document options are provided' do
|
3143
4038
|
|
3144
4039
|
context 'when return_document is :after' do
|
@@ -3262,7 +4157,7 @@ describe Mongo::Collection do
|
|
3262
4157
|
|
3263
4158
|
let(:result) do
|
3264
4159
|
collection_with_validator.find_one_and_replace(
|
3265
|
-
|
4160
|
+
{ a: 1 }, { a: 5 }, :return_document => :after)
|
3266
4161
|
end
|
3267
4162
|
|
3268
4163
|
it 'replaces successfully when document is valid' do
|
@@ -3276,7 +4171,7 @@ describe Mongo::Collection do
|
|
3276
4171
|
|
3277
4172
|
let(:result2) do
|
3278
4173
|
collection_with_validator.find_one_and_replace(
|
3279
|
-
|
4174
|
+
{ a: 1 }, { x: 5 }, :return_document => :after)
|
3280
4175
|
end
|
3281
4176
|
|
3282
4177
|
it 'raises OperationFailure' do
|
@@ -3290,8 +4185,8 @@ describe Mongo::Collection do
|
|
3290
4185
|
|
3291
4186
|
let(:result3) do
|
3292
4187
|
collection_with_validator.find_one_and_replace(
|
3293
|
-
|
3294
|
-
|
4188
|
+
{ a: 1 }, { x: 1 }, :bypass_document_validation => true,
|
4189
|
+
:return_document => :after)
|
3295
4190
|
end
|
3296
4191
|
|
3297
4192
|
it 'replaces successfully' do
|
@@ -3398,4 +4293,115 @@ describe Mongo::Collection do
|
|
3398
4293
|
end
|
3399
4294
|
end
|
3400
4295
|
end
|
4296
|
+
|
4297
|
+
describe '#watch' do
|
4298
|
+
|
4299
|
+
context 'when change streams can be tested', if: test_change_streams? do
|
4300
|
+
|
4301
|
+
let(:change_stream) do
|
4302
|
+
authorized_collection.watch
|
4303
|
+
end
|
4304
|
+
|
4305
|
+
let(:enum) do
|
4306
|
+
change_stream.to_enum
|
4307
|
+
end
|
4308
|
+
|
4309
|
+
before do
|
4310
|
+
change_stream
|
4311
|
+
authorized_collection.insert_one(a: 1)
|
4312
|
+
end
|
4313
|
+
|
4314
|
+
context 'when no options are provided' do
|
4315
|
+
|
4316
|
+
context 'when the operation type is an insert' do
|
4317
|
+
|
4318
|
+
it 'returns the change' do
|
4319
|
+
expect(enum.next[:fullDocument][:a]).to eq(1)
|
4320
|
+
end
|
4321
|
+
end
|
4322
|
+
|
4323
|
+
context 'when the operation type is an update' do
|
4324
|
+
|
4325
|
+
before do
|
4326
|
+
authorized_collection.update_one({ a: 1 }, { '$set' => { a: 2 } })
|
4327
|
+
end
|
4328
|
+
|
4329
|
+
let(:change_doc) do
|
4330
|
+
enum.next
|
4331
|
+
enum.next
|
4332
|
+
end
|
4333
|
+
|
4334
|
+
it 'returns the change' do
|
4335
|
+
expect(change_doc[:operationType]).to eq('update')
|
4336
|
+
expect(change_doc[:updateDescription][:updatedFields]).to eq('a' => 2)
|
4337
|
+
end
|
4338
|
+
end
|
4339
|
+
end
|
4340
|
+
|
4341
|
+
context 'when options are provided' do
|
4342
|
+
|
4343
|
+
context 'when full_document is updateLookup' do
|
4344
|
+
|
4345
|
+
let(:change_stream) do
|
4346
|
+
authorized_collection.watch([], full_document: 'updateLookup').to_enum
|
4347
|
+
end
|
4348
|
+
|
4349
|
+
before do
|
4350
|
+
authorized_collection.update_one({ a: 1 }, { '$set' => { a: 2 } })
|
4351
|
+
end
|
4352
|
+
|
4353
|
+
let(:change_doc) do
|
4354
|
+
enum.next
|
4355
|
+
enum.next
|
4356
|
+
end
|
4357
|
+
|
4358
|
+
it 'returns the change' do
|
4359
|
+
expect(change_doc[:operationType]).to eq('update')
|
4360
|
+
expect(change_doc[:fullDocument][:a]).to eq(2)
|
4361
|
+
end
|
4362
|
+
end
|
4363
|
+
|
4364
|
+
context 'when batch_size is provided' do
|
4365
|
+
|
4366
|
+
before do
|
4367
|
+
authorized_collection.insert_one(a: 2)
|
4368
|
+
authorized_collection.insert_one(a: 3)
|
4369
|
+
end
|
4370
|
+
|
4371
|
+
let(:change_stream) do
|
4372
|
+
authorized_collection.watch([], batch_size: 2)
|
4373
|
+
end
|
4374
|
+
|
4375
|
+
it 'returns the documents in the batch size specified' do
|
4376
|
+
expect(change_stream.instance_variable_get(:@cursor)).to receive(:get_more).once.and_call_original
|
4377
|
+
enum.next
|
4378
|
+
enum.next
|
4379
|
+
end
|
4380
|
+
end
|
4381
|
+
|
4382
|
+
context 'when collation is provided' do
|
4383
|
+
# pending 'server support for collation with the $changeStream operator'
|
4384
|
+
#
|
4385
|
+
# before do
|
4386
|
+
# authorized_collection.update_one({ a: 1 }, { '$set' => { a: 2 } })
|
4387
|
+
# end
|
4388
|
+
#
|
4389
|
+
# let(:change_doc) do
|
4390
|
+
# change_stream.next
|
4391
|
+
# change_stream.next
|
4392
|
+
# end
|
4393
|
+
#
|
4394
|
+
# let(:change_stream) do
|
4395
|
+
# authorized_collection.watch([ { '$match' => { operationType: 'UPDATE'}}],
|
4396
|
+
# collation: { locale: 'en_US', strength: 2 } ).to_enum
|
4397
|
+
# end
|
4398
|
+
#
|
4399
|
+
# it 'returns the change' do
|
4400
|
+
# expect(change_doc[:operationType]).to eq('update')
|
4401
|
+
# expect(change_doc[:fullDocument][:a]).to eq(2)
|
4402
|
+
# end
|
4403
|
+
end
|
4404
|
+
end
|
4405
|
+
end
|
4406
|
+
end
|
3401
4407
|
end
|