mongo 2.10.3 → 2.10.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/lib/mongo/auth/user.rb +7 -1
- data/lib/mongo/bulk_write/transformable.rb +3 -3
- data/lib/mongo/cluster.rb +2 -0
- data/lib/mongo/collection/view/writable.rb +3 -3
- data/lib/mongo/cursor/builder/kill_cursors_command.rb +8 -1
- data/lib/mongo/cursor/builder/op_kill_cursors.rb +8 -1
- data/lib/mongo/protocol/serializers.rb +12 -2
- data/lib/mongo/uri.rb +1 -1
- data/lib/mongo/version.rb +1 -1
- data/mongo.gemspec +1 -1
- data/spec/integration/crud_spec.rb +45 -0
- data/spec/integration/cursor_reaping_spec.rb +2 -1
- data/spec/mongo/auth/user/view_spec.rb +36 -1
- data/spec/mongo/auth/user_spec.rb +12 -0
- data/spec/mongo/bulk_write_spec.rb +2 -2
- data/spec/mongo/cluster_spec.rb +19 -0
- data/spec/mongo/cursor/builder/op_kill_cursors_spec.rb +56 -0
- data/spec/mongo/uri_spec.rb +1 -1
- data/spec/support/command_monitoring.rb +1 -1
- data/spec/support/utils.rb +11 -1
- metadata +612 -608
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 190086c9201d8ce762881a79c1f1665e27967c0750b55475fbb0947052d3e56b
|
4
|
+
data.tar.gz: 02452d83bc45ff4ef0e9f143c495985cf4584f4f0c7a7ea775e8553887f33d52
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 21278dcaf52c867fcf8bd257713882699d2e58b8d983fc9760b05e21b5d8412dad92a52163c0b28c1a9e6f48589167def7851b6624d68b31a6b068f0b89ead4d
|
7
|
+
data.tar.gz: '039e1d49bf742ec0ef51bf727c6b542d27efdf36d0cf864ca7898b1335b1312d967fe73beec34ec876d7ebfd7a04287ab6d732863c9b23ade753c6a1f6bfc8f0'
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/lib/mongo/auth/user.rb
CHANGED
@@ -151,6 +151,8 @@ module Mongo
|
|
151
151
|
# authorized for.
|
152
152
|
# @option options [ String ] :user The user name.
|
153
153
|
# @option options [ String ] :password The user's password.
|
154
|
+
# @option options [ String ] :pwd Legacy option for the user's password.
|
155
|
+
# If :password and :pwd are both specified, :password takes precedence.
|
154
156
|
# @option options [ Symbol ] :auth_mech The authorization mechanism.
|
155
157
|
# @option options [ Array<String>, Array<Hash> ] roles The user roles.
|
156
158
|
# @option options [ String ] :client_key The user's client key cached from a previous
|
@@ -196,7 +198,11 @@ module Mongo
|
|
196
198
|
#
|
197
199
|
# @since 2.0.0
|
198
200
|
def spec
|
199
|
-
{
|
201
|
+
{roles: roles}.tap do |spec|
|
202
|
+
if password
|
203
|
+
spec[:pwd] = password
|
204
|
+
end
|
205
|
+
end
|
200
206
|
end
|
201
207
|
|
202
208
|
private
|
@@ -92,7 +92,7 @@ module Mongo
|
|
92
92
|
Operation::U => doc[:replacement],
|
93
93
|
}.tap do |d|
|
94
94
|
if doc[:upsert]
|
95
|
-
d[
|
95
|
+
d['upsert'] = true
|
96
96
|
end
|
97
97
|
d[Operation::COLLATION] = doc[:collation] if doc[:collation]
|
98
98
|
end
|
@@ -108,7 +108,7 @@ module Mongo
|
|
108
108
|
Operation::MULTI => true,
|
109
109
|
}.tap do |d|
|
110
110
|
if doc[:upsert]
|
111
|
-
d[
|
111
|
+
d['upsert'] = true
|
112
112
|
end
|
113
113
|
d[Operation::COLLATION] = doc[:collation] if doc[:collation]
|
114
114
|
d[Operation::ARRAY_FILTERS] = doc[:array_filters] if doc[:array_filters]
|
@@ -124,7 +124,7 @@ module Mongo
|
|
124
124
|
Operation::U => doc[:update],
|
125
125
|
}.tap do |d|
|
126
126
|
if doc[:upsert]
|
127
|
-
d[
|
127
|
+
d['upsert'] = true
|
128
128
|
end
|
129
129
|
d[Operation::COLLATION] = doc[:collation] if doc[:collation]
|
130
130
|
d[Operation::ARRAY_FILTERS] = doc[:array_filters] if doc[:array_filters]
|
data/lib/mongo/cluster.rb
CHANGED
@@ -232,7 +232,7 @@ module Mongo
|
|
232
232
|
Operation::U => replacement,
|
233
233
|
}
|
234
234
|
if opts[:upsert]
|
235
|
-
update_doc[
|
235
|
+
update_doc['upsert'] = true
|
236
236
|
end
|
237
237
|
with_session(opts) do |session|
|
238
238
|
write_concern = write_concern_with_session(session)
|
@@ -279,7 +279,7 @@ module Mongo
|
|
279
279
|
Operation::MULTI => true,
|
280
280
|
}
|
281
281
|
if opts[:upsert]
|
282
|
-
update_doc[
|
282
|
+
update_doc['upsert'] = true
|
283
283
|
end
|
284
284
|
with_session(opts) do |session|
|
285
285
|
write_concern = write_concern_with_session(session)
|
@@ -323,7 +323,7 @@ module Mongo
|
|
323
323
|
Operation::U => spec,
|
324
324
|
}
|
325
325
|
if opts[:upsert]
|
326
|
-
update_doc[
|
326
|
+
update_doc['upsert'] = true
|
327
327
|
end
|
328
328
|
with_session(opts) do |session|
|
329
329
|
write_concern = write_concern_with_session(session)
|
@@ -92,7 +92,14 @@ module Mongo
|
|
92
92
|
#
|
93
93
|
# @since 2.3.0
|
94
94
|
def get_cursors_list(spec)
|
95
|
-
spec[:selector][:cursors].map
|
95
|
+
spec[:selector][:cursors].map do |value|
|
96
|
+
if value.respond_to?(:value)
|
97
|
+
# bson-ruby >= 4.6.0
|
98
|
+
value = value.value
|
99
|
+
else
|
100
|
+
value = value.instance_variable_get('@integer')
|
101
|
+
end
|
102
|
+
end
|
96
103
|
end
|
97
104
|
end
|
98
105
|
end
|
@@ -87,7 +87,14 @@ module Mongo
|
|
87
87
|
#
|
88
88
|
# @since 2.3.0
|
89
89
|
def get_cursors_list(spec)
|
90
|
-
spec[:cursor_ids].map
|
90
|
+
spec[:cursor_ids].map do |value|
|
91
|
+
if value.respond_to?(:value)
|
92
|
+
# bson-ruby >= 4.6.0
|
93
|
+
value.value
|
94
|
+
else
|
95
|
+
value.instance_variable_get('@integer')
|
96
|
+
end
|
97
|
+
end
|
91
98
|
end
|
92
99
|
end
|
93
100
|
end
|
@@ -110,7 +110,12 @@ module Mongo
|
|
110
110
|
# @return [String] Buffer with serialized value.
|
111
111
|
def self.serialize(buffer, value, validating_keys = BSON::Config.validating_keys?)
|
112
112
|
if value.is_a?(BSON::Int32)
|
113
|
-
|
113
|
+
if value.respond_to?(:value)
|
114
|
+
# bson-ruby >= 4.6.0
|
115
|
+
value = value.value
|
116
|
+
else
|
117
|
+
value = value.instance_variable_get('@integer')
|
118
|
+
end
|
114
119
|
end
|
115
120
|
buffer.put_int32(value)
|
116
121
|
end
|
@@ -138,7 +143,12 @@ module Mongo
|
|
138
143
|
# @return [ String ] Buffer with serialized value.
|
139
144
|
def self.serialize(buffer, value, validating_keys = BSON::Config.validating_keys?)
|
140
145
|
if value.is_a?(BSON::Int64)
|
141
|
-
|
146
|
+
if value.respond_to?(:value)
|
147
|
+
# bson-ruby >= 4.6.0
|
148
|
+
value = value.value
|
149
|
+
else
|
150
|
+
value = value.instance_variable_get('@integer')
|
151
|
+
end
|
142
152
|
end
|
143
153
|
buffer.put_int64(value)
|
144
154
|
end
|
data/lib/mongo/uri.rb
CHANGED
data/lib/mongo/version.rb
CHANGED
data/mongo.gemspec
CHANGED
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'CRUD operations' do
|
4
|
+
let(:collection) { authorized_client['crud_integration'] }
|
5
|
+
|
6
|
+
before do
|
7
|
+
collection.delete_many
|
8
|
+
end
|
9
|
+
|
10
|
+
describe 'upsert' do
|
11
|
+
context 'with default write concern' do
|
12
|
+
it 'upserts' do
|
13
|
+
collection.count_documents({}).should == 0
|
14
|
+
|
15
|
+
res = collection.find(_id: 'foo').update_one({'$set' => {foo: 'bar'}}, upsert: true)
|
16
|
+
|
17
|
+
res.documents.first['upserted'].length.should == 1
|
18
|
+
|
19
|
+
collection.count_documents({}).should == 1
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context 'unacknowledged write' do
|
24
|
+
let(:unack_collection) do
|
25
|
+
collection.with(write_concern: {w: 0})
|
26
|
+
end
|
27
|
+
|
28
|
+
before do
|
29
|
+
unack_collection.write_concern.acknowledged?.should be false
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'upserts' do
|
33
|
+
unack_collection.count_documents({}).should == 0
|
34
|
+
|
35
|
+
res = unack_collection.find(_id: 'foo').update_one({'$set' => {foo: 'bar'}}, upsert: true)
|
36
|
+
|
37
|
+
# since write concern is unacknowledged, wait for the data to be
|
38
|
+
# persisted (hopefully)
|
39
|
+
sleep 0.25
|
40
|
+
|
41
|
+
unack_collection.count_documents({}).should == 1
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -59,7 +59,8 @@ describe 'Cursor reaping' do
|
|
59
59
|
client.cluster.instance_variable_get('@periodic_executor').execute
|
60
60
|
|
61
61
|
started_event = EventSubscriber.started_events.detect do |event|
|
62
|
-
event.command['killCursors'] &&
|
62
|
+
event.command['killCursors'] &&
|
63
|
+
event.command['cursors'].map { |c| Utils.int64_value(c) }.include?(cursor_id)
|
63
64
|
end
|
64
65
|
|
65
66
|
expect(started_event).not_to be_nil
|
@@ -2,8 +2,10 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Mongo::Auth::User::View do
|
4
4
|
|
5
|
+
let(:database) { root_authorized_client.database }
|
6
|
+
|
5
7
|
let(:view) do
|
6
|
-
described_class.new(
|
8
|
+
described_class.new(database)
|
7
9
|
end
|
8
10
|
|
9
11
|
before do
|
@@ -12,6 +14,39 @@ describe Mongo::Auth::User::View do
|
|
12
14
|
|
13
15
|
describe '#create' do
|
14
16
|
|
17
|
+
context 'when password is not provided' do
|
18
|
+
|
19
|
+
let(:database) { root_authorized_client.use('$external').database }
|
20
|
+
|
21
|
+
let(:username) { 'passwordless-user' }
|
22
|
+
|
23
|
+
let(:response) do
|
24
|
+
view.create(
|
25
|
+
username,
|
26
|
+
# https://stackoverflow.com/questions/55939832/mongodb-external-database-cannot-create-new-user-with-user-defined-role
|
27
|
+
roles: [{role: 'read', db: 'admin'}],
|
28
|
+
)
|
29
|
+
end
|
30
|
+
|
31
|
+
before do
|
32
|
+
begin
|
33
|
+
view.remove(username)
|
34
|
+
rescue Mongo::Error::OperationFailure
|
35
|
+
# can be user not found, ignore
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'creates the user' do
|
40
|
+
view.info(username).should == []
|
41
|
+
|
42
|
+
lambda do
|
43
|
+
response
|
44
|
+
end.should_not raise_error
|
45
|
+
|
46
|
+
view.info(username).first['user'].should == username
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
15
50
|
context 'when a session is not used' do
|
16
51
|
|
17
52
|
let!(:response) do
|
@@ -284,4 +284,16 @@ describe Mongo::Auth::User do
|
|
284
284
|
end
|
285
285
|
end
|
286
286
|
end
|
287
|
+
|
288
|
+
describe '#spec' do
|
289
|
+
context 'when no password and no roles are set' do
|
290
|
+
let(:user) do
|
291
|
+
described_class.new(user: 'foo')
|
292
|
+
end
|
293
|
+
|
294
|
+
it 'is a hash with empty roles' do
|
295
|
+
user.spec.should == {roles: []}
|
296
|
+
end
|
297
|
+
end
|
298
|
+
end
|
287
299
|
end
|
@@ -1924,11 +1924,11 @@ describe Mongo::BulkWrite do
|
|
1924
1924
|
end
|
1925
1925
|
|
1926
1926
|
let(:first_txn_number) do
|
1927
|
-
started_events[-2].command['txnNumber']
|
1927
|
+
Utils.int64_value(started_events[-2].command['txnNumber'])
|
1928
1928
|
end
|
1929
1929
|
|
1930
1930
|
let(:second_txn_number) do
|
1931
|
-
started_events[-1].command['txnNumber']
|
1931
|
+
Utils.int64_value(started_events[-1].command['txnNumber'])
|
1932
1932
|
end
|
1933
1933
|
|
1934
1934
|
it 'inserts the documents' do
|
data/spec/mongo/cluster_spec.rb
CHANGED
@@ -19,6 +19,25 @@ describe Mongo::Cluster do
|
|
19
19
|
|
20
20
|
let(:cluster) { cluster_without_io }
|
21
21
|
|
22
|
+
describe 'initialize' do
|
23
|
+
|
24
|
+
context 'when there are duplicate addresses' do
|
25
|
+
|
26
|
+
let(:addresses) do
|
27
|
+
SpecConfig.instance.addresses + SpecConfig.instance.addresses
|
28
|
+
end
|
29
|
+
let(:cluster_with_dup_addresses) do
|
30
|
+
register_cluster(
|
31
|
+
described_class.new(addresses, monitoring, SpecConfig.instance.test_options))
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'does not raise an exception' do
|
35
|
+
expect { cluster_with_dup_addresses }.not_to raise_error
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
22
41
|
describe '#==' do
|
23
42
|
|
24
43
|
context 'when the other is a cluster' do
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Mongo::Cursor::Builder::OpKillCursors do
|
4
|
+
|
5
|
+
let(:reply) do
|
6
|
+
Mongo::Protocol::Reply.allocate.tap do |reply|
|
7
|
+
allow(reply).to receive(:cursor_id).and_return(8000)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
let(:result) do
|
12
|
+
Mongo::Operation::Result.new(reply)
|
13
|
+
end
|
14
|
+
|
15
|
+
let(:view) do
|
16
|
+
Mongo::Collection::View.new(
|
17
|
+
authorized_collection,
|
18
|
+
{},
|
19
|
+
tailable: true,
|
20
|
+
max_time_ms: 100
|
21
|
+
)
|
22
|
+
end
|
23
|
+
|
24
|
+
let(:cursor) do
|
25
|
+
Mongo::Cursor.new(view, result, authorized_primary)
|
26
|
+
end
|
27
|
+
|
28
|
+
let(:builder) do
|
29
|
+
described_class.new(cursor)
|
30
|
+
end
|
31
|
+
|
32
|
+
describe '#specification' do
|
33
|
+
|
34
|
+
let(:specification) do
|
35
|
+
builder.specification
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'includes the cursor ids' do
|
39
|
+
expect(specification[:cursor_ids]).to eq([BSON::Int64.new(8000)])
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'includes the database name' do
|
43
|
+
expect(specification[:db_name]).to eq(SpecConfig.instance.test_db)
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'includes the collection name' do
|
47
|
+
expect(specification[:coll_name]).to eq(TEST_COLL)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe '.get_cursors_list' do
|
52
|
+
it 'returns integer cursor ids' do
|
53
|
+
expect(described_class.get_cursors_list(builder.specification)).to eq([8000])
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
data/spec/mongo/uri_spec.rb
CHANGED
@@ -352,7 +352,7 @@ describe Mongo::URI do
|
|
352
352
|
let(:servers) { '%2Ftmp%2Fmongodb-27017.sock' }
|
353
353
|
|
354
354
|
it 'returns an array with the parsed server' do
|
355
|
-
expect(uri.servers).to eq([URI.unescape(servers)])
|
355
|
+
expect(uri.servers).to eq([URI::DEFAULT_PARSER.unescape(servers)])
|
356
356
|
end
|
357
357
|
end
|
358
358
|
|
@@ -135,7 +135,7 @@ module Mongo
|
|
135
135
|
if expected.keys.first == '$numberLong'
|
136
136
|
converted = expected.values.first.to_i
|
137
137
|
if actual.is_a?(BSON::Int64)
|
138
|
-
actual = actual
|
138
|
+
actual = Utils.int64_value(actual)
|
139
139
|
elsif actual.is_a?(BSON::Int32)
|
140
140
|
return false
|
141
141
|
end
|
data/spec/support/utils.rb
CHANGED
@@ -70,7 +70,7 @@ module Utils
|
|
70
70
|
# Convert txnNumber field from a BSON integer to an extended JSON int64
|
71
71
|
if command['txnNumber']
|
72
72
|
command['txnNumber'] = {
|
73
|
-
'$numberLong' => command['txnNumber'].
|
73
|
+
'$numberLong' => int64_value(command['txnNumber']).to_s
|
74
74
|
}
|
75
75
|
end
|
76
76
|
|
@@ -184,4 +184,14 @@ module Utils
|
|
184
184
|
end
|
185
185
|
end
|
186
186
|
module_function :convert_operation_options
|
187
|
+
|
188
|
+
def int64_value(value)
|
189
|
+
if value.respond_to?(:value)
|
190
|
+
# bson-ruby >= 4.6.0
|
191
|
+
value.value
|
192
|
+
else
|
193
|
+
value.instance_variable_get('@integer')
|
194
|
+
end
|
195
|
+
end
|
196
|
+
module_function :int64_value
|
187
197
|
end
|