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