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
@@ -0,0 +1,64 @@
|
|
1
|
+
# Copyright (C) 2014-2015 MongoDB, Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
require 'mongo/grid/stream/read'
|
16
|
+
require 'mongo/grid/stream/write'
|
17
|
+
|
18
|
+
module Mongo
|
19
|
+
module Grid
|
20
|
+
class FSBucket
|
21
|
+
|
22
|
+
# A stream that reads and writes files from/to the FSBucket.
|
23
|
+
#
|
24
|
+
# @since 2.1.0
|
25
|
+
module Stream
|
26
|
+
extend self
|
27
|
+
|
28
|
+
# The symbol for opening a read stream.
|
29
|
+
#
|
30
|
+
# @since 2.1.0
|
31
|
+
READ_MODE = :r
|
32
|
+
|
33
|
+
# The symbol for opening a write stream.
|
34
|
+
#
|
35
|
+
# @since 2.1.0
|
36
|
+
WRITE_MODE = :w
|
37
|
+
|
38
|
+
# Mapping from mode to stream class.
|
39
|
+
#
|
40
|
+
# @since 2.1.0
|
41
|
+
MODE_MAP = {
|
42
|
+
READ_MODE => Read,
|
43
|
+
WRITE_MODE => Write
|
44
|
+
}.freeze
|
45
|
+
|
46
|
+
# Get a stream for reading/writing files from/to the FSBucket.
|
47
|
+
#
|
48
|
+
# @example Get a stream.
|
49
|
+
# FSBucket::Stream.get(fs, FSBucket::READ_MODE, options)
|
50
|
+
#
|
51
|
+
# @param [ FSBucket ] fs The GridFS bucket object.
|
52
|
+
# @param [ FSBucket::READ_MODE, FSBucket::WRITE_MODE ] mode The stream mode.
|
53
|
+
# @param [ Hash ] options The stream options.
|
54
|
+
#
|
55
|
+
# @return [ Stream::Read, Stream::Write ] The stream object.
|
56
|
+
#
|
57
|
+
# @since 2.1.0
|
58
|
+
def get(fs, mode, options = {})
|
59
|
+
MODE_MAP[mode].new(fs, options)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,208 @@
|
|
1
|
+
# Copyright (C) 2014-2015 MongoDB, Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
module Mongo
|
16
|
+
module Grid
|
17
|
+
class FSBucket
|
18
|
+
|
19
|
+
module Stream
|
20
|
+
# A stream that reads files from the FSBucket.
|
21
|
+
#
|
22
|
+
# @since 2.1.0
|
23
|
+
class Read
|
24
|
+
include Enumerable
|
25
|
+
|
26
|
+
# @return [ FSBucket ] fs The fs bucket from which this stream reads.
|
27
|
+
#
|
28
|
+
# @since 2.1.0
|
29
|
+
attr_reader :fs
|
30
|
+
|
31
|
+
# @return [ Hash ] options The stream options.
|
32
|
+
#
|
33
|
+
# @since 2.1.0
|
34
|
+
attr_reader :options
|
35
|
+
|
36
|
+
# @return [ BSON::ObjectId, Object ] file_id The id of the file being read.
|
37
|
+
#
|
38
|
+
# @since 2.1.0
|
39
|
+
attr_reader :file_id
|
40
|
+
|
41
|
+
# Create a stream for reading files from the FSBucket.
|
42
|
+
#
|
43
|
+
# @example Create the stream.
|
44
|
+
# Stream::Read.new(fs, options)
|
45
|
+
#
|
46
|
+
# @param [ FSBucket ] fs The GridFS bucket object.
|
47
|
+
# @param [ Hash ] options The read stream options.
|
48
|
+
#
|
49
|
+
# @since 2.1.0
|
50
|
+
def initialize(fs, options)
|
51
|
+
@fs = fs
|
52
|
+
@options = options.dup
|
53
|
+
@file_id = @options.delete(:file_id)
|
54
|
+
@open = true
|
55
|
+
end
|
56
|
+
|
57
|
+
# Iterate through chunk data streamed from the FSBucket.
|
58
|
+
#
|
59
|
+
# @example Iterate through the chunk data.
|
60
|
+
# stream.each do |data|
|
61
|
+
# buffer << data
|
62
|
+
# end
|
63
|
+
#
|
64
|
+
# @return [ Enumerator ] The enumerator.
|
65
|
+
#
|
66
|
+
# @raise [ Error::MissingFileChunk ] If a chunk is found out of sequence.
|
67
|
+
#
|
68
|
+
# @yieldparam [ Hash ] Each chunk of file data.
|
69
|
+
#
|
70
|
+
# @since 2.1.0
|
71
|
+
def each
|
72
|
+
ensure_readable!
|
73
|
+
num_chunks = (file_info.length + file_info.chunk_size - 1) / file_info.chunk_size
|
74
|
+
view.each_with_index.reduce(0) do |length_read, (doc, index)|
|
75
|
+
chunk = Grid::File::Chunk.new(doc)
|
76
|
+
validate!(index, num_chunks, chunk, length_read)
|
77
|
+
data = Grid::File::Chunk.assemble([ chunk ])
|
78
|
+
yield data
|
79
|
+
length_read += data.size
|
80
|
+
end if block_given?
|
81
|
+
view.to_enum
|
82
|
+
end
|
83
|
+
|
84
|
+
# Read all file data.
|
85
|
+
#
|
86
|
+
# @example Read the file data.
|
87
|
+
# stream.read
|
88
|
+
#
|
89
|
+
# @return [ String ] The file data.
|
90
|
+
#
|
91
|
+
# @raise [ Error::MissingFileChunk ] If a chunk is found out of sequence.
|
92
|
+
#
|
93
|
+
# @since 2.1.0
|
94
|
+
def read
|
95
|
+
to_a.join
|
96
|
+
end
|
97
|
+
|
98
|
+
# Close the read stream.
|
99
|
+
#
|
100
|
+
# @example Close the stream.
|
101
|
+
# stream.close
|
102
|
+
#
|
103
|
+
# @return [ BSON::ObjectId, Object ] The file id.
|
104
|
+
#
|
105
|
+
# @raise [ Error::ClosedStream ] If the stream is already closed.
|
106
|
+
#
|
107
|
+
# @since 2.1.0
|
108
|
+
def close
|
109
|
+
ensure_open!
|
110
|
+
view.close_query
|
111
|
+
@open = false
|
112
|
+
file_id
|
113
|
+
end
|
114
|
+
|
115
|
+
# Is the stream closed.
|
116
|
+
#
|
117
|
+
# @example Is the stream closd.
|
118
|
+
# stream.closed?
|
119
|
+
#
|
120
|
+
# @return [ true, false ] Whether the stream is closed.
|
121
|
+
#
|
122
|
+
# @since 2.1.0
|
123
|
+
def closed?
|
124
|
+
!@open
|
125
|
+
end
|
126
|
+
|
127
|
+
# Get the read preference used when streaming.
|
128
|
+
#
|
129
|
+
# @example Get the read preference.
|
130
|
+
# stream.read_preference
|
131
|
+
#
|
132
|
+
# @return [ Mongo::ServerSelector ] The read preference.
|
133
|
+
#
|
134
|
+
# @since 2.1.0
|
135
|
+
def read_preference
|
136
|
+
@read_preference ||= @options[:read] ?
|
137
|
+
ServerSelector.get((@options[:read] || {}).merge(fs.options)) :
|
138
|
+
fs.read_preference
|
139
|
+
end
|
140
|
+
|
141
|
+
# Get the files collection file information document for the file being read.
|
142
|
+
#
|
143
|
+
# @example Get the file info document.
|
144
|
+
# stream.file_info
|
145
|
+
#
|
146
|
+
# @return [ Hash ] The file info document.
|
147
|
+
#
|
148
|
+
# @since 2.1.0
|
149
|
+
def file_info
|
150
|
+
doc = fs.files_collection.find(_id: file_id).first
|
151
|
+
if doc
|
152
|
+
@file_info ||= File::Info.new(Options::Mapper.transform(doc, File::Info::MAPPINGS.invert))
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
private
|
157
|
+
|
158
|
+
def ensure_open!
|
159
|
+
raise Error::ClosedStream.new if closed?
|
160
|
+
end
|
161
|
+
|
162
|
+
def ensure_file_info!
|
163
|
+
raise Error::FileNotFound.new(file_id, :id) unless file_info
|
164
|
+
end
|
165
|
+
|
166
|
+
def ensure_readable!
|
167
|
+
ensure_open!
|
168
|
+
ensure_file_info!
|
169
|
+
end
|
170
|
+
|
171
|
+
def view
|
172
|
+
@view ||= fs.chunks_collection.find({ :files_id => file_id }, options).read(read_preference).sort(:n => 1)
|
173
|
+
end
|
174
|
+
|
175
|
+
def validate!(index, num_chunks, chunk, length_read)
|
176
|
+
validate_n!(index, chunk)
|
177
|
+
validate_length!(index, num_chunks, chunk, length_read)
|
178
|
+
end
|
179
|
+
|
180
|
+
def raise_unexpected_chunk_length!(chunk)
|
181
|
+
close
|
182
|
+
raise Error::UnexpectedChunkLength.new(file_info.chunk_size, chunk)
|
183
|
+
end
|
184
|
+
|
185
|
+
def validate_length!(index, num_chunks, chunk, length_read)
|
186
|
+
if num_chunks > 0 && chunk.data.data.size > 0
|
187
|
+
raise Error::ExtraFileChunk.new unless index < num_chunks
|
188
|
+
if index == num_chunks - 1
|
189
|
+
unless chunk.data.data.size + length_read == file_info.length
|
190
|
+
raise_unexpected_chunk_length!(chunk)
|
191
|
+
end
|
192
|
+
elsif chunk.data.data.size != file_info.chunk_size
|
193
|
+
raise_unexpected_chunk_length!(chunk)
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
def validate_n!(index, chunk)
|
199
|
+
unless index == chunk.n
|
200
|
+
close
|
201
|
+
raise Error::MissingFileChunk.new(index, chunk)
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
@@ -0,0 +1,187 @@
|
|
1
|
+
# Copyright (C) 2014-2015 MongoDB, Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
module Mongo
|
16
|
+
module Grid
|
17
|
+
class FSBucket
|
18
|
+
|
19
|
+
module Stream
|
20
|
+
# A stream that writes files to the FSBucket.
|
21
|
+
#
|
22
|
+
# @since 2.1.0
|
23
|
+
class Write
|
24
|
+
|
25
|
+
# @return [ FSBucket ] fs The fs bucket to which this stream writes.
|
26
|
+
#
|
27
|
+
# @since 2.1.0
|
28
|
+
attr_reader :fs
|
29
|
+
|
30
|
+
# @return [ BSON::ObjectId ] file_id The id of the file being uploaded.
|
31
|
+
#
|
32
|
+
# @since 2.1.0
|
33
|
+
attr_reader :file_id
|
34
|
+
|
35
|
+
# @return [ String ] filename The name of the file being uploaded.
|
36
|
+
#
|
37
|
+
# @since 2.1.0
|
38
|
+
attr_reader :filename
|
39
|
+
|
40
|
+
# @return [ Hash ] options The write stream options.
|
41
|
+
#
|
42
|
+
# @since 2.1.0
|
43
|
+
attr_reader :options
|
44
|
+
|
45
|
+
# Create a stream for writing files to the FSBucket.
|
46
|
+
#
|
47
|
+
# @example Create the stream.
|
48
|
+
# Stream::Write.new(fs, options)
|
49
|
+
#
|
50
|
+
# @param [ FSBucket ] fs The GridFS bucket object.
|
51
|
+
# @param [ Hash ] options The write stream options.
|
52
|
+
#
|
53
|
+
# @option opts [ Integer ] :chunk_size Override the default chunk size.
|
54
|
+
# @option opts [ Hash ] :write The write concern.
|
55
|
+
# @option opts [ Hash ] :metadata User data for the 'metadata' field of the files collection document.
|
56
|
+
# @option opts [ String ] :content_type The content type of the file.
|
57
|
+
# Deprecated, please use the metadata document instead.
|
58
|
+
# @option opts [ Array<String> ] :aliases A list of aliases.
|
59
|
+
# Deprecated, please use the metadata document instead.
|
60
|
+
#
|
61
|
+
# @since 2.1.0
|
62
|
+
def initialize(fs, options)
|
63
|
+
@fs = fs
|
64
|
+
@length = 0
|
65
|
+
@n = 0
|
66
|
+
@file_id = BSON::ObjectId.new
|
67
|
+
@options = options
|
68
|
+
@filename = @options[:filename]
|
69
|
+
@open = true
|
70
|
+
end
|
71
|
+
|
72
|
+
# Write to the GridFS bucket from the source stream.
|
73
|
+
#
|
74
|
+
# @example Write to GridFS.
|
75
|
+
# stream.write(io)
|
76
|
+
#
|
77
|
+
# @param [ IO ] io The source io stream to upload from.
|
78
|
+
#
|
79
|
+
# @return [ Stream::Write ] self The write stream itself.
|
80
|
+
#
|
81
|
+
# @since 2.1.0
|
82
|
+
def write(io)
|
83
|
+
ensure_open!
|
84
|
+
@indexes ||= ensure_indexes!
|
85
|
+
data = io.read
|
86
|
+
@length += data.length
|
87
|
+
chunks = File::Chunk.split(data, file_info, @n)
|
88
|
+
@n += chunks.size
|
89
|
+
chunks_collection.insert_many(chunks) unless chunks.empty?
|
90
|
+
self
|
91
|
+
end
|
92
|
+
|
93
|
+
# Close the write stream.
|
94
|
+
#
|
95
|
+
# @example Close the stream.
|
96
|
+
# stream.close
|
97
|
+
#
|
98
|
+
# @return [ BSON::ObjectId, Object ] The file id.
|
99
|
+
#
|
100
|
+
# @raise [ Error::ClosedStream ] If the stream is already closed.
|
101
|
+
#
|
102
|
+
# @since 2.1.0
|
103
|
+
def close
|
104
|
+
ensure_open!
|
105
|
+
update_length
|
106
|
+
files_collection.insert_one(file_info)
|
107
|
+
@open = false
|
108
|
+
file_id
|
109
|
+
end
|
110
|
+
|
111
|
+
# Get the write concern used when uploading.
|
112
|
+
#
|
113
|
+
# @example Get the write concern.
|
114
|
+
# stream.write_concern
|
115
|
+
#
|
116
|
+
# @return [ Mongo::WriteConcern ] The write concern.
|
117
|
+
#
|
118
|
+
# @since 2.1.0
|
119
|
+
def write_concern
|
120
|
+
@write_concern ||= @options[:write] ? WriteConcern.get(@options[:write]) :
|
121
|
+
fs.write_concern
|
122
|
+
end
|
123
|
+
|
124
|
+
# Is the stream closed.
|
125
|
+
#
|
126
|
+
# @example Is the stream closed.
|
127
|
+
# stream.closed?
|
128
|
+
#
|
129
|
+
# @return [ true, false ] Whether the stream is closed.
|
130
|
+
#
|
131
|
+
# @since 2.1.0
|
132
|
+
def closed?
|
133
|
+
!@open
|
134
|
+
end
|
135
|
+
|
136
|
+
# Abort the upload by deleting all chunks already inserted.
|
137
|
+
#
|
138
|
+
# @example Abort the write operation.
|
139
|
+
# stream.abort
|
140
|
+
#
|
141
|
+
# @return [ true ] True if the operation was aborted and the stream is closed.
|
142
|
+
#
|
143
|
+
# @since 2.1.0
|
144
|
+
def abort
|
145
|
+
fs.chunks_collection.find(:files_id => file_id).delete_many
|
146
|
+
@open = false || true
|
147
|
+
end
|
148
|
+
|
149
|
+
private
|
150
|
+
|
151
|
+
def chunks_collection
|
152
|
+
with_write_concern(fs.chunks_collection)
|
153
|
+
end
|
154
|
+
|
155
|
+
def files_collection
|
156
|
+
with_write_concern(fs.files_collection)
|
157
|
+
end
|
158
|
+
|
159
|
+
def with_write_concern(collection)
|
160
|
+
if collection.write_concern.options == write_concern.options
|
161
|
+
collection
|
162
|
+
else
|
163
|
+
collection.client.with(write: write_concern.options)[collection.name]
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
def update_length
|
168
|
+
file_info.document[:length] = @length
|
169
|
+
end
|
170
|
+
|
171
|
+
def file_info
|
172
|
+
doc = { length: @length, _id: file_id, filename: filename }
|
173
|
+
@file_info ||= File::Info.new(options.merge(doc))
|
174
|
+
end
|
175
|
+
|
176
|
+
def ensure_indexes!
|
177
|
+
fs.send(:ensure_indexes!)
|
178
|
+
end
|
179
|
+
|
180
|
+
def ensure_open!
|
181
|
+
raise Error::ClosedStream.new if closed?
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|