mongo 2.1.0.beta → 2.1.0.rc0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/Rakefile +2 -2
- data/lib/mongo.rb +2 -3
- data/lib/mongo/address.rb +7 -5
- data/lib/mongo/address/unix.rb +2 -2
- data/lib/mongo/auth/ldap/conversation.rb +6 -2
- data/lib/mongo/auth/scram/conversation.rb +8 -2
- data/lib/mongo/auth/user/view.rb +21 -0
- data/lib/mongo/bulk_write.rb +155 -23
- data/lib/mongo/bulk_write/combineable.rb +51 -0
- data/lib/mongo/bulk_write/ordered_combiner.rb +55 -0
- data/lib/mongo/bulk_write/result.rb +61 -8
- data/lib/mongo/bulk_write/result_combiner.rb +117 -0
- data/lib/mongo/bulk_write/transformable.rb +117 -0
- data/lib/mongo/bulk_write/unordered_combiner.rb +52 -0
- data/lib/mongo/bulk_write/validatable.rb +62 -0
- data/lib/mongo/client.rb +7 -3
- data/lib/mongo/cluster.rb +3 -3
- data/lib/mongo/cluster/topology/replica_set.rb +8 -6
- data/lib/mongo/cluster/topology/unknown.rb +5 -2
- data/lib/mongo/collection.rb +75 -4
- data/lib/mongo/collection/view.rb +1 -2
- data/lib/mongo/collection/view/aggregation.rb +13 -8
- data/lib/mongo/collection/view/immutable.rb +6 -6
- data/lib/mongo/collection/view/iterable.rb +13 -4
- data/lib/mongo/collection/view/map_reduce.rb +22 -17
- data/lib/mongo/collection/view/readable.rb +121 -70
- data/lib/mongo/cursor.rb +5 -1
- data/lib/mongo/database.rb +3 -3
- data/lib/mongo/database/view.rb +1 -1
- data/lib/mongo/error.rb +7 -0
- data/lib/mongo/{bulk_write/unordered_bulk_write.rb → error/closed_stream.rb} +12 -21
- data/lib/mongo/{bulk_write/ordered_bulk_write.rb → error/extra_file_chunk.rb} +13 -27
- data/lib/mongo/error/file_not_found.rb +37 -0
- data/lib/mongo/error/invalid_file.rb +2 -2
- data/lib/mongo/error/invalid_file_revision.rb +37 -0
- data/lib/mongo/error/invalid_uri.rb +5 -4
- data/lib/mongo/error/missing_file_chunk.rb +38 -0
- data/lib/mongo/error/operation_failure.rb +1 -1
- data/lib/mongo/error/unchangeable_collection_option.rb +38 -0
- data/lib/mongo/error/unexpected_chunk_length.rb +39 -0
- data/lib/mongo/grid.rb +2 -1
- data/lib/mongo/grid/file.rb +12 -9
- data/lib/mongo/grid/file/chunk.rb +6 -6
- data/lib/mongo/grid/file/{metadata.rb → info.rb} +41 -39
- data/lib/mongo/grid/fs_bucket.rb +441 -0
- data/lib/mongo/grid/stream.rb +64 -0
- data/lib/mongo/grid/stream/read.rb +208 -0
- data/lib/mongo/grid/stream/write.rb +187 -0
- data/lib/mongo/index/view.rb +1 -1
- data/lib/mongo/loggable.rb +34 -57
- data/lib/mongo/logger.rb +16 -78
- data/lib/mongo/monitoring.rb +1 -5
- data/lib/mongo/monitoring/command_log_subscriber.rb +35 -17
- data/lib/mongo/monitoring/event/command_succeeded.rb +20 -1
- data/lib/mongo/monitoring/publishable.rb +22 -12
- data/lib/mongo/operation.rb +3 -6
- data/lib/mongo/operation/commands.rb +24 -0
- data/lib/mongo/operation/{aggregate.rb → commands/aggregate.rb} +3 -41
- data/lib/mongo/operation/{aggregate → commands/aggregate}/result.rb +0 -0
- data/lib/mongo/operation/commands/collections_info.rb +66 -0
- data/lib/mongo/operation/{command.rb → commands/command.rb} +2 -18
- data/lib/mongo/operation/commands/indexes.rb +70 -0
- data/lib/mongo/operation/commands/list_collections.rb +54 -0
- data/lib/mongo/operation/commands/list_collections/result.rb +112 -0
- data/lib/mongo/operation/commands/list_indexes.rb +56 -0
- data/lib/mongo/operation/commands/list_indexes/result.rb +115 -0
- data/lib/mongo/operation/{map_reduce.rb → commands/map_reduce.rb} +3 -41
- data/lib/mongo/operation/{map_reduce → commands/map_reduce}/result.rb +0 -0
- data/lib/mongo/operation/{parallel_scan.rb → commands/parallel_scan.rb} +3 -23
- data/lib/mongo/operation/{parallel_scan → commands/parallel_scan}/result.rb +0 -0
- data/lib/mongo/operation/commands/user_query.rb +69 -0
- data/lib/mongo/operation/commands/users_info.rb +53 -0
- data/lib/mongo/operation/commands/users_info/result.rb +36 -0
- data/lib/mongo/operation/executable.rb +4 -68
- data/lib/mongo/operation/kill_cursors.rb +3 -3
- data/lib/mongo/operation/read.rb +0 -4
- data/lib/mongo/operation/read/get_more.rb +2 -22
- data/lib/mongo/operation/read/query.rb +2 -21
- data/lib/mongo/operation/{read_preferrable.rb → read_preference.rb} +3 -2
- data/lib/mongo/operation/specifiable.rb +24 -0
- data/lib/mongo/operation/write.rb +2 -0
- data/lib/mongo/operation/write/bulk.rb +6 -3
- data/lib/mongo/operation/write/bulk/bulkable.rb +82 -0
- data/lib/mongo/operation/write/bulk/delete.rb +71 -0
- data/lib/mongo/operation/write/bulk/delete/result.rb +74 -0
- data/lib/mongo/operation/write/bulk/insert.rb +96 -0
- data/lib/mongo/operation/write/bulk/insert/result.rb +129 -0
- data/lib/mongo/operation/write/bulk/legacy_mergable.rb +87 -0
- data/lib/mongo/operation/write/bulk/mergable.rb +71 -0
- data/lib/mongo/operation/write/bulk/update.rb +81 -0
- data/lib/mongo/operation/write/bulk/update/result.rb +174 -0
- data/lib/mongo/operation/write/command/create_index.rb +0 -1
- data/lib/mongo/operation/write/command/create_user.rb +0 -1
- data/lib/mongo/operation/write/command/delete.rb +0 -1
- data/lib/mongo/operation/write/command/drop_index.rb +0 -1
- data/lib/mongo/operation/write/command/insert.rb +0 -1
- data/lib/mongo/operation/write/command/remove_user.rb +0 -1
- data/lib/mongo/operation/write/command/update.rb +0 -1
- data/lib/mongo/operation/write/command/update_user.rb +0 -1
- data/lib/mongo/operation/write/command/writable.rb +13 -18
- data/lib/mongo/operation/write/create_index.rb +4 -27
- data/lib/mongo/operation/write/create_user.rb +4 -30
- data/lib/mongo/operation/write/delete.rb +5 -28
- data/lib/mongo/operation/write/drop_index.rb +3 -3
- data/lib/mongo/operation/write/gle.rb +48 -0
- data/lib/mongo/operation/write/idable.rb +5 -0
- data/lib/mongo/operation/write/insert.rb +2 -24
- data/lib/mongo/operation/write/remove_user.rb +4 -27
- data/lib/mongo/operation/write/update.rb +4 -32
- data/lib/mongo/operation/write/update_user.rb +4 -30
- data/lib/mongo/operation/write/write_command_enabled.rb +53 -0
- data/lib/mongo/options/mapper.rb +4 -2
- data/lib/mongo/protocol/delete.rb +68 -3
- data/lib/mongo/protocol/get_more.rb +54 -2
- data/lib/mongo/protocol/insert.rb +59 -1
- data/lib/mongo/protocol/kill_cursors.rb +53 -4
- data/lib/mongo/protocol/message.rb +12 -12
- data/lib/mongo/protocol/query.rb +139 -65
- data/lib/mongo/protocol/reply.rb +69 -1
- data/lib/mongo/protocol/update.rb +70 -1
- data/lib/mongo/server/connection.rb +11 -3
- data/lib/mongo/server/description.rb +29 -0
- data/lib/mongo/server/description/features.rb +2 -1
- data/lib/mongo/server/monitor.rb +2 -2
- data/lib/mongo/server_selector.rb +14 -10
- data/lib/mongo/server_selector/selectable.rb +24 -22
- data/lib/mongo/socket.rb +6 -3
- data/lib/mongo/socket/tcp.rb +2 -2
- data/lib/mongo/socket/unix.rb +5 -8
- data/lib/mongo/uri.rb +243 -139
- data/lib/mongo/version.rb +1 -1
- data/spec/mongo/address/unix_spec.rb +1 -1
- data/spec/mongo/address_spec.rb +25 -0
- data/spec/mongo/auth/ldap/conversation_spec.rb +43 -0
- data/spec/mongo/auth/user/view_spec.rb +26 -1
- data/spec/mongo/bulk_write/ordered_combiner_spec.rb +271 -0
- data/spec/mongo/bulk_write/unordered_combiner_spec.rb +239 -0
- data/spec/mongo/bulk_write_spec.rb +332 -166
- data/spec/mongo/client_spec.rb +25 -0
- data/spec/mongo/cluster/topology/replica_set_spec.rb +2 -0
- data/spec/mongo/collection/view/aggregation_spec.rb +65 -0
- data/spec/mongo/collection/view/immutable_spec.rb +103 -0
- data/spec/mongo/collection/view/map_reduce_spec.rb +98 -3
- data/spec/mongo/collection/view/readable_spec.rb +17 -30
- data/spec/mongo/collection/view_spec.rb +233 -7
- data/spec/mongo/collection_spec.rb +360 -18
- data/spec/mongo/command_monitoring_spec.rb +51 -0
- data/spec/mongo/connection_string_spec.rb +137 -0
- data/spec/mongo/database_spec.rb +27 -11
- data/spec/mongo/grid/file/chunk_spec.rb +5 -5
- data/spec/mongo/grid/file/{metadata_spec.rb → info_spec.rb} +29 -17
- data/spec/mongo/grid/file_spec.rb +8 -8
- data/spec/mongo/grid/fs_bucket_spec.rb +1020 -0
- data/spec/mongo/grid/stream/read_spec.rb +275 -0
- data/spec/mongo/grid/stream/write_spec.rb +440 -0
- data/spec/mongo/grid/stream_spec.rb +48 -0
- data/spec/mongo/gridfs_spec.rb +50 -0
- data/spec/mongo/logger_spec.rb +0 -40
- data/spec/mongo/monitoring/command_log_subscriber_spec.rb +76 -0
- data/spec/mongo/operation/{aggregate_spec.rb → commands/aggregate_spec.rb} +0 -42
- data/spec/mongo/operation/{read → commands}/collections_info_spec.rb +1 -1
- data/spec/mongo/operation/{command_spec.rb → commands/command_spec.rb} +0 -0
- data/spec/mongo/operation/{read → commands}/indexes_spec.rb +1 -1
- data/spec/mongo/operation/{map_reduce_spec.rb → commands/map_reduce_spec.rb} +0 -18
- data/spec/mongo/operation/kill_cursors_spec.rb +1 -1
- data/spec/mongo/operation/{read_preferrable_spec.rb → read_preference_spec.rb} +11 -11
- data/spec/mongo/operation/write/bulk/{bulk_delete_spec.rb → delete_spec.rb} +1 -12
- data/spec/mongo/operation/write/bulk/{bulk_insert_spec.rb → insert_spec.rb} +1 -12
- data/spec/mongo/operation/write/bulk/{bulk_update_spec.rb → update_spec.rb} +1 -12
- data/spec/mongo/operation/write/insert_spec.rb +0 -11
- data/spec/mongo/protocol/kill_cursors_spec.rb +5 -3
- data/spec/mongo/server/description_spec.rb +42 -0
- data/spec/mongo/server/monitor_spec.rb +21 -0
- data/spec/mongo/server_discovery_and_monitoring_spec.rb +1 -0
- data/spec/mongo/server_selection_spec.rb +3 -3
- data/spec/mongo/server_selector/nearest_spec.rb +34 -27
- data/spec/mongo/server_selector/primary_preferred_spec.rb +31 -30
- data/spec/mongo/server_selector/primary_spec.rb +14 -13
- data/spec/mongo/server_selector/secondary_preferred_spec.rb +27 -26
- data/spec/mongo/server_selector/secondary_spec.rb +23 -22
- data/spec/mongo/server_selector_spec.rb +87 -24
- data/spec/mongo/socket/unix_spec.rb +52 -0
- data/spec/mongo/uri_spec.rb +251 -39
- data/spec/spec_helper.rb +11 -4
- data/spec/support/authorization.rb +4 -5
- data/spec/support/command_monitoring.rb +365 -0
- data/spec/support/command_monitoring/bulkWrite.yml +73 -0
- data/spec/support/command_monitoring/command.yml +42 -0
- data/spec/support/command_monitoring/deleteMany.yml +55 -0
- data/spec/support/command_monitoring/deleteOne.yml +55 -0
- data/spec/support/command_monitoring/find.yml +219 -0
- data/spec/support/command_monitoring/insertMany.yml +81 -0
- data/spec/support/command_monitoring/insertOne.yml +51 -0
- data/spec/support/command_monitoring/updateMany.yml +67 -0
- data/spec/support/command_monitoring/updateOne.yml +95 -0
- data/spec/support/connection_string.rb +228 -0
- data/spec/support/connection_string_tests/invalid-uris.yml +193 -0
- data/spec/support/connection_string_tests/valid-auth.yml +256 -0
- data/spec/support/connection_string_tests/valid-host_identifiers.yml +121 -0
- data/spec/support/connection_string_tests/valid-options.yml +30 -0
- data/spec/support/connection_string_tests/valid-unix_socket-absolute.yml +197 -0
- data/spec/support/connection_string_tests/valid-unix_socket-relative.yml +213 -0
- data/spec/support/connection_string_tests/valid-warnings.yml +55 -0
- data/spec/support/crud.rb +3 -1
- data/spec/support/crud/read.rb +14 -10
- data/spec/support/crud/write.rb +36 -9
- data/spec/support/gridfs.rb +637 -0
- data/spec/support/gridfs_tests/delete.yml +157 -0
- data/spec/support/gridfs_tests/download.yml +210 -0
- data/spec/support/gridfs_tests/download_by_name.yml +113 -0
- data/spec/support/gridfs_tests/upload.yml +158 -0
- data/spec/support/sdam/rs/equal_electionids.yml +1 -2
- data/spec/support/sdam/rs/new_primary_new_electionid.yml +0 -3
- data/spec/support/sdam/rs/primary_mismatched_me.yml +37 -0
- data/spec/support/sdam/rs/primary_to_no_primary_mismatched_me.yml +75 -0
- data/spec/support/sdam/rs/secondary_mismatched_me.yml +37 -0
- 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/not_ok_response.yml +0 -1
- data/spec/support/server_discovery_and_monitoring.rb +3 -1
- data/spec/support/server_selection.rb +3 -1
- data/spec/support/shared/bulk_write.rb +192 -0
- data/spec/support/shared/server_selector.rb +21 -12
- metadata +147 -57
- metadata.gz.sig +0 -0
- data/lib/mongo/bulk_write/bulk_writable.rb +0 -252
- data/lib/mongo/bulk_write/deletable.rb +0 -57
- data/lib/mongo/bulk_write/insertable.rb +0 -49
- data/lib/mongo/bulk_write/replacable.rb +0 -58
- data/lib/mongo/bulk_write/updatable.rb +0 -69
- data/lib/mongo/grid/fs.rb +0 -146
- data/lib/mongo/operation/list_collections/result.rb +0 -114
- data/lib/mongo/operation/list_indexes/result.rb +0 -118
- data/lib/mongo/operation/read/collections_info.rb +0 -68
- data/lib/mongo/operation/read/indexes.rb +0 -69
- data/lib/mongo/operation/read/list_collections.rb +0 -76
- data/lib/mongo/operation/read/list_indexes.rb +0 -78
- data/lib/mongo/operation/write/bulk/bulk_delete.rb +0 -145
- data/lib/mongo/operation/write/bulk/bulk_delete/result.rb +0 -75
- data/lib/mongo/operation/write/bulk/bulk_insert.rb +0 -132
- data/lib/mongo/operation/write/bulk/bulk_insert/result.rb +0 -130
- data/lib/mongo/operation/write/bulk/bulk_mergable.rb +0 -67
- data/lib/mongo/operation/write/bulk/bulk_update.rb +0 -154
- data/lib/mongo/operation/write/bulk/bulk_update/result.rb +0 -174
- data/lib/mongo/operation/write/bulk/legacy_bulk_mergable.rb +0 -83
- data/spec/mongo/grid/fs_spec.rb +0 -160
- data/spec/mongo/loggable_spec.rb +0 -63
data/spec/mongo/client_spec.rb
CHANGED
@@ -20,6 +20,10 @@ describe Mongo::Client do
|
|
20
20
|
)
|
21
21
|
end
|
22
22
|
|
23
|
+
after do
|
24
|
+
client.close
|
25
|
+
end
|
26
|
+
|
23
27
|
context 'when the other is a client' do
|
24
28
|
|
25
29
|
context 'when the options and cluster are equal' do
|
@@ -222,6 +226,27 @@ describe Mongo::Client do
|
|
222
226
|
expect(client[:users].name).to eq('users')
|
223
227
|
end
|
224
228
|
end
|
229
|
+
|
230
|
+
context 'when providing a custom logger' do
|
231
|
+
|
232
|
+
let(:logger) do
|
233
|
+
Logger.new($stdout).tap do |l|
|
234
|
+
l.level = Logger::FATAL
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
let(:client) do
|
239
|
+
authorized_client.with(logger: logger)
|
240
|
+
end
|
241
|
+
|
242
|
+
after do
|
243
|
+
client.close
|
244
|
+
end
|
245
|
+
|
246
|
+
it 'does not use the global logger' do
|
247
|
+
expect(client.cluster.logger).to_not eq(Mongo::Logger.logger)
|
248
|
+
end
|
249
|
+
end
|
225
250
|
end
|
226
251
|
|
227
252
|
context 'when providing a connection string' do
|
@@ -239,6 +239,7 @@ describe Mongo::Cluster::Topology::ReplicaSet do
|
|
239
239
|
double('description').tap do |d|
|
240
240
|
allow(d).to receive(:config).and_return({ 'ismaster' => true })
|
241
241
|
allow(d).to receive(:primary?).and_return(false)
|
242
|
+
allow(d).to receive(:me_mismatch?).and_return(false)
|
242
243
|
allow(d).to receive(:hosts).and_return([])
|
243
244
|
end
|
244
245
|
end
|
@@ -257,6 +258,7 @@ describe Mongo::Cluster::Topology::ReplicaSet do
|
|
257
258
|
allow(d).to receive(:hosts).and_return([ primary ])
|
258
259
|
allow(d).to receive(:replica_set_name).and_return('test')
|
259
260
|
allow(d).to receive(:replica_set_member?).and_return(true)
|
261
|
+
allow(d).to receive(:me_mismatch?).and_return(false)
|
260
262
|
end
|
261
263
|
end
|
262
264
|
|
@@ -300,4 +300,69 @@ describe Mongo::Collection::View::Aggregation do
|
|
300
300
|
end
|
301
301
|
end
|
302
302
|
end
|
303
|
+
|
304
|
+
context 'when $out is in the pipeline', if: write_command_enabled? do
|
305
|
+
|
306
|
+
let(:pipeline) do
|
307
|
+
[{
|
308
|
+
"$group" => {
|
309
|
+
"_id" => "$city",
|
310
|
+
"totalpop" => { "$sum" => "$pop" }
|
311
|
+
}
|
312
|
+
},
|
313
|
+
{
|
314
|
+
'$out' => 'output_collection'
|
315
|
+
}
|
316
|
+
]
|
317
|
+
end
|
318
|
+
|
319
|
+
after do
|
320
|
+
authorized_client['output_collection'].delete_many
|
321
|
+
end
|
322
|
+
|
323
|
+
context 'when $out is a string' do
|
324
|
+
|
325
|
+
it 'does not allow the operation on a secondary' do
|
326
|
+
expect(aggregation.send(:secondary_ok?)).to be(false)
|
327
|
+
end
|
328
|
+
end
|
329
|
+
|
330
|
+
context 'when $out is a symbol' do
|
331
|
+
|
332
|
+
let(:pipeline) do
|
333
|
+
[{
|
334
|
+
"$group" => {
|
335
|
+
"_id" => "$city",
|
336
|
+
"totalpop" => { "$sum" => "$pop" }
|
337
|
+
}
|
338
|
+
},
|
339
|
+
{
|
340
|
+
:$out => 'output_collection'
|
341
|
+
}
|
342
|
+
]
|
343
|
+
end
|
344
|
+
|
345
|
+
it 'does not allow the operation on a secondary' do
|
346
|
+
expect(aggregation.send(:secondary_ok?)).to be(false)
|
347
|
+
end
|
348
|
+
end
|
349
|
+
|
350
|
+
|
351
|
+
context 'when the context is not a valid server for writing' do
|
352
|
+
|
353
|
+
it 'reroutes the operation to a primary' do
|
354
|
+
allow(aggregation).to receive(:valid_server?).and_return(false)
|
355
|
+
expect(Mongo::Logger.logger).to receive(:warn?).and_call_original
|
356
|
+
aggregation.to_a
|
357
|
+
end
|
358
|
+
end
|
359
|
+
|
360
|
+
context 'when the context is a valid server for writing' do
|
361
|
+
|
362
|
+
it 'does not reroute the operation to a primary' do
|
363
|
+
expect(Mongo::Logger.logger).not_to receive(:warn?)
|
364
|
+
aggregation.to_a
|
365
|
+
end
|
366
|
+
end
|
367
|
+
end
|
303
368
|
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Mongo::Collection::View::Immutable do
|
4
|
+
|
5
|
+
let(:selector) do
|
6
|
+
{}
|
7
|
+
end
|
8
|
+
|
9
|
+
let(:options) do
|
10
|
+
{}
|
11
|
+
end
|
12
|
+
|
13
|
+
let(:view) do
|
14
|
+
Mongo::Collection::View.new(authorized_collection, selector, options)
|
15
|
+
end
|
16
|
+
|
17
|
+
after do
|
18
|
+
authorized_collection.delete_many
|
19
|
+
end
|
20
|
+
|
21
|
+
describe '#configure' do
|
22
|
+
|
23
|
+
context 'when the options has a modifiers document' do
|
24
|
+
|
25
|
+
let(:options) do
|
26
|
+
{ modifiers: { :$maxTimeMS => 500 } }
|
27
|
+
end
|
28
|
+
|
29
|
+
let(:new_view) do
|
30
|
+
view.projection(_id: 1)
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'returns a new view' do
|
34
|
+
expect(view).not_to be(new_view)
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'creates a new options hash' do
|
38
|
+
expect(view.options).not_to be(new_view.options)
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'keeps the modifier fields already in the options hash' do
|
42
|
+
expect(new_view.modifiers[:$maxTimeMS]).to eq(500)
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'sets the option' do
|
46
|
+
expect(new_view.projection).to eq(_id: 1)
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'creates a new modifiers document' do
|
50
|
+
expect(view.modifiers).not_to be(new_view.modifiers)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe '#configure_modifier' do
|
56
|
+
|
57
|
+
let(:new_view) do
|
58
|
+
view.sort('x' => Mongo::Index::ASCENDING)
|
59
|
+
end
|
60
|
+
|
61
|
+
context 'when the options does not have a modifiers document' do
|
62
|
+
|
63
|
+
it 'returns a new view' do
|
64
|
+
expect(view).not_to be(new_view)
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'returns a new view with the modifiers document containing the option' do
|
68
|
+
expect(new_view.modifiers[:$orderby]).to eq({ 'x' => Mongo::Index::ASCENDING })
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
context 'when the options has a modifiers document' do
|
73
|
+
|
74
|
+
let(:options) do
|
75
|
+
{ modifiers: { :$maxTimeMS => 500 } }
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'returns a new view' do
|
79
|
+
expect(view).not_to be(new_view)
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'creates a new options hash' do
|
83
|
+
expect(view.options).not_to be(new_view.options)
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'keeps the fields already in the options hash and merges in the new one' do
|
87
|
+
expect(new_view.modifiers[:$maxTimeMS]).to eq(500)
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'sets the new value in the new view modifier document' do
|
91
|
+
expect(new_view.modifiers[:$orderby]).to eq('x' => Mongo::Index::ASCENDING)
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'returns that value when the corresponding option method is called' do
|
95
|
+
expect(new_view.sort).to eq({ 'x' => Mongo::Index::ASCENDING })
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'creates a new modifiers document' do
|
99
|
+
expect(view.modifiers).not_to be(new_view.modifiers)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
@@ -66,6 +66,39 @@ describe Mongo::Collection::View::MapReduce do
|
|
66
66
|
end
|
67
67
|
end
|
68
68
|
|
69
|
+
context 'when out is in the options' do
|
70
|
+
|
71
|
+
after do
|
72
|
+
authorized_client['output_collection'].delete_many
|
73
|
+
end
|
74
|
+
|
75
|
+
context 'when out is a string' do
|
76
|
+
|
77
|
+
let(:options) do
|
78
|
+
{ :out => 'output_collection' }
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'iterates over the documents in the result' do
|
82
|
+
map_reduce.each do |document|
|
83
|
+
expect(document[:value]).to_not be_nil
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
context 'when out is a document' do
|
89
|
+
|
90
|
+
let(:options) do
|
91
|
+
{ :out => { replace: 'output_collection' } }
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'iterates over the documents in the result' do
|
95
|
+
map_reduce.each do |document|
|
96
|
+
expect(document[:value]).to_not be_nil
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
69
102
|
context 'when out is inline' do
|
70
103
|
|
71
104
|
let(:new_map_reduce) do
|
@@ -82,7 +115,7 @@ describe Mongo::Collection::View::MapReduce do
|
|
82
115
|
context 'when out is a collection' do
|
83
116
|
|
84
117
|
after do
|
85
|
-
authorized_client['output_collection'].
|
118
|
+
authorized_client['output_collection'].delete_many
|
86
119
|
end
|
87
120
|
|
88
121
|
context 'when the option is to replace' do
|
@@ -135,6 +168,17 @@ describe Mongo::Collection::View::MapReduce do
|
|
135
168
|
expect(new_map_reduce.count).to eq(2)
|
136
169
|
end
|
137
170
|
end
|
171
|
+
|
172
|
+
context 'when the option is a collection name' do
|
173
|
+
|
174
|
+
let(:new_map_reduce) do
|
175
|
+
map_reduce.out('output_collection')
|
176
|
+
end
|
177
|
+
|
178
|
+
it 'fetches the results from the collection' do
|
179
|
+
expect(new_map_reduce.count).to eq(2)
|
180
|
+
end
|
181
|
+
end
|
138
182
|
end
|
139
183
|
|
140
184
|
context 'when the view has a selector' do
|
@@ -169,7 +213,7 @@ describe Mongo::Collection::View::MapReduce do
|
|
169
213
|
end
|
170
214
|
|
171
215
|
it 'includes the selector in the operation spec' do
|
172
|
-
expect(map_reduce.send(:map_reduce_spec)[:selector][:query]).to eq(selector[:$query])
|
216
|
+
expect(map_reduce.send(:map_reduce_spec)[:selector][:query]).to eq(BSON::Document.new(selector[:$query]))
|
173
217
|
end
|
174
218
|
end
|
175
219
|
end
|
@@ -250,6 +294,57 @@ describe Mongo::Collection::View::MapReduce do
|
|
250
294
|
expect(map_reduce.send(:map_reduce_spec)[:selector][:out]).to eq(inline: 1)
|
251
295
|
end
|
252
296
|
end
|
297
|
+
|
298
|
+
context 'when out is specified in the options' do
|
299
|
+
|
300
|
+
let(:location) do
|
301
|
+
{ replace: 'testing' }
|
302
|
+
end
|
303
|
+
|
304
|
+
let(:options) do
|
305
|
+
{ :out => location }
|
306
|
+
end
|
307
|
+
|
308
|
+
it 'sets the out value' do
|
309
|
+
expect(map_reduce.out).to eq(location)
|
310
|
+
end
|
311
|
+
|
312
|
+
it 'includes the out value in the operation spec' do
|
313
|
+
expect(map_reduce.send(:map_reduce_spec)[:selector][:out]).to be(location)
|
314
|
+
end
|
315
|
+
end
|
316
|
+
|
317
|
+
context 'when out is not inline' do
|
318
|
+
|
319
|
+
let(:location) do
|
320
|
+
{ replace: 'testing' }
|
321
|
+
end
|
322
|
+
|
323
|
+
let(:options) do
|
324
|
+
{ :out => location }
|
325
|
+
end
|
326
|
+
|
327
|
+
it 'does not allow the operation on a secondary' do
|
328
|
+
expect(map_reduce.send(:secondary_ok?)).to be(false)
|
329
|
+
end
|
330
|
+
|
331
|
+
context 'when the context is not a valid server for writing' do
|
332
|
+
|
333
|
+
it 'reroutes the operation to a primary' do
|
334
|
+
allow(map_reduce).to receive(:valid_server?).and_return(false)
|
335
|
+
expect(Mongo::Logger.logger).to receive(:warn?).and_call_original
|
336
|
+
map_reduce.to_a
|
337
|
+
end
|
338
|
+
end
|
339
|
+
|
340
|
+
context 'when the context is a valid server for writing' do
|
341
|
+
|
342
|
+
it 'does not reroute the operation to a primary' do
|
343
|
+
expect(Mongo::Logger.logger).not_to receive(:warn?)
|
344
|
+
map_reduce.to_a
|
345
|
+
end
|
346
|
+
end
|
347
|
+
end
|
253
348
|
end
|
254
349
|
|
255
350
|
describe '#scope' do
|
@@ -316,7 +411,7 @@ describe Mongo::Collection::View::MapReduce do
|
|
316
411
|
end
|
317
412
|
|
318
413
|
it 'includes the sort object in the operation spec' do
|
319
|
-
expect(map_reduce.send(:map_reduce_spec)[:selector][:sort]).to
|
414
|
+
expect(map_reduce.send(:map_reduce_spec)[:selector][:sort][:name]).to eq(sort[:name])
|
320
415
|
end
|
321
416
|
end
|
322
417
|
|
@@ -465,53 +465,40 @@ describe Mongo::Collection::View::Readable do
|
|
465
465
|
end
|
466
466
|
end
|
467
467
|
|
468
|
-
describe '#
|
468
|
+
describe '#max_value' do
|
469
469
|
|
470
470
|
let(:new_view) do
|
471
|
-
view.
|
471
|
+
view.max_value(_id: 1)
|
472
472
|
end
|
473
473
|
|
474
|
-
it 'sets the
|
475
|
-
expect(new_view.
|
476
|
-
end
|
477
|
-
|
478
|
-
it 'returns a new View' do
|
479
|
-
expect(new_view).not_to be(view)
|
474
|
+
it 'sets the value in the options' do
|
475
|
+
expect(new_view.max_value).to eq('_id' => 1)
|
480
476
|
end
|
481
477
|
end
|
482
478
|
|
483
|
-
describe '#
|
479
|
+
describe '#min_value' do
|
484
480
|
|
485
|
-
let(:
|
486
|
-
(1
|
487
|
-
{ name: "testing-scan-#{i}" }
|
488
|
-
end
|
481
|
+
let(:new_view) do
|
482
|
+
view.min_value(_id: 1)
|
489
483
|
end
|
490
484
|
|
491
|
-
|
492
|
-
|
485
|
+
it 'sets the value in the options' do
|
486
|
+
expect(new_view.min_value).to eq('_id' => 1)
|
493
487
|
end
|
488
|
+
end
|
494
489
|
|
495
|
-
|
496
|
-
view.parallel_scan(2)
|
497
|
-
end
|
490
|
+
describe '#no_cursor_timeout' do
|
498
491
|
|
499
|
-
|
500
|
-
|
501
|
-
expect(cursor.class).to be(Mongo::Cursor)
|
502
|
-
end
|
492
|
+
let(:new_view) do
|
493
|
+
view.no_cursor_timeout
|
503
494
|
end
|
504
495
|
|
505
|
-
it '
|
506
|
-
expect(
|
507
|
-
cursors.reduce(0) { |total, cursor| total + cursor.to_a.size }
|
508
|
-
).to eq(200)
|
496
|
+
it 'sets the flag' do
|
497
|
+
expect(new_view.send(:flags)).to include(:no_cursor_timeout)
|
509
498
|
end
|
510
499
|
|
511
|
-
it '
|
512
|
-
expect
|
513
|
-
cursors
|
514
|
-
}.to raise_error(Mongo::Error::OperationFailure)
|
500
|
+
it 'returns a new View' do
|
501
|
+
expect(new_view).not_to be(view)
|
515
502
|
end
|
516
503
|
end
|
517
504
|
|
@@ -18,6 +18,180 @@ describe Mongo::Collection::View do
|
|
18
18
|
authorized_collection.delete_many
|
19
19
|
end
|
20
20
|
|
21
|
+
context 'when query modifiers are provided' do
|
22
|
+
|
23
|
+
context 'when a selector has a query modifier' do
|
24
|
+
|
25
|
+
let(:options) do
|
26
|
+
{}
|
27
|
+
end
|
28
|
+
|
29
|
+
let(:expected_modifiers) do
|
30
|
+
BSON::Document.new(selector)
|
31
|
+
end
|
32
|
+
|
33
|
+
let(:parsed_selector) do
|
34
|
+
{}
|
35
|
+
end
|
36
|
+
|
37
|
+
let(:query_selector) do
|
38
|
+
BSON::Document.new(selector)
|
39
|
+
end
|
40
|
+
|
41
|
+
context 'when the $query key is a string' do
|
42
|
+
|
43
|
+
let(:selector) do
|
44
|
+
{ "$query" => { a: 1 }, :$someMod => 100 }
|
45
|
+
end
|
46
|
+
|
47
|
+
let(:expected_modifiers) do
|
48
|
+
BSON::Document.new(selector)
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'sets the modifiers' do
|
52
|
+
expect(view.instance_variable_get(:@modifiers)).to eq(expected_modifiers)
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'removes the modifiers from the selector' do
|
56
|
+
expect(view.selector).to eq(parsed_selector)
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'creates the correct query selector' do
|
60
|
+
expect(view.send(:query_spec)[:selector]).to eq(query_selector)
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
context 'when the $query key is a symbol' do
|
66
|
+
|
67
|
+
let(:selector) do
|
68
|
+
{ :$query => { a: 1 }, :$someMod => 100 }
|
69
|
+
end
|
70
|
+
|
71
|
+
let(:expected_modifiers) do
|
72
|
+
BSON::Document.new(selector)
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'sets the modifiers' do
|
76
|
+
expect(view.instance_variable_get(:@modifiers)).to eq(expected_modifiers)
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'removes the modifiers from the selector' do
|
80
|
+
expect(view.selector).to eq(parsed_selector)
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'creates the correct query selector' do
|
84
|
+
expect(view.send(:query_spec)[:selector]).to eq(query_selector)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
context 'when a modifiers document is provided in the options' do
|
90
|
+
|
91
|
+
let(:selector) do
|
92
|
+
{ a: 1 }
|
93
|
+
end
|
94
|
+
|
95
|
+
let(:options) do
|
96
|
+
{ :modifiers => { :$someMod => 100 } }
|
97
|
+
end
|
98
|
+
|
99
|
+
let(:expected_modifiers) do
|
100
|
+
options[:modifiers]
|
101
|
+
end
|
102
|
+
|
103
|
+
let(:parsed_selector) do
|
104
|
+
{ a: 1 }
|
105
|
+
end
|
106
|
+
|
107
|
+
let(:query_selector) do
|
108
|
+
BSON::Document.new(:$query => { a: 1 }, :$someMod => 100)
|
109
|
+
end
|
110
|
+
|
111
|
+
it 'sets the modifiers' do
|
112
|
+
expect(view.instance_variable_get(:@modifiers)).to eq(expected_modifiers)
|
113
|
+
end
|
114
|
+
|
115
|
+
it 'removes the modifiers from the selector' do
|
116
|
+
expect(view.selector).to eq(parsed_selector)
|
117
|
+
end
|
118
|
+
|
119
|
+
it 'creates the correct query selector' do
|
120
|
+
expect(view.send(:query_spec)[:selector]).to eq(query_selector)
|
121
|
+
end
|
122
|
+
|
123
|
+
context 'when modifiers and options are both provided' do
|
124
|
+
|
125
|
+
let(:selector) do
|
126
|
+
{ a: 1 }
|
127
|
+
end
|
128
|
+
|
129
|
+
let(:options) do
|
130
|
+
{ :sort => { a: Mongo::Index::ASCENDING }, :modifiers => { :$orderby => { a: Mongo::Index::DESCENDING } } }
|
131
|
+
end
|
132
|
+
|
133
|
+
let(:expected_modifiers) do
|
134
|
+
{ :$orderby => options[:sort] }
|
135
|
+
end
|
136
|
+
|
137
|
+
let(:parsed_selector) do
|
138
|
+
{ a: 1 }
|
139
|
+
end
|
140
|
+
|
141
|
+
let(:query_selector) do
|
142
|
+
BSON::Document.new(:$query => selector, :$orderby => { a: Mongo::Index::ASCENDING })
|
143
|
+
end
|
144
|
+
|
145
|
+
it 'sets the modifiers' do
|
146
|
+
expect(view.instance_variable_get(:@modifiers)).to eq(expected_modifiers)
|
147
|
+
end
|
148
|
+
|
149
|
+
it 'removes the modifiers from the selector' do
|
150
|
+
expect(view.selector).to eq(parsed_selector)
|
151
|
+
end
|
152
|
+
|
153
|
+
it 'creates the correct query selector' do
|
154
|
+
expect(view.send(:query_spec)[:selector]).to eq(query_selector)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
context 'when modifiers, options and a query modifier are provided' do
|
159
|
+
|
160
|
+
let(:selector) do
|
161
|
+
{ b: 2, :$query => { a: 1 }, :$someMod => 100 }
|
162
|
+
end
|
163
|
+
|
164
|
+
let(:options) do
|
165
|
+
{ :sort => { a: Mongo::Index::ASCENDING }, :modifiers => { :$someMod => true, :$orderby => { a: Mongo::Index::DESCENDING } } }
|
166
|
+
end
|
167
|
+
|
168
|
+
let(:expected_modifiers) do
|
169
|
+
{ :$query => { a: 1 }, :$orderby => { a: Mongo::Index::ASCENDING }, :$someMod => 100 }
|
170
|
+
end
|
171
|
+
|
172
|
+
let(:parsed_selector) do
|
173
|
+
{ b: 2 }
|
174
|
+
end
|
175
|
+
|
176
|
+
let(:query_selector) do
|
177
|
+
BSON::Document.new(:$query => { a: 1 }, :$someMod => 100, :$orderby => { a: Mongo::Index::ASCENDING })
|
178
|
+
end
|
179
|
+
|
180
|
+
it 'sets the modifiers' do
|
181
|
+
expect(view.instance_variable_get(:@modifiers)).to eq(expected_modifiers)
|
182
|
+
end
|
183
|
+
|
184
|
+
it 'removes the modifiers from the selector' do
|
185
|
+
expect(view.selector).to eq(parsed_selector)
|
186
|
+
end
|
187
|
+
|
188
|
+
it 'creates the correct query selector' do
|
189
|
+
expect(view.send(:query_spec)[:selector]).to eq(query_selector)
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
21
195
|
describe '#==' do
|
22
196
|
|
23
197
|
context 'when the other object is not a collection view' do
|
@@ -165,7 +339,7 @@ describe Mongo::Collection::View do
|
|
165
339
|
end
|
166
340
|
|
167
341
|
it 'sets the batch size on the initial query' do
|
168
|
-
expect(query_spec[:options][:
|
342
|
+
expect(query_spec[:options][:batch_size]).to eq(options[:batch_size])
|
169
343
|
end
|
170
344
|
|
171
345
|
it 'returns all the documents' do
|
@@ -232,7 +406,11 @@ describe Mongo::Collection::View do
|
|
232
406
|
end
|
233
407
|
|
234
408
|
it 'sets the batch size on the initial query' do
|
235
|
-
expect(query_spec[:options][:
|
409
|
+
expect(query_spec[:options][:batch_size]).to eq(options[:batch_size])
|
410
|
+
end
|
411
|
+
|
412
|
+
it 'sets the limit on the initial query' do
|
413
|
+
expect(query_spec[:options][:limit]).to eq(options[:limit])
|
236
414
|
end
|
237
415
|
|
238
416
|
it 'returns the limit of documents' do
|
@@ -396,7 +574,6 @@ describe Mongo::Collection::View do
|
|
396
574
|
context 'when the cluster is sharded', if: sharded? do
|
397
575
|
|
398
576
|
before do
|
399
|
-
allow(authorized_collection.cluster).to receive(:sharded?).and_return(true)
|
400
577
|
expect(view).to receive(:special_selector).and_call_original
|
401
578
|
end
|
402
579
|
|
@@ -405,6 +582,40 @@ describe Mongo::Collection::View do
|
|
405
582
|
expect(doc).to have_key('field')
|
406
583
|
end
|
407
584
|
end
|
585
|
+
|
586
|
+
context 'when there is a read preference' do
|
587
|
+
|
588
|
+
let(:collection) do
|
589
|
+
authorized_collection.with(read: { mode: :secondary})
|
590
|
+
end
|
591
|
+
|
592
|
+
let(:view) do
|
593
|
+
described_class.new(collection, selector, options)
|
594
|
+
end
|
595
|
+
|
596
|
+
let(:formatted_read_pref) do
|
597
|
+
BSON::Document.new(Mongo::ServerSelector.get(mode: :secondary).to_mongos)
|
598
|
+
end
|
599
|
+
|
600
|
+
it 'adds the formatted read preference to the selector' do
|
601
|
+
expect(view.send(:query_spec)[:selector][:$readPreference]).to eq(formatted_read_pref)
|
602
|
+
end
|
603
|
+
end
|
604
|
+
|
605
|
+
context 'when the read preference is primary' do
|
606
|
+
|
607
|
+
let(:collection) do
|
608
|
+
authorized_collection.with(read: { mode: :primary})
|
609
|
+
end
|
610
|
+
|
611
|
+
let(:view) do
|
612
|
+
described_class.new(collection, selector, options)
|
613
|
+
end
|
614
|
+
|
615
|
+
it 'does not add the formatted read preference to the selector' do
|
616
|
+
expect(view.send(:query_spec)[:selector][:$readPreference]).to be(nil)
|
617
|
+
end
|
618
|
+
end
|
408
619
|
end
|
409
620
|
|
410
621
|
context 'when a modifier document is provided' do
|
@@ -541,14 +752,11 @@ describe Mongo::Collection::View do
|
|
541
752
|
end
|
542
753
|
|
543
754
|
it 'overrides the modifier value with the option value' do
|
544
|
-
expect(query_spec[:selector][:$query]).to eq(
|
755
|
+
expect(query_spec[:selector][:$query]).to eq(options[:modifiers][:$query])
|
545
756
|
end
|
546
757
|
end
|
547
|
-
|
548
|
-
|
549
758
|
end
|
550
759
|
end
|
551
|
-
|
552
760
|
end
|
553
761
|
|
554
762
|
context 'when there are no special fields' do
|
@@ -578,6 +786,24 @@ describe Mongo::Collection::View do
|
|
578
786
|
end
|
579
787
|
end
|
580
788
|
end
|
789
|
+
|
790
|
+
describe '#close_query' do
|
791
|
+
|
792
|
+
let(:options) do
|
793
|
+
{ :batch_size => 1 }
|
794
|
+
end
|
795
|
+
|
796
|
+
before do
|
797
|
+
e = view.to_enum
|
798
|
+
e.next
|
799
|
+
cursor = view.instance_variable_get(:@cursor)
|
800
|
+
expect(cursor).to receive(:kill_cursors).and_call_original
|
801
|
+
end
|
802
|
+
|
803
|
+
it 'sends a kill cursors command for the cursor' do
|
804
|
+
view.close_query
|
805
|
+
end
|
806
|
+
end
|
581
807
|
end
|
582
808
|
|
583
809
|
describe '#hash' do
|