mongo 2.4.3 → 2.5.0.beta
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +3 -2
- data.tar.gz.sig +0 -0
- data/lib/mongo.rb +3 -2
- data/lib/mongo/auth/cr.rb +6 -4
- data/lib/mongo/auth/cr/conversation.rb +33 -17
- data/lib/mongo/auth/ldap.rb +4 -2
- data/lib/mongo/auth/ldap/conversation.rb +19 -9
- data/lib/mongo/auth/scram.rb +7 -4
- data/lib/mongo/auth/scram/conversation.rb +62 -24
- data/lib/mongo/auth/user.rb +10 -0
- data/lib/mongo/auth/user/view.rb +44 -22
- data/lib/mongo/auth/x509.rb +4 -2
- data/lib/mongo/auth/x509/conversation.rb +19 -9
- data/lib/mongo/bulk_write.rb +33 -27
- data/lib/mongo/bulk_write/combineable.rb +5 -0
- data/lib/mongo/bulk_write/transformable.rb +2 -0
- data/lib/mongo/bulk_write/validatable.rb +4 -0
- data/lib/mongo/client.rb +123 -12
- data/lib/mongo/cluster.rb +52 -11
- data/lib/mongo/cluster/app_metadata.rb +8 -2
- data/lib/mongo/cluster/cursor_reaper.rb +0 -1
- data/lib/mongo/cluster/topology.rb +1 -1
- data/lib/mongo/collection.rb +114 -27
- data/lib/mongo/collection/view.rb +8 -2
- data/lib/mongo/collection/view/aggregation.rb +11 -7
- data/lib/mongo/collection/view/builder/aggregation.rb +5 -1
- data/lib/mongo/collection/view/builder/find_command.rb +5 -3
- data/lib/mongo/collection/view/builder/map_reduce.rb +11 -3
- data/lib/mongo/collection/view/builder/op_query.rb +1 -1
- data/lib/mongo/collection/view/change_stream.rb +160 -0
- data/lib/mongo/collection/view/change_stream/retryable.rb +57 -0
- data/lib/mongo/collection/view/iterable.rb +11 -10
- data/lib/mongo/collection/view/map_reduce.rb +22 -18
- data/lib/mongo/collection/view/readable.rb +51 -37
- data/lib/mongo/collection/view/writable.rb +72 -40
- data/lib/mongo/cursor.rb +25 -4
- data/lib/mongo/cursor/builder/get_more_command.rb +4 -2
- data/lib/mongo/database.rb +22 -11
- data/lib/mongo/database/view.rb +16 -12
- data/lib/mongo/error.rb +5 -0
- data/lib/mongo/error/invalid_session.rb +36 -0
- data/lib/mongo/error/missing_resume_token.rb +39 -0
- data/lib/mongo/error/operation_failure.rb +17 -0
- data/lib/mongo/error/parser.rb +3 -2
- data/lib/mongo/error/unknown_payload_type.rb +41 -0
- data/lib/mongo/error/unsupported_array_filters.rb +51 -0
- data/lib/mongo/error/unsupported_message_type.rb +23 -0
- data/lib/mongo/grid/fs_bucket.rb +5 -4
- data/lib/mongo/grid/stream/read.rb +3 -2
- data/lib/mongo/grid/stream/write.rb +2 -2
- data/lib/mongo/index/view.rb +35 -25
- data/lib/mongo/monitoring/event/secure.rb +14 -0
- data/lib/mongo/operation.rb +16 -0
- data/lib/mongo/operation/commands.rb +1 -0
- data/lib/mongo/operation/commands/aggregate.rb +9 -5
- data/lib/mongo/operation/commands/aggregate/result.rb +1 -1
- data/lib/mongo/operation/commands/collections_info.rb +6 -6
- data/lib/mongo/operation/commands/command.rb +2 -1
- data/lib/mongo/operation/commands/create.rb +6 -2
- data/lib/mongo/operation/commands/drop.rb +6 -2
- data/lib/mongo/operation/commands/drop_database.rb +6 -2
- data/lib/mongo/operation/commands/explain.rb +27 -0
- data/lib/mongo/operation/commands/explain/result.rb +52 -0
- data/lib/mongo/operation/commands/indexes.rb +1 -1
- data/lib/mongo/operation/commands/list_collections.rb +1 -1
- data/lib/mongo/operation/commands/list_collections/result.rb +1 -1
- data/lib/mongo/operation/commands/list_indexes.rb +1 -1
- data/lib/mongo/operation/commands/list_indexes/result.rb +1 -1
- data/lib/mongo/operation/commands/map_reduce.rb +8 -4
- data/lib/mongo/operation/commands/map_reduce/result.rb +13 -1
- data/lib/mongo/operation/commands/user_query.rb +1 -1
- data/lib/mongo/operation/commands/users_info.rb +6 -2
- data/lib/mongo/operation/executable.rb +4 -1
- data/lib/mongo/operation/read_preference.rb +10 -5
- data/lib/mongo/operation/result.rb +26 -2
- data/lib/mongo/operation/specifiable.rb +13 -1
- data/lib/mongo/operation/uses_command_op_msg.rb +47 -0
- data/lib/mongo/operation/write/bulk/bulkable.rb +4 -1
- data/lib/mongo/operation/write/bulk/insert/result.rb +4 -4
- data/lib/mongo/operation/write/command/create_index.rb +6 -1
- data/lib/mongo/operation/write/command/delete.rb +28 -4
- data/lib/mongo/operation/write/command/drop_index.rb +6 -1
- data/lib/mongo/operation/write/command/insert.rb +22 -18
- data/lib/mongo/operation/write/command/update.rb +24 -9
- data/lib/mongo/operation/write/command/writable.rb +14 -1
- data/lib/mongo/operation/write/insert.rb +4 -1
- data/lib/mongo/operation/write/insert/result.rb +2 -2
- data/lib/mongo/operation/write/update.rb +7 -1
- data/lib/mongo/operation/write/write_command_enabled.rb +20 -3
- data/lib/mongo/protocol.rb +3 -0
- data/lib/mongo/protocol/bit_vector.rb +2 -2
- data/lib/mongo/protocol/compressed.rb +135 -0
- data/lib/mongo/protocol/delete.rb +8 -6
- data/lib/mongo/protocol/get_more.rb +8 -6
- data/lib/mongo/protocol/insert.rb +8 -6
- data/lib/mongo/protocol/kill_cursors.rb +8 -6
- data/lib/mongo/protocol/message.rb +31 -3
- data/lib/mongo/protocol/msg.rb +172 -0
- data/lib/mongo/protocol/query.rb +26 -6
- data/lib/mongo/protocol/registry.rb +76 -0
- data/lib/mongo/protocol/reply.rb +10 -5
- data/lib/mongo/protocol/serializers.rb +224 -0
- data/lib/mongo/protocol/update.rb +8 -6
- data/lib/mongo/retryable.rb +4 -2
- data/lib/mongo/server.rb +6 -3
- data/lib/mongo/server/connectable.rb +1 -1
- data/lib/mongo/server/connection.rb +30 -8
- data/lib/mongo/server/description.rb +25 -1
- data/lib/mongo/server/description/features.rb +4 -1
- data/lib/mongo/server/monitor.rb +5 -0
- data/lib/mongo/server/monitor/connection.rb +50 -2
- data/lib/mongo/server_selector/nearest.rb +10 -4
- data/lib/mongo/server_selector/primary.rb +20 -0
- data/lib/mongo/server_selector/primary_preferred.rb +10 -4
- data/lib/mongo/server_selector/secondary.rb +10 -4
- data/lib/mongo/server_selector/secondary_preferred.rb +24 -4
- data/lib/mongo/session.rb +180 -0
- data/lib/mongo/session/server_session.rb +73 -0
- data/lib/mongo/session/session_pool.rb +161 -0
- data/lib/mongo/uri.rb +11 -0
- data/lib/mongo/version.rb +1 -1
- data/mongo.gemspec +2 -1
- data/spec/mongo/auth/cr_spec.rb +12 -0
- data/spec/mongo/auth/ldap_spec.rb +2 -0
- data/spec/mongo/auth/scram/conversation_spec.rb +6 -6
- data/spec/mongo/auth/scram_spec.rb +25 -1
- data/spec/mongo/auth/user/view_spec.rb +268 -76
- data/spec/mongo/auth/x509_spec.rb +2 -0
- data/spec/mongo/bulk_write_spec.rb +435 -5
- data/spec/mongo/client_spec.rb +356 -39
- data/spec/mongo/cluster/app_metadata_spec.rb +2 -2
- data/spec/mongo/cluster_spec.rb +176 -0
- data/spec/mongo/collection/view/aggregation_spec.rb +33 -12
- data/spec/mongo/collection/view/builder/find_command_spec.rb +46 -6
- data/spec/mongo/collection/view/change_stream_spec.rb +814 -0
- data/spec/mongo/collection/view/map_reduce_spec.rb +94 -17
- data/spec/mongo/collection/view/readable_spec.rb +3 -12
- data/spec/mongo/collection_spec.rb +1048 -42
- data/spec/mongo/cursor/builder/get_more_command_spec.rb +19 -0
- data/spec/mongo/cursor_spec.rb +2 -2
- data/spec/mongo/database_spec.rb +50 -1
- data/spec/mongo/grid/fs_bucket_spec.rb +225 -137
- data/spec/mongo/grid/stream/read_spec.rb +2 -2
- data/spec/mongo/index/view_spec.rb +146 -8
- data/spec/mongo/monitoring/event/secure_spec.rb +42 -0
- data/spec/mongo/operation/read/query_spec.rb +2 -1
- data/spec/mongo/operation/specifiable_spec.rb +2 -2
- data/spec/mongo/operation/write/command/delete_spec.rb +96 -13
- data/spec/mongo/operation/write/command/insert_spec.rb +111 -12
- data/spec/mongo/operation/write/command/update_spec.rb +93 -10
- data/spec/mongo/operation/write/delete_spec.rb +1 -1
- data/spec/mongo/operation/write/insert_spec.rb +1 -1
- data/spec/mongo/operation/write/update_spec.rb +1 -1
- data/spec/mongo/protocol/compressed_spec.rb +66 -0
- data/spec/mongo/protocol/delete_spec.rb +14 -0
- data/spec/mongo/protocol/get_more_spec.rb +14 -0
- data/spec/mongo/protocol/insert_spec.rb +14 -0
- data/spec/mongo/protocol/kill_cursors_spec.rb +14 -0
- data/spec/mongo/protocol/msg_spec.rb +499 -0
- data/spec/mongo/protocol/query_spec.rb +45 -0
- data/spec/mongo/protocol/registry_spec.rb +31 -0
- data/spec/mongo/protocol/reply_spec.rb +14 -0
- data/spec/mongo/protocol/update_spec.rb +14 -0
- data/spec/mongo/retryable_spec.rb +6 -2
- data/spec/mongo/sdam_spec.rb +4 -0
- data/spec/mongo/server/connection_spec.rb +4 -2
- data/spec/mongo/server/description_spec.rb +28 -1
- data/spec/mongo/session/server_session_spec.rb +16 -0
- data/spec/mongo/session/session_pool_spec.rb +194 -0
- data/spec/mongo/uri_spec.rb +31 -2
- data/spec/spec_helper.rb +104 -0
- data/spec/support/authorization.rb +6 -1
- data/spec/support/crud.rb +3 -1
- data/spec/support/crud/write.rb +6 -1
- data/spec/support/crud_tests/write/findOneAndUpdate-arrayFilters.yml +69 -0
- data/spec/support/crud_tests/write/updateMany-arrayFilters.yml +63 -0
- data/spec/support/crud_tests/write/updateOne-arrayFilters.yml +109 -0
- data/spec/support/sdam/rs/discover_arbiters.yml +1 -1
- data/spec/support/sdam/rs/discover_passives.yml +2 -2
- data/spec/support/sdam/rs/discover_primary.yml +1 -1
- data/spec/support/sdam/rs/discover_secondary.yml +1 -1
- data/spec/support/sdam/rs/discovery.yml +4 -4
- data/spec/support/sdam/rs/equal_electionids.yml +1 -0
- data/spec/support/sdam/rs/ghost_discovered.yml +1 -1
- data/spec/support/sdam/rs/hosts_differ_from_seeds.yml +1 -1
- data/spec/support/sdam/rs/ls_timeout.yml +88 -0
- data/spec/support/sdam/rs/member_reconfig.yml +2 -2
- data/spec/support/sdam/rs/member_standalone.yml +2 -2
- data/spec/support/sdam/rs/new_primary.yml +2 -2
- data/spec/support/sdam/rs/new_primary_new_electionid.yml +3 -0
- data/spec/support/sdam/rs/new_primary_new_setversion.yml +3 -0
- data/spec/support/sdam/rs/new_primary_wrong_set_name.yml +2 -2
- data/spec/support/sdam/rs/non_rs_member.yml +1 -1
- data/spec/support/sdam/rs/normalize_case.yml +1 -1
- data/spec/support/sdam/rs/null_election_id.yml +4 -0
- data/spec/support/sdam/rs/primary_becomes_standalone.yml +2 -2
- data/spec/support/sdam/rs/primary_changes_set_name.yml +2 -2
- data/spec/support/sdam/rs/primary_disconnect.yml +2 -2
- data/spec/support/sdam/rs/primary_disconnect_electionid.yml +5 -0
- data/spec/support/sdam/rs/primary_disconnect_setversion.yml +5 -0
- data/spec/support/sdam/rs/primary_hint_from_secondary_with_mismatched_me.yml +58 -0
- data/spec/support/sdam/rs/primary_reports_new_member.yml +4 -4
- data/spec/support/sdam/rs/primary_to_no_primary_mismatched_me.yml +2 -2
- data/spec/support/sdam/rs/primary_wrong_set_name.yml +1 -1
- data/spec/support/sdam/rs/response_from_removed.yml +2 -2
- data/spec/support/sdam/rs/rsother_discovered.yml +1 -1
- data/spec/support/sdam/rs/sec_not_auth.yml +1 -1
- data/spec/support/sdam/rs/secondary_wrong_set_name.yml +1 -1
- data/spec/support/sdam/rs/secondary_wrong_set_name_with_primary.yml +2 -2
- data/spec/support/sdam/rs/setversion_without_electionid.yml +2 -0
- data/spec/support/sdam/rs/stepdown_change_set_name.yml +2 -2
- data/spec/support/sdam/rs/unexpected_mongos.yml +1 -1
- data/spec/support/sdam/rs/use_setversion_without_electionid.yml +3 -0
- data/spec/support/sdam/rs/wrong_set_name.yml +1 -1
- data/spec/support/sdam/sharded/ls_timeout_mongos.yml +97 -0
- data/spec/support/sdam/sharded/mongos_disconnect.yml +3 -3
- data/spec/support/sdam/sharded/multiple_mongoses.yml +1 -1
- data/spec/support/sdam/sharded/non_mongos_removed.yml +1 -1
- data/spec/support/sdam/sharded/normalize_uri_case.yml +1 -1
- data/spec/support/sdam/single/direct_connection_external_ip.yml +1 -1
- data/spec/support/sdam/single/direct_connection_mongos.yml +1 -1
- data/spec/support/sdam/single/direct_connection_rsarbiter.yml +1 -1
- data/spec/support/sdam/single/direct_connection_rsprimary.yml +1 -1
- data/spec/support/sdam/single/direct_connection_rssecondary.yml +1 -1
- data/spec/support/sdam/single/direct_connection_slave.yml +1 -1
- data/spec/support/sdam/single/direct_connection_standalone.yml +1 -1
- data/spec/support/sdam/single/ls_timeout_standalone.yml +35 -0
- data/spec/support/sdam/single/not_ok_response.yml +1 -1
- data/spec/support/sdam/single/standalone_removed.yml +1 -1
- data/spec/support/sdam/single/unavailable_seed.yml +1 -1
- data/spec/support/server_discovery_and_monitoring.rb +4 -0
- data/spec/support/shared/session.rb +236 -0
- metadata +53 -15
- metadata.gz.sig +0 -0
@@ -28,6 +28,25 @@ describe Mongo::Cursor::Builder::GetMoreCommand do
|
|
28
28
|
specification[:selector]
|
29
29
|
end
|
30
30
|
|
31
|
+
context 'when the operation has a session' do
|
32
|
+
|
33
|
+
let(:view) do
|
34
|
+
Mongo::Collection::View.new(authorized_collection)
|
35
|
+
end
|
36
|
+
|
37
|
+
let(:session) do
|
38
|
+
double('session')
|
39
|
+
end
|
40
|
+
|
41
|
+
let(:builder) do
|
42
|
+
described_class.new(cursor, session)
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'adds the session to the specification' do
|
46
|
+
expect(builder.specification[:session]).to be(session)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
31
50
|
shared_examples_for 'a getmore command builder' do
|
32
51
|
|
33
52
|
it 'includes the database name' do
|
data/spec/mongo/cursor_spec.rb
CHANGED
@@ -5,7 +5,7 @@ describe Mongo::Cursor do
|
|
5
5
|
describe '#each' do
|
6
6
|
|
7
7
|
let(:server) do
|
8
|
-
view.
|
8
|
+
view.send(:server_selector).select_server(authorized_client.cluster)
|
9
9
|
end
|
10
10
|
|
11
11
|
let(:reply) do
|
@@ -22,7 +22,7 @@ describe Mongo::Cursor do
|
|
22
22
|
Mongo::Collection::View.new(authorized_collection)
|
23
23
|
end
|
24
24
|
|
25
|
-
context 'when the initial query
|
25
|
+
context 'when the initial query retrieves all documents' do
|
26
26
|
|
27
27
|
let(:documents) do
|
28
28
|
(1..10).map{ |i| { field: "test#{i}" }}
|
data/spec/mongo/database_spec.rb
CHANGED
@@ -79,7 +79,8 @@ describe Mongo::Database do
|
|
79
79
|
end
|
80
80
|
|
81
81
|
it 'applies the options to the collection' do
|
82
|
-
expect(collection.
|
82
|
+
expect(collection.server_selector).to eq(Mongo::ServerSelector.get(mode: :secondary))
|
83
|
+
expect(collection.read_preference).to eq(BSON::Document.new(mode: :secondary))
|
83
84
|
end
|
84
85
|
end
|
85
86
|
end
|
@@ -106,6 +107,19 @@ describe Mongo::Database do
|
|
106
107
|
expect(database.collection_names).to_not include('system.indexes')
|
107
108
|
end
|
108
109
|
|
110
|
+
context 'when provided a session' do
|
111
|
+
|
112
|
+
let(:operation) do
|
113
|
+
database.collection_names(session: session)
|
114
|
+
end
|
115
|
+
|
116
|
+
let(:client) do
|
117
|
+
authorized_client
|
118
|
+
end
|
119
|
+
|
120
|
+
it_behaves_like 'an operation using a session'
|
121
|
+
end
|
122
|
+
|
109
123
|
context 'when specifying a batch size' do
|
110
124
|
|
111
125
|
it 'returns the stripped names of the collections' do
|
@@ -223,6 +237,28 @@ describe Mongo::Database do
|
|
223
237
|
expect(database.command(:ismaster => 1).written_count).to eq(0)
|
224
238
|
end
|
225
239
|
|
240
|
+
it 'does not mutate the command selector' do
|
241
|
+
expect(database.command({:ismaster => 1}.freeze).written_count).to eq(0)
|
242
|
+
end
|
243
|
+
|
244
|
+
context 'when provided a session' do
|
245
|
+
|
246
|
+
let(:operation) do
|
247
|
+
database.command({ :ismaster => 1 }, session: session)
|
248
|
+
end
|
249
|
+
|
250
|
+
let(:failed_operation) do
|
251
|
+
database.command({ :invalid => 1 }, session: session)
|
252
|
+
end
|
253
|
+
|
254
|
+
let(:client) do
|
255
|
+
authorized_client
|
256
|
+
end
|
257
|
+
|
258
|
+
it_behaves_like 'an operation using a session'
|
259
|
+
it_behaves_like 'a failed operation using a session'
|
260
|
+
end
|
261
|
+
|
226
262
|
context 'when a read concern is provided', if: find_command_enabled? do
|
227
263
|
|
228
264
|
context 'when the read concern is valid' do
|
@@ -409,6 +445,19 @@ describe Mongo::Database do
|
|
409
445
|
}.to raise_error(Mongo::Error::OperationFailure)
|
410
446
|
end
|
411
447
|
|
448
|
+
context 'when provided a session' do
|
449
|
+
|
450
|
+
let(:operation) do
|
451
|
+
database.drop(session: session)
|
452
|
+
end
|
453
|
+
|
454
|
+
let(:client) do
|
455
|
+
authorized_client
|
456
|
+
end
|
457
|
+
|
458
|
+
it_behaves_like 'an operation using a session'
|
459
|
+
end
|
460
|
+
|
412
461
|
context 'when the client/database has a write concern' do
|
413
462
|
|
414
463
|
let(:client_options) do
|
@@ -3,7 +3,11 @@ require 'spec_helper'
|
|
3
3
|
describe Mongo::Grid::FSBucket do
|
4
4
|
|
5
5
|
let(:fs) do
|
6
|
-
described_class.new(
|
6
|
+
described_class.new(client.database, options)
|
7
|
+
end
|
8
|
+
|
9
|
+
let(:client) do
|
10
|
+
authorized_client
|
7
11
|
end
|
8
12
|
|
9
13
|
let(:options) do
|
@@ -54,12 +58,8 @@ describe Mongo::Grid::FSBucket do
|
|
54
58
|
{ read: { mode: :secondary } }
|
55
59
|
end
|
56
60
|
|
57
|
-
let(:read_pref) do
|
58
|
-
Mongo::ServerSelector.get(Mongo::Options::Redacted.new(options[:read].merge(authorized_client.options)))
|
59
|
-
end
|
60
|
-
|
61
61
|
it 'sets the read preference' do
|
62
|
-
expect(fs.send(:read_preference)).to eq(
|
62
|
+
expect(fs.send(:read_preference)).to eq(options[:read])
|
63
63
|
end
|
64
64
|
end
|
65
65
|
|
@@ -486,7 +486,7 @@ describe Mongo::Grid::FSBucket do
|
|
486
486
|
context 'when a read stream is opened' do
|
487
487
|
|
488
488
|
let(:fs) do
|
489
|
-
described_class.new(authorized_client.database)
|
489
|
+
described_class.new(authorized_client.database, options)
|
490
490
|
end
|
491
491
|
|
492
492
|
let(:io) do
|
@@ -594,6 +594,29 @@ describe Mongo::Grid::FSBucket do
|
|
594
594
|
|
595
595
|
describe '#download_to_stream' do
|
596
596
|
|
597
|
+
context 'sessions' do
|
598
|
+
|
599
|
+
let(:options) do
|
600
|
+
{ session: session }
|
601
|
+
end
|
602
|
+
|
603
|
+
let(:file_id) do
|
604
|
+
fs.open_upload_stream(filename) do |stream|
|
605
|
+
stream.write(file)
|
606
|
+
end.file_id
|
607
|
+
end
|
608
|
+
|
609
|
+
let(:operation) do
|
610
|
+
fs.download_to_stream(file_id, io)
|
611
|
+
end
|
612
|
+
|
613
|
+
let(:client) do
|
614
|
+
authorized_client
|
615
|
+
end
|
616
|
+
|
617
|
+
it_behaves_like 'an operation using a session'
|
618
|
+
end
|
619
|
+
|
597
620
|
context 'when the file is found' do
|
598
621
|
|
599
622
|
let!(:file_id) do
|
@@ -678,12 +701,13 @@ describe Mongo::Grid::FSBucket do
|
|
678
701
|
end
|
679
702
|
|
680
703
|
it 'sets the read preference on the Stream::Read object' do
|
681
|
-
expect(stream.read_preference).to eq(
|
704
|
+
expect(stream.read_preference).to eq(options[:read])
|
682
705
|
end
|
683
706
|
end
|
684
707
|
|
685
708
|
describe '#download_to_stream_by_name' do
|
686
709
|
|
710
|
+
|
687
711
|
let(:files) do
|
688
712
|
[
|
689
713
|
StringIO.new('hello 1'),
|
@@ -693,75 +717,105 @@ describe Mongo::Grid::FSBucket do
|
|
693
717
|
]
|
694
718
|
end
|
695
719
|
|
696
|
-
|
697
|
-
|
698
|
-
|
720
|
+
context ' when using a session' do
|
721
|
+
|
722
|
+
let(:options) do
|
723
|
+
{ session: session }
|
699
724
|
end
|
700
|
-
end
|
701
725
|
|
702
|
-
|
703
|
-
|
704
|
-
|
726
|
+
let(:operation) do
|
727
|
+
fs.download_to_stream_by_name('test.txt', io)
|
728
|
+
end
|
705
729
|
|
706
|
-
|
730
|
+
let(:client) do
|
731
|
+
authorized_client
|
732
|
+
end
|
707
733
|
|
708
|
-
|
709
|
-
|
734
|
+
before do
|
735
|
+
files.each do |file|
|
736
|
+
authorized_client.database.fs.upload_from_stream('test.txt', file)
|
737
|
+
end
|
710
738
|
end
|
711
739
|
|
712
|
-
|
713
|
-
|
740
|
+
let(:io) do
|
741
|
+
StringIO.new
|
714
742
|
end
|
743
|
+
|
744
|
+
it_behaves_like 'an operation using a session'
|
715
745
|
end
|
716
746
|
|
717
|
-
context 'when
|
747
|
+
context 'when not using a session' do
|
718
748
|
|
719
|
-
|
720
|
-
|
749
|
+
before do
|
750
|
+
files.each do |file|
|
751
|
+
fs.upload_from_stream('test.txt', file)
|
752
|
+
end
|
721
753
|
end
|
722
754
|
|
723
|
-
|
724
|
-
|
755
|
+
let(:io) do
|
756
|
+
StringIO.new
|
725
757
|
end
|
726
|
-
end
|
727
758
|
|
728
|
-
|
759
|
+
context 'when revision is not specified' do
|
760
|
+
|
761
|
+
let!(:result) do
|
762
|
+
fs.download_to_stream_by_name('test.txt', io)
|
763
|
+
end
|
729
764
|
|
730
|
-
|
731
|
-
|
765
|
+
it 'returns the most recent version' do
|
766
|
+
expect(io.string).to eq('hello 4')
|
767
|
+
end
|
732
768
|
end
|
733
769
|
|
734
|
-
|
735
|
-
|
770
|
+
context 'when revision is 0' do
|
771
|
+
|
772
|
+
let!(:result) do
|
773
|
+
fs.download_to_stream_by_name('test.txt', io, revision: 0)
|
774
|
+
end
|
775
|
+
|
776
|
+
it 'returns the original stored file' do
|
777
|
+
expect(io.string).to eq('hello 1')
|
778
|
+
end
|
736
779
|
end
|
737
|
-
end
|
738
780
|
|
739
|
-
|
781
|
+
context 'when revision is negative' do
|
782
|
+
|
783
|
+
let!(:result) do
|
784
|
+
fs.download_to_stream_by_name('test.txt', io, revision: -2)
|
785
|
+
end
|
740
786
|
|
741
|
-
|
742
|
-
|
787
|
+
it 'returns that number of versions from the most recent' do
|
788
|
+
expect(io.string).to eq('hello 3')
|
789
|
+
end
|
743
790
|
end
|
744
791
|
|
745
|
-
|
746
|
-
|
792
|
+
context 'when revision is positive' do
|
793
|
+
|
794
|
+
let!(:result) do
|
795
|
+
fs.download_to_stream_by_name('test.txt', io, revision: 1)
|
796
|
+
end
|
797
|
+
|
798
|
+
it 'returns that number revision' do
|
799
|
+
expect(io.string).to eq('hello 2')
|
800
|
+
end
|
747
801
|
end
|
748
|
-
end
|
749
802
|
|
750
|
-
|
803
|
+
context 'when the file revision is not found' do
|
751
804
|
|
752
|
-
|
753
|
-
|
754
|
-
|
755
|
-
|
805
|
+
it 'raises a FileNotFound error' do
|
806
|
+
expect {
|
807
|
+
fs.download_to_stream_by_name('test.txt', io, revision: 100)
|
808
|
+
}.to raise_exception(Mongo::Error::InvalidFileRevision)
|
809
|
+
end
|
756
810
|
end
|
757
|
-
end
|
758
811
|
|
759
|
-
|
812
|
+
context 'when the file is not found' do
|
760
813
|
|
761
|
-
|
762
|
-
|
763
|
-
|
764
|
-
|
814
|
+
it 'raises a FileNotFound error' do
|
815
|
+
expect {
|
816
|
+
fs.download_to_stream_by_name('non-existent.txt', io)
|
817
|
+
}.to raise_exception(Mongo::Error::FileNotFound)
|
818
|
+
end
|
765
819
|
end
|
766
820
|
end
|
767
821
|
end
|
@@ -777,124 +831,154 @@ describe Mongo::Grid::FSBucket do
|
|
777
831
|
]
|
778
832
|
end
|
779
833
|
|
780
|
-
before do
|
781
|
-
files.each do |file|
|
782
|
-
fs.upload_from_stream('test.txt', file)
|
783
|
-
end
|
784
|
-
end
|
785
|
-
|
786
834
|
let(:io) do
|
787
835
|
StringIO.new
|
788
836
|
end
|
789
837
|
|
790
|
-
context 'when a
|
838
|
+
context ' when using a session' do
|
791
839
|
|
792
|
-
let(:
|
793
|
-
|
794
|
-
io.write(stream.read)
|
795
|
-
end
|
840
|
+
let(:options) do
|
841
|
+
{ session: session }
|
796
842
|
end
|
797
843
|
|
798
|
-
|
799
|
-
|
844
|
+
let(:operation) do
|
845
|
+
fs.download_to_stream_by_name('test.txt', io)
|
800
846
|
end
|
801
847
|
|
802
|
-
|
803
|
-
|
848
|
+
let(:client) do
|
849
|
+
authorized_client
|
804
850
|
end
|
805
851
|
|
806
|
-
|
807
|
-
|
808
|
-
|
852
|
+
before do
|
853
|
+
files.each do |file|
|
854
|
+
authorized_client.database.fs.upload_from_stream('test.txt', file)
|
855
|
+
end
|
809
856
|
end
|
810
857
|
|
811
|
-
|
858
|
+
let(:io) do
|
859
|
+
StringIO.new
|
860
|
+
end
|
812
861
|
|
813
|
-
|
814
|
-
|
815
|
-
io.write(stream.read)
|
816
|
-
end
|
817
|
-
end
|
862
|
+
it_behaves_like 'an operation using a session'
|
863
|
+
end
|
818
864
|
|
819
|
-
|
820
|
-
|
865
|
+
context 'when not using a session' do
|
866
|
+
|
867
|
+
before do
|
868
|
+
files.each do |file|
|
869
|
+
fs.upload_from_stream('test.txt', file)
|
821
870
|
end
|
822
871
|
end
|
823
872
|
|
824
|
-
context 'when
|
873
|
+
context 'when a block is provided' do
|
825
874
|
|
826
|
-
let
|
827
|
-
fs.open_download_stream_by_name('test.txt'
|
875
|
+
let(:stream) do
|
876
|
+
fs.open_download_stream_by_name('test.txt') do |stream|
|
828
877
|
io.write(stream.read)
|
829
878
|
end
|
830
879
|
end
|
831
880
|
|
832
|
-
it 'returns
|
833
|
-
expect(
|
881
|
+
it 'returns a Stream::Read object' do
|
882
|
+
expect(stream).to be_a(Mongo::Grid::FSBucket::Stream::Read)
|
834
883
|
end
|
835
|
-
end
|
836
884
|
|
837
|
-
|
885
|
+
it 'closes the stream after the block completes' do
|
886
|
+
expect(stream.closed?).to be(true)
|
887
|
+
end
|
838
888
|
|
839
|
-
|
840
|
-
|
841
|
-
|
889
|
+
it 'yields the stream to the block' do
|
890
|
+
stream
|
891
|
+
expect(io.size).to eq(files[0].size)
|
892
|
+
end
|
893
|
+
|
894
|
+
context 'when revision is not specified' do
|
895
|
+
|
896
|
+
let!(:result) do
|
897
|
+
fs.open_download_stream_by_name('test.txt') do |stream|
|
898
|
+
io.write(stream.read)
|
899
|
+
end
|
900
|
+
end
|
901
|
+
|
902
|
+
it 'returns the most recent version' do
|
903
|
+
expect(io.string).to eq('hello 4')
|
842
904
|
end
|
843
905
|
end
|
844
906
|
|
845
|
-
|
846
|
-
|
907
|
+
context 'when revision is 0' do
|
908
|
+
|
909
|
+
let!(:result) do
|
910
|
+
fs.open_download_stream_by_name('test.txt', revision: 0) do |stream|
|
911
|
+
io.write(stream.read)
|
912
|
+
end
|
913
|
+
end
|
914
|
+
|
915
|
+
it 'returns the original stored file' do
|
916
|
+
expect(io.string).to eq('hello 1')
|
917
|
+
end
|
847
918
|
end
|
848
|
-
end
|
849
919
|
|
850
|
-
|
920
|
+
context 'when revision is negative' do
|
851
921
|
|
852
|
-
|
853
|
-
|
854
|
-
|
922
|
+
let!(:result) do
|
923
|
+
fs.open_download_stream_by_name('test.txt', revision: -2) do |stream|
|
924
|
+
io.write(stream.read)
|
925
|
+
end
|
926
|
+
end
|
927
|
+
|
928
|
+
it 'returns that number of versions from the most recent' do
|
929
|
+
expect(io.string).to eq('hello 3')
|
855
930
|
end
|
856
931
|
end
|
857
932
|
|
858
|
-
|
859
|
-
|
933
|
+
context 'when revision is positive' do
|
934
|
+
|
935
|
+
let!(:result) do
|
936
|
+
fs.open_download_stream_by_name('test.txt', revision: 1) do |stream|
|
937
|
+
io.write(stream.read)
|
938
|
+
end
|
939
|
+
end
|
940
|
+
|
941
|
+
it 'returns that number revision' do
|
942
|
+
expect(io.string).to eq('hello 2')
|
943
|
+
end
|
860
944
|
end
|
861
|
-
end
|
862
945
|
|
863
|
-
|
946
|
+
context 'when the file revision is not found' do
|
864
947
|
|
865
|
-
|
866
|
-
|
867
|
-
|
868
|
-
|
948
|
+
it 'raises a FileNotFound error' do
|
949
|
+
expect {
|
950
|
+
fs.open_download_stream_by_name('test.txt', revision: 100)
|
951
|
+
}.to raise_exception(Mongo::Error::InvalidFileRevision)
|
952
|
+
end
|
869
953
|
end
|
870
|
-
end
|
871
954
|
|
872
|
-
|
955
|
+
context 'when the file is not found' do
|
873
956
|
|
874
|
-
|
875
|
-
|
876
|
-
|
877
|
-
|
957
|
+
it 'raises a FileNotFound error' do
|
958
|
+
expect {
|
959
|
+
fs.open_download_stream_by_name('non-existent.txt')
|
960
|
+
}.to raise_exception(Mongo::Error::FileNotFound)
|
961
|
+
end
|
878
962
|
end
|
879
963
|
end
|
880
|
-
end
|
881
964
|
|
882
|
-
|
965
|
+
context 'when a block is not provided' do
|
883
966
|
|
884
|
-
|
885
|
-
|
886
|
-
|
967
|
+
let!(:stream) do
|
968
|
+
fs.open_download_stream_by_name('test.txt')
|
969
|
+
end
|
887
970
|
|
888
|
-
|
889
|
-
|
890
|
-
|
971
|
+
it 'returns a Stream::Read object' do
|
972
|
+
expect(stream).to be_a(Mongo::Grid::FSBucket::Stream::Read)
|
973
|
+
end
|
891
974
|
|
892
|
-
|
893
|
-
|
894
|
-
|
975
|
+
it 'does not close the stream' do
|
976
|
+
expect(stream.closed?).to be(false)
|
977
|
+
end
|
895
978
|
|
896
|
-
|
897
|
-
|
979
|
+
it 'does not yield the stream to the block' do
|
980
|
+
expect(io.size).to eq(0)
|
981
|
+
end
|
898
982
|
end
|
899
983
|
end
|
900
984
|
end
|
@@ -941,32 +1025,36 @@ describe Mongo::Grid::FSBucket do
|
|
941
1025
|
|
942
1026
|
context 'when a block is provided' do
|
943
1027
|
|
944
|
-
|
945
|
-
|
946
|
-
|
1028
|
+
context 'when a session is not used' do
|
1029
|
+
|
1030
|
+
let!(:stream) do
|
1031
|
+
fs.open_upload_stream(filename) do |stream|
|
1032
|
+
stream.write(file)
|
1033
|
+
end
|
947
1034
|
end
|
948
|
-
end
|
949
1035
|
|
950
|
-
|
951
|
-
|
952
|
-
|
1036
|
+
let(:result) do
|
1037
|
+
fs.find_one(filename: filename)
|
1038
|
+
end
|
953
1039
|
|
954
|
-
|
955
|
-
|
956
|
-
|
1040
|
+
it 'returns the stream' do
|
1041
|
+
expect(stream).to be_a(Mongo::Grid::FSBucket::Stream::Write)
|
1042
|
+
end
|
957
1043
|
|
958
|
-
|
959
|
-
|
960
|
-
|
1044
|
+
it 'creates an ObjectId for the file' do
|
1045
|
+
expect(stream.file_id).to be_a(BSON::ObjectId)
|
1046
|
+
end
|
961
1047
|
|
962
|
-
|
963
|
-
|
964
|
-
|
1048
|
+
it 'yields the stream to the block' do
|
1049
|
+
expect(result.data.size).to eq(file.size)
|
1050
|
+
end
|
965
1051
|
|
966
|
-
|
967
|
-
|
1052
|
+
it 'closes the stream when the block completes' do
|
1053
|
+
expect(stream.closed?).to be(true)
|
1054
|
+
end
|
968
1055
|
end
|
969
1056
|
end
|
1057
|
+
|
970
1058
|
end
|
971
1059
|
|
972
1060
|
describe '#upload_from_stream' do
|