mongo 2.10.3 → 2.10.4
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/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
|