mongo 2.2.1 → 2.2.2
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 +1 -0
- data/lib/mongo/bson.rb +1 -1
- data/lib/mongo/cluster/topology/replica_set.rb +21 -4
- data/lib/mongo/collection/view/readable.rb +0 -1
- data/lib/mongo/error/operation_failure.rb +3 -1
- data/lib/mongo/grid/file.rb +14 -11
- data/lib/mongo/grid/file/chunk.rb +12 -10
- data/lib/mongo/grid/fs_bucket.rb +2 -2
- data/lib/mongo/grid/stream/read.rb +1 -1
- data/lib/mongo/grid/stream/write.rb +5 -5
- data/lib/mongo/options/mapper.rb +17 -0
- data/lib/mongo/protocol/message.rb +1 -1
- data/lib/mongo/server/connection.rb +3 -25
- data/lib/mongo/server/description.rb +19 -2
- data/lib/mongo/version.rb +1 -1
- data/lib/mongo/write_concern/normalizable.rb +2 -1
- data/spec/mongo/client_spec.rb +1 -1
- data/spec/mongo/collection/view/readable_spec.rb +18 -0
- data/spec/mongo/grid/file/chunk_spec.rb +1 -0
- data/spec/mongo/grid/file_spec.rb +25 -6
- data/spec/mongo/grid/stream/write_spec.rb +11 -0
- data/spec/mongo/protocol/reply_spec.rb +13 -0
- data/spec/mongo/server/connection_spec.rb +4 -4
- data/spec/mongo/write_concern_spec.rb +15 -0
- data/spec/support/command_monitoring.rb +3 -0
- data/spec/support/sdam/rs/equal_electionids.yml +4 -0
- data/spec/support/sdam/rs/new_primary_new_electionid.yml +7 -1
- data/spec/support/sdam/rs/new_primary_new_setversion.yml +101 -0
- data/spec/support/sdam/rs/null_election_id.yml +8 -1
- data/spec/support/sdam/rs/primary_disconnect_electionid.yml +37 -1
- data/spec/support/sdam/rs/primary_disconnect_setversion.yml +160 -0
- data/spec/support/sdam/rs/set_version_without_electionid.yml +69 -0
- data/spec/support/sdam/rs/setversion_without_electionid.yml +69 -0
- data/spec/support/sdam/rs/use_setversion_without_electionid.yml +99 -0
- metadata +36 -5
- metadata.gz.sig +1 -0
- data/lib/csasl/csasl.bundle +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 72df9675f13de7a6111464ef0089ba64b4ef11af
|
4
|
+
data.tar.gz: 20832950dd436fb031938d2e164cca2c7fe5d84c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: eaaf003581ddec08e424a7a8168917b4a971514029527229ffe0e1a5746715be52caf0eb8e1f3ef4af29e35d744b23240282fecfa157280f4e31cb4f8c03bfbf
|
7
|
+
data.tar.gz: 32dd69254433179769be7b7d030e230da1b499ce59da53ab1535b1d736cca6dd2a3bb8d1516323abdf3f8dbb7d2285356ef011c708f8a460cc2ffa1e4e88f015
|
checksums.yaml.gz.sig
ADDED
Binary file
|
data.tar.gz.sig
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
���Y;ht����S���~r�٘-��ZK���cu�̸x����=��\�w�JG��%@y�U�3x;�d�:IR"�^�i�\���<^;O�Y����H�,�;_1eH�����6���(�>�/�`zRІ|@N �&����b�lz�8r��jy�ѓ��C����i,JY(^Q�a�ydQ���"
_�k�94�J#*5���hi�F���'�����`~+�85�>q���Nl��|[]/��8&�no���v
|
data/lib/mongo/bson.rb
CHANGED
@@ -68,6 +68,7 @@ module Mongo
|
|
68
68
|
end
|
69
69
|
end
|
70
70
|
update_max_election_id(description)
|
71
|
+
update_max_set_version(description)
|
71
72
|
end
|
72
73
|
else
|
73
74
|
log_warn(
|
@@ -88,7 +89,8 @@ module Mongo
|
|
88
89
|
# @since 2.0.0
|
89
90
|
def initialize(options, seeds = [])
|
90
91
|
@options = options
|
91
|
-
@max_election_id =
|
92
|
+
@max_election_id = nil
|
93
|
+
@max_set_version = nil
|
92
94
|
end
|
93
95
|
|
94
96
|
# A replica set topology is a replica set.
|
@@ -222,14 +224,29 @@ module Mongo
|
|
222
224
|
private
|
223
225
|
|
224
226
|
def update_max_election_id(description)
|
225
|
-
if description.election_id &&
|
227
|
+
if description.election_id &&
|
228
|
+
(@max_election_id.nil? ||
|
229
|
+
description.election_id > @max_election_id)
|
226
230
|
@max_election_id = description.election_id
|
227
231
|
end
|
228
232
|
end
|
229
233
|
|
234
|
+
def update_max_set_version(description)
|
235
|
+
if description.set_version &&
|
236
|
+
(@max_set_version.nil? ||
|
237
|
+
description.set_version > @max_set_version)
|
238
|
+
@max_set_version = description.set_version
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
230
242
|
def detect_stale_primary!(description)
|
231
|
-
if description.election_id && description.
|
232
|
-
|
243
|
+
if description.election_id && description.set_version
|
244
|
+
if @max_set_version && @max_election_id &&
|
245
|
+
(description.set_version < @max_set_version ||
|
246
|
+
(description.set_version == @max_set_version &&
|
247
|
+
description.election_id < @max_election_id))
|
248
|
+
description.unknown!
|
249
|
+
end
|
233
250
|
end
|
234
251
|
end
|
235
252
|
|
@@ -120,7 +120,6 @@ module Mongo
|
|
120
120
|
# @option options :limit [ Integer ] Max number of docs to return.
|
121
121
|
# @option options :max_time_ms [ Integer ] The maximum amount of time to allow the
|
122
122
|
# command to run.
|
123
|
-
# @option options :read [ Hash ] The read preference for this command.
|
124
123
|
#
|
125
124
|
# @return [ Integer ] The document count.
|
126
125
|
#
|
@@ -37,7 +37,9 @@ module Mongo
|
|
37
37
|
'error querying',
|
38
38
|
'could not get last error',
|
39
39
|
'connection attempt failed',
|
40
|
-
'interrupted at shutdown'
|
40
|
+
'interrupted at shutdown',
|
41
|
+
'unknown replica set',
|
42
|
+
'dbclient error communicating with server'
|
41
43
|
].freeze
|
42
44
|
|
43
45
|
# Can the operation that caused the error be retried?
|
data/lib/mongo/grid/file.rb
CHANGED
@@ -30,9 +30,6 @@ module Mongo
|
|
30
30
|
# @return [ Array<Chunk> ] chunks The file chunks.
|
31
31
|
attr_reader :chunks
|
32
32
|
|
33
|
-
# @return [ IO ] data The raw data for the file.
|
34
|
-
attr_reader :data
|
35
|
-
|
36
33
|
# @return [ File::Info ] info The file information.
|
37
34
|
attr_reader :info
|
38
35
|
|
@@ -48,7 +45,7 @@ module Mongo
|
|
48
45
|
# @since 2.0.0
|
49
46
|
def ==(other)
|
50
47
|
return false unless other.is_a?(File)
|
51
|
-
chunks == other.chunks &&
|
48
|
+
chunks == other.chunks && info == other.info
|
52
49
|
end
|
53
50
|
|
54
51
|
# Initialize the file.
|
@@ -56,8 +53,8 @@ module Mongo
|
|
56
53
|
# @example Create the file.
|
57
54
|
# Grid::File.new(data, :filename => 'test.txt')
|
58
55
|
#
|
59
|
-
# @param [ IO, Array<BSON::Document> ] data The file
|
60
|
-
# chunks.
|
56
|
+
# @param [ IO, String, Array<BSON::Document> ] data The file object, file
|
57
|
+
# contents or chunks.
|
61
58
|
# @param [ BSON::Document, Hash ] options The info options.
|
62
59
|
#
|
63
60
|
# @option options [ String ] :filename Required name of the file.
|
@@ -71,10 +68,19 @@ module Mongo
|
|
71
68
|
#
|
72
69
|
# @since 2.0.0
|
73
70
|
def initialize(data, options = {})
|
74
|
-
@info = Info.new(options.merge(:length => data.
|
71
|
+
@info = Info.new(options.merge(:length => data.size))
|
75
72
|
initialize_chunks!(data)
|
76
73
|
end
|
77
74
|
|
75
|
+
# Joins chunks into a string.
|
76
|
+
#
|
77
|
+
# @return [ String ] The raw data for the file.
|
78
|
+
#
|
79
|
+
# @since 2.0.0
|
80
|
+
def data
|
81
|
+
@data ||= Chunk.assemble(chunks)
|
82
|
+
end
|
83
|
+
|
78
84
|
# Gets a pretty inspection of the file.
|
79
85
|
#
|
80
86
|
# @example Get the file inspection.
|
@@ -96,12 +102,9 @@ module Mongo
|
|
96
102
|
# the original data itself.
|
97
103
|
def initialize_chunks!(value)
|
98
104
|
if value.is_a?(Array)
|
99
|
-
|
100
|
-
@chunks = chks
|
101
|
-
@data = Chunk.assemble(chks)
|
105
|
+
@chunks = value.map{ |doc| Chunk.new(doc) }
|
102
106
|
else
|
103
107
|
@chunks = Chunk.split(value, info)
|
104
|
-
@data = value
|
105
108
|
end
|
106
109
|
end
|
107
110
|
end
|
@@ -12,6 +12,8 @@
|
|
12
12
|
# See the License for the specific language governing permissions and
|
13
13
|
# limitations under the License.
|
14
14
|
|
15
|
+
require 'stringio'
|
16
|
+
|
15
17
|
module Mongo
|
16
18
|
module Grid
|
17
19
|
class File
|
@@ -159,23 +161,23 @@ module Mongo
|
|
159
161
|
# @example Split the data into chunks.
|
160
162
|
# Chunks.split(data)
|
161
163
|
#
|
162
|
-
# @param [ String ] data The raw bytes.
|
164
|
+
# @param [ String, IO ] data The raw bytes.
|
163
165
|
# @param [ File::Info ] file_info The files collection file doc.
|
164
166
|
#
|
165
167
|
# @return [ Array<Chunk> ] The chunks of the data.
|
166
168
|
#
|
167
169
|
# @since 2.0.0
|
168
|
-
def split(
|
169
|
-
|
170
|
-
|
171
|
-
|
170
|
+
def split(io, file_info, offset = 0)
|
171
|
+
io = StringIO.new(io) if io.is_a?(String)
|
172
|
+
parts = Enumerator.new { |y| y << io.read(file_info.chunk_size) until io.eof? }
|
173
|
+
parts.map.with_index do |bytes, n|
|
172
174
|
file_info.md5.update(bytes)
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
175
|
+
Chunk.new(
|
176
|
+
data: BSON::Binary.new(bytes),
|
177
|
+
files_id: file_info.id,
|
178
|
+
n: n + offset,
|
179
|
+
)
|
177
180
|
end
|
178
|
-
chunks
|
179
181
|
end
|
180
182
|
end
|
181
183
|
end
|
data/lib/mongo/grid/fs_bucket.rb
CHANGED
@@ -359,8 +359,8 @@ module Mongo
|
|
359
359
|
# chunks collection. After all the chunks have been uploaded, it creates a files collection
|
360
360
|
# document for the filename in the files collection.
|
361
361
|
#
|
362
|
-
# @example
|
363
|
-
# fs.
|
362
|
+
# @example Upload a file to the GridFS bucket.
|
363
|
+
# fs.upload_from_stream('a-file.txt')
|
364
364
|
#
|
365
365
|
# @param [ String ] filename The filename of the file to upload.
|
366
366
|
# @param [ IO ] io The source io stream to upload from.
|
@@ -74,7 +74,7 @@ module Mongo
|
|
74
74
|
view.each_with_index.reduce(0) do |length_read, (doc, index)|
|
75
75
|
chunk = Grid::File::Chunk.new(doc)
|
76
76
|
validate!(index, num_chunks, chunk, length_read)
|
77
|
-
data =
|
77
|
+
data = chunk.data.data
|
78
78
|
yield data
|
79
79
|
length_read += data.size
|
80
80
|
end if block_given?
|
@@ -82,9 +82,8 @@ module Mongo
|
|
82
82
|
def write(io)
|
83
83
|
ensure_open!
|
84
84
|
@indexes ||= ensure_indexes!
|
85
|
-
|
86
|
-
|
87
|
-
chunks = File::Chunk.split(data, file_info, @n)
|
85
|
+
@length += io.size
|
86
|
+
chunks = File::Chunk.split(io, file_info, @n)
|
88
87
|
@n += chunks.size
|
89
88
|
chunks_collection.insert_many(chunks) unless chunks.empty?
|
90
89
|
self
|
@@ -157,10 +156,11 @@ module Mongo
|
|
157
156
|
end
|
158
157
|
|
159
158
|
def with_write_concern(collection)
|
160
|
-
if
|
159
|
+
if write_concern.nil? || (collection.write_concern &&
|
160
|
+
collection.write_concern.options == write_concern.options)
|
161
161
|
collection
|
162
162
|
else
|
163
|
-
collection.
|
163
|
+
collection.with(write: write_concern.options)
|
164
164
|
end
|
165
165
|
end
|
166
166
|
|
data/lib/mongo/options/mapper.rb
CHANGED
@@ -81,6 +81,23 @@ module Mongo
|
|
81
81
|
end
|
82
82
|
end
|
83
83
|
|
84
|
+
# Coverts all the keys of the options to symbols.
|
85
|
+
#
|
86
|
+
# @example Convert all option keys to symbols.
|
87
|
+
# Mapper.transform({ 'name' => 1 })
|
88
|
+
#
|
89
|
+
# @param [ Hash ] options The options to transform.
|
90
|
+
#
|
91
|
+
# @return [ Hash ] The transformed options.
|
92
|
+
#
|
93
|
+
# @since 2.2.2
|
94
|
+
def transform_keys_to_symbols(options)
|
95
|
+
options.reduce({}) do |transformed, (key, value)|
|
96
|
+
transformed[key.to_sym] = value
|
97
|
+
transformed
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
84
101
|
# Coverts all the symbol values to strings.
|
85
102
|
#
|
86
103
|
# @example Convert all option symbol values to strings.
|
@@ -114,7 +114,7 @@ module Mongo
|
|
114
114
|
|
115
115
|
# Protection from potential DOS man-in-the-middle attacks. See
|
116
116
|
# DRIVERS-276.
|
117
|
-
if length > max_message_size
|
117
|
+
if length > (max_message_size || MAX_MESSAGE_SIZE)
|
118
118
|
raise Error::MaxMessageSize.new(max_message_size)
|
119
119
|
end
|
120
120
|
|
@@ -38,29 +38,12 @@ module Mongo
|
|
38
38
|
# @since 2.1.0
|
39
39
|
PING_BYTES = PING_MESSAGE.serialize.to_s.freeze
|
40
40
|
|
41
|
-
# @return [ Mongo::Auth::CR, Mongo::Auth::X509, Mongo::Auth:LDAP, Mongo::Auth::SCRAM ]
|
42
|
-
# authenticator The authentication strategy.
|
43
|
-
attr_reader :authenticator
|
44
|
-
|
45
41
|
def_delegators :@server,
|
46
42
|
:features,
|
47
43
|
:max_bson_object_size,
|
48
44
|
:max_message_size,
|
49
45
|
:mongos?
|
50
46
|
|
51
|
-
# Is this connection authenticated. Will return true if authorization
|
52
|
-
# details were provided and authentication passed.
|
53
|
-
#
|
54
|
-
# @example Is the connection authenticated?
|
55
|
-
# connection.authenticated?
|
56
|
-
#
|
57
|
-
# @return [ true, false ] If the connection is authenticated.
|
58
|
-
#
|
59
|
-
# @since 2.0.0
|
60
|
-
def authenticated?
|
61
|
-
!!@authenticated
|
62
|
-
end
|
63
|
-
|
64
47
|
# Tell the underlying socket to establish a connection to the host.
|
65
48
|
#
|
66
49
|
# @example Connect to the host.
|
@@ -76,10 +59,7 @@ module Mongo
|
|
76
59
|
unless socket
|
77
60
|
@socket = address.socket(timeout, ssl_options)
|
78
61
|
socket.connect!
|
79
|
-
|
80
|
-
authenticator.login(self)
|
81
|
-
@authenticated = true
|
82
|
-
end
|
62
|
+
authenticate!
|
83
63
|
end
|
84
64
|
true
|
85
65
|
end
|
@@ -99,7 +79,6 @@ module Mongo
|
|
99
79
|
if socket
|
100
80
|
socket.close
|
101
81
|
@socket = nil
|
102
|
-
@authenticated = false
|
103
82
|
end
|
104
83
|
true
|
105
84
|
end
|
@@ -151,7 +130,6 @@ module Mongo
|
|
151
130
|
@ssl_options = options.reject { |k, v| !k.to_s.start_with?(SSL) }
|
152
131
|
@socket = nil
|
153
132
|
@pid = Process.pid
|
154
|
-
setup_authentication!
|
155
133
|
end
|
156
134
|
|
157
135
|
# Ping the connection to see if the server is responding to commands.
|
@@ -180,11 +158,11 @@ module Mongo
|
|
180
158
|
messages.last.replyable? ? read : nil
|
181
159
|
end
|
182
160
|
|
183
|
-
def
|
161
|
+
def authenticate!
|
184
162
|
if options[:user]
|
185
163
|
default_mechanism = @server.features.scram_sha_1_enabled? ? :scram : :mongodb_cr
|
186
164
|
user = Auth::User.new(Options::Redacted.new(:auth_mech => default_mechanism).merge(options))
|
187
|
-
|
165
|
+
Auth.get(user).login(self)
|
188
166
|
end
|
189
167
|
end
|
190
168
|
|
@@ -129,11 +129,16 @@ module Mongo
|
|
129
129
|
# @since 2.0.0
|
130
130
|
TAGS = 'tags'.freeze
|
131
131
|
|
132
|
-
# Constant for reading
|
132
|
+
# Constant for reading electionId info from config.
|
133
133
|
#
|
134
134
|
# @since 2.1.0
|
135
135
|
ELECTION_ID = 'electionId'.freeze
|
136
136
|
|
137
|
+
# Constant for reading setVersion info from config.
|
138
|
+
#
|
139
|
+
# @since 2.2.2
|
140
|
+
SET_VERSION = 'setVersion'.freeze
|
141
|
+
|
137
142
|
# Constant for reading localTime info from config.
|
138
143
|
#
|
139
144
|
# @since 2.1.0
|
@@ -142,7 +147,7 @@ module Mongo
|
|
142
147
|
# Fields to exclude when comparing two descriptions.
|
143
148
|
#
|
144
149
|
# @since 2.0.6
|
145
|
-
EXCLUDE_FOR_COMPARISON = [ LOCAL_TIME, ELECTION_ID ].freeze
|
150
|
+
EXCLUDE_FOR_COMPARISON = [ LOCAL_TIME, ELECTION_ID, SET_VERSION ].freeze
|
146
151
|
|
147
152
|
# @return [ Address ] address The server's address.
|
148
153
|
attr_reader :address
|
@@ -343,6 +348,18 @@ module Mongo
|
|
343
348
|
config[ELECTION_ID]
|
344
349
|
end
|
345
350
|
|
351
|
+
# Get the setVersion from the config.
|
352
|
+
#
|
353
|
+
# @example Get the setVersion.
|
354
|
+
# description.set_version
|
355
|
+
#
|
356
|
+
# @return [ Integer ] The set version.
|
357
|
+
#
|
358
|
+
# @since 2.2.2
|
359
|
+
def set_version
|
360
|
+
config[SET_VERSION]
|
361
|
+
end
|
362
|
+
|
346
363
|
# Is the server a mongos?
|
347
364
|
#
|
348
365
|
# @example Is the server a mongos?
|
data/lib/mongo/version.rb
CHANGED
data/spec/mongo/client_spec.rb
CHANGED
@@ -688,7 +688,7 @@ describe Mongo::Client do
|
|
688
688
|
end
|
689
689
|
|
690
690
|
it 'returns a acknowledged write concern' do
|
691
|
-
expect(concern.get_last_error).to eq(:getlasterror => 1,
|
691
|
+
expect(concern.get_last_error).to eq(:getlasterror => 1, :j => true)
|
692
692
|
end
|
693
693
|
end
|
694
694
|
|
@@ -377,6 +377,17 @@ describe Mongo::Collection::View::Readable do
|
|
377
377
|
expect(distinct).to be_empty
|
378
378
|
end
|
379
379
|
end
|
380
|
+
|
381
|
+
context 'when the field does not exist' do
|
382
|
+
|
383
|
+
let(:distinct) do
|
384
|
+
view.distinct(:doesnotexist)
|
385
|
+
end
|
386
|
+
|
387
|
+
it 'returns an empty array' do
|
388
|
+
expect(distinct).to be_empty
|
389
|
+
end
|
390
|
+
end
|
380
391
|
end
|
381
392
|
|
382
393
|
context 'when no selector is provided' do
|
@@ -462,6 +473,13 @@ describe Mongo::Collection::View::Readable do
|
|
462
473
|
expect(view.distinct(:field, max_time_ms: 100)).to eq([ 'test' ])
|
463
474
|
end
|
464
475
|
end
|
476
|
+
|
477
|
+
context 'when the field does not exist' do
|
478
|
+
|
479
|
+
it 'returns an empty array' do
|
480
|
+
expect(view.distinct(:nofieldexists)).to be_empty
|
481
|
+
end
|
482
|
+
end
|
465
483
|
end
|
466
484
|
|
467
485
|
describe '#hint' do
|