mongo 2.16.0 → 2.17.1
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/README.md +1 -1
- data/lib/mongo/auth/aws/request.rb +0 -1
- data/lib/mongo/client.rb +4 -0
- data/lib/mongo/cluster/reapers/cursor_reaper.rb +26 -14
- data/lib/mongo/collection/view/aggregation.rb +62 -17
- data/lib/mongo/collection/view/builder/aggregation.rb +11 -13
- data/lib/mongo/collection/view/builder/map_reduce.rb +8 -5
- data/lib/mongo/collection/view/change_stream.rb +7 -3
- data/lib/mongo/collection/view/iterable.rb +2 -3
- data/lib/mongo/collection/view/map_reduce.rb +16 -1
- data/lib/mongo/collection/view/readable.rb +24 -1
- data/lib/mongo/collection/view/writable.rb +23 -0
- data/lib/mongo/collection.rb +21 -1
- data/lib/mongo/cursor/kill_spec.rb +19 -2
- data/lib/mongo/cursor.rb +5 -5
- data/lib/mongo/database/view.rb +4 -2
- data/lib/mongo/database.rb +6 -6
- data/lib/mongo/error/snapshot_session_invalid_server_version.rb +31 -0
- data/lib/mongo/error/snapshot_session_transaction_prohibited.rb +30 -0
- data/lib/mongo/error.rb +2 -0
- data/lib/mongo/operation/delete/op_msg.rb +2 -1
- data/lib/mongo/operation/find/builder/command.rb +1 -0
- data/lib/mongo/operation/result.rb +6 -0
- data/lib/mongo/operation/shared/executable.rb +4 -0
- data/lib/mongo/operation/shared/sessions_supported.rb +18 -2
- data/lib/mongo/operation/update/op_msg.rb +2 -1
- data/lib/mongo/server/description/features.rb +3 -1
- data/lib/mongo/server/push_monitor.rb +4 -1
- data/lib/mongo/server_selector/base.rb +26 -4
- data/lib/mongo/session.rb +19 -0
- data/lib/mongo/socket/ocsp_cache.rb +2 -3
- data/lib/mongo/socket.rb +1 -5
- data/lib/mongo/utils.rb +0 -6
- data/lib/mongo/version.rb +1 -1
- data/mongo.gemspec +1 -1
- data/spec/integration/read_preference_spec.rb +16 -12
- data/spec/lite_spec_helper.rb +7 -0
- data/spec/mongo/cluster/cursor_reaper_spec.rb +22 -15
- data/spec/mongo/collection/view/aggregation_spec.rb +71 -95
- data/spec/mongo/collection/view/change_stream_spec.rb +1 -1
- data/spec/mongo/collection/view/map_reduce_spec.rb +30 -1
- data/spec/mongo/cursor_spec.rb +3 -2
- data/spec/mongo/operation/read_preference_op_msg_spec.rb +24 -1
- data/spec/mongo/server/monitor/connection_spec.rb +22 -0
- data/spec/mongo/server/push_monitor_spec.rb +101 -0
- data/spec/mongo/server_selector_spec.rb +136 -15
- data/spec/mongo/socket/ssl_spec.rb +26 -58
- data/spec/mongo/utils_spec.rb +0 -14
- data/spec/runners/auth.rb +1 -1
- data/spec/runners/change_streams/spec.rb +1 -1
- data/spec/runners/cmap.rb +1 -1
- data/spec/runners/command_monitoring.rb +1 -1
- data/spec/runners/connection_string.rb +1 -1
- data/spec/runners/crud/spec.rb +1 -3
- data/spec/runners/crud/verifier.rb +1 -2
- data/spec/runners/gridfs.rb +1 -1
- data/spec/runners/read_write_concern_document.rb +1 -1
- data/spec/runners/sdam.rb +1 -1
- data/spec/runners/server_selection.rb +1 -1
- data/spec/runners/server_selection_rtt.rb +1 -1
- data/spec/runners/unified/assertions.rb +3 -1
- data/spec/runners/unified/crud_operations.rb +77 -23
- data/spec/runners/unified/ddl_operations.rb +29 -1
- data/spec/runners/unified/entity_map.rb +3 -3
- data/spec/runners/unified/support_operations.rb +6 -1
- data/spec/runners/unified/test.rb +15 -3
- data/spec/runners/unified/test_group.rb +1 -1
- data/spec/spec_tests/data/crud_unified/aggregate-let.yml +138 -0
- data/spec/spec_tests/data/crud_unified/aggregate-write-readPreference.yml +155 -0
- data/spec/spec_tests/data/crud_unified/db-aggregate-write-readPreference.yml +151 -0
- data/spec/spec_tests/data/crud_unified/deleteMany-let.yml +91 -0
- data/spec/spec_tests/data/crud_unified/deleteOne-let.yml +89 -0
- data/spec/spec_tests/data/crud_unified/find-let.yml +71 -0
- data/spec/spec_tests/data/crud_unified/findOneAndDelete-let.yml +88 -0
- data/spec/spec_tests/data/crud_unified/findOneAndReplace-let.yml +94 -0
- data/spec/spec_tests/data/crud_unified/findOneAndUpdate-let.yml +96 -0
- data/spec/spec_tests/data/crud_unified/updateMany-let.yml +103 -0
- data/spec/spec_tests/data/crud_unified/updateOne-let.yml +98 -0
- data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/DefaultNoMaxStaleness.yml +2 -2
- data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/LastUpdateTime.yml +3 -3
- data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/Nearest.yml +3 -3
- data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/Nearest2.yml +3 -3
- data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/PrimaryPreferred.yml +2 -2
- data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/PrimaryPreferred_tags.yml +2 -2
- data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/Secondary.yml +4 -4
- data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/SecondaryPreferred.yml +2 -2
- data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/SecondaryPreferred_tags.yml +4 -4
- data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/ZeroMaxStaleness.yml +2 -2
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/DefaultNoMaxStaleness.yml +2 -2
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/LastUpdateTime.yml +3 -3
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/LongHeartbeat.yml +2 -2
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/LongHeartbeat2.yml +2 -2
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/MaxStalenessTooSmall.yml +2 -2
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/MaxStalenessWithModePrimary.yml +2 -2
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/Nearest.yml +3 -3
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/Nearest2.yml +3 -3
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/Nearest_tags.yml +2 -2
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/PrimaryPreferred.yml +2 -2
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/SecondaryPreferred.yml +2 -2
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/SecondaryPreferred_tags.yml +5 -5
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/SecondaryPreferred_tags2.yml +3 -3
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/Secondary_tags.yml +5 -5
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/Secondary_tags2.yml +3 -3
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/ZeroMaxStaleness.yml +2 -2
- data/spec/spec_tests/data/max_staleness/Sharded/SmallMaxStaleness.yml +2 -2
- data/spec/spec_tests/data/max_staleness/Single/SmallMaxStaleness.yml +1 -1
- data/spec/spec_tests/data/max_staleness/Unknown/SmallMaxStaleness.yml +1 -1
- data/spec/spec_tests/data/sessions_unified/snapshot-sessions-not-supported-client-error.yml +69 -0
- data/spec/spec_tests/data/sessions_unified/snapshot-sessions-not-supported-server-error.yml +102 -0
- data/spec/spec_tests/data/sessions_unified/snapshot-sessions-unsupported-ops.yml +258 -0
- data/spec/spec_tests/data/sessions_unified/snapshot-sessions.yml +482 -0
- data/spec/spec_tests/seed_list_discovery_spec.rb +1 -1
- data/spec/spec_tests/sessions_unified_spec.rb +13 -0
- data/spec/support/utils.rb +31 -0
- data.tar.gz.sig +0 -0
- metadata +1127 -1090
- metadata.gz.sig +1 -2
|
@@ -306,67 +306,40 @@ describe Mongo::Socket::SSL, retry: 3 do
|
|
|
306
306
|
end
|
|
307
307
|
end
|
|
308
308
|
|
|
309
|
-
context 'when ruby version is < 2.4.1' do
|
|
310
|
-
ruby_version_lt '2.4.1'
|
|
311
|
-
|
|
312
|
-
context 'when a key is passed, but it is not of the right type' do
|
|
313
|
-
|
|
314
|
-
let(:ssl_options) do
|
|
315
|
-
key = "This is a string not a key"
|
|
316
|
-
{
|
|
317
|
-
:ssl => true,
|
|
318
|
-
:ssl_key_object => key,
|
|
319
|
-
:ssl_cert => SpecConfig.instance.client_cert_path,
|
|
320
|
-
:ssl_verify => false
|
|
321
|
-
}
|
|
322
|
-
end
|
|
323
|
-
|
|
324
|
-
it 'raises a TypeError' do
|
|
325
|
-
expect do
|
|
326
|
-
socket
|
|
327
|
-
end.to raise_exception(TypeError)
|
|
328
|
-
end
|
|
329
|
-
end
|
|
330
|
-
end
|
|
331
|
-
|
|
332
309
|
# Note that as of MRI 2.4, Creating a socket with the wrong key type raises
|
|
333
310
|
# a NoMethodError because #private? is attempted to be called on the key.
|
|
334
311
|
# In jruby 9.2 a TypeError is raised.
|
|
335
312
|
# In jruby 9.1 a OpenSSL::PKey::PKeyError is raised.
|
|
336
|
-
context 'when
|
|
337
|
-
ruby_version_gte '2.4.1'
|
|
313
|
+
context 'when a key is passed, but it is not of the right type' do
|
|
338
314
|
|
|
339
|
-
|
|
315
|
+
let(:ssl_options) do
|
|
316
|
+
key = "This is a string not a key"
|
|
317
|
+
{
|
|
318
|
+
:ssl => true,
|
|
319
|
+
:ssl_key_object => key,
|
|
320
|
+
:ssl_cert => SpecConfig.instance.client_cert_path,
|
|
321
|
+
:ssl_verify => false
|
|
322
|
+
}
|
|
323
|
+
end
|
|
340
324
|
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
:ssl_cert => SpecConfig.instance.client_cert_path,
|
|
347
|
-
:ssl_verify => false
|
|
348
|
-
}
|
|
349
|
-
end
|
|
350
|
-
|
|
351
|
-
let(:expected_exception) do
|
|
352
|
-
if SpecConfig.instance.jruby?
|
|
353
|
-
if RUBY_VERSION >= '2.5.0'
|
|
354
|
-
# jruby 9.2
|
|
355
|
-
TypeError
|
|
356
|
-
else
|
|
357
|
-
# jruby 9.1
|
|
358
|
-
OpenSSL::OpenSSLError
|
|
359
|
-
end
|
|
325
|
+
let(:expected_exception) do
|
|
326
|
+
if SpecConfig.instance.jruby?
|
|
327
|
+
if RUBY_VERSION >= '2.5.0'
|
|
328
|
+
# jruby 9.2
|
|
329
|
+
TypeError
|
|
360
330
|
else
|
|
361
|
-
|
|
331
|
+
# jruby 9.1
|
|
332
|
+
OpenSSL::OpenSSLError
|
|
362
333
|
end
|
|
334
|
+
else
|
|
335
|
+
NoMethodError
|
|
363
336
|
end
|
|
337
|
+
end
|
|
364
338
|
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
end
|
|
339
|
+
it 'raises a NoMethodError' do
|
|
340
|
+
expect do
|
|
341
|
+
socket
|
|
342
|
+
end.to raise_exception(expected_exception)
|
|
370
343
|
end
|
|
371
344
|
end
|
|
372
345
|
|
|
@@ -403,13 +376,8 @@ describe Mongo::Socket::SSL, retry: 3 do
|
|
|
403
376
|
context 'when a bad key is provided' do
|
|
404
377
|
|
|
405
378
|
let(:expected_exception) do
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
[OpenSSL::OpenSSLError, /Could not parse PKey/]
|
|
409
|
-
else
|
|
410
|
-
# ArgumentError: Could not parse PKey: no start line
|
|
411
|
-
[ArgumentError, /Could not parse PKey/]
|
|
412
|
-
end
|
|
379
|
+
# OpenSSL::PKey::PKeyError: Could not parse PKey: no start line
|
|
380
|
+
[OpenSSL::OpenSSLError, /Could not parse PKey/]
|
|
413
381
|
end
|
|
414
382
|
|
|
415
383
|
let(:ssl_options) do
|
data/spec/mongo/utils_spec.rb
CHANGED
|
@@ -39,18 +39,4 @@ describe Mongo::Utils do
|
|
|
39
39
|
}
|
|
40
40
|
end
|
|
41
41
|
end
|
|
42
|
-
|
|
43
|
-
describe '#slice_hash' do
|
|
44
|
-
it do
|
|
45
|
-
hash = {'key1' => 1, :key2 => 's', :key3 => true}
|
|
46
|
-
expect(
|
|
47
|
-
described_class.slice_hash(hash, 'key1', :key3)
|
|
48
|
-
).to eq(
|
|
49
|
-
{
|
|
50
|
-
'key1' => 1,
|
|
51
|
-
:key3 => true
|
|
52
|
-
}
|
|
53
|
-
)
|
|
54
|
-
end
|
|
55
|
-
end
|
|
56
42
|
end
|
data/spec/runners/auth.rb
CHANGED
|
@@ -32,7 +32,7 @@ module Mongo
|
|
|
32
32
|
#
|
|
33
33
|
# @since 2.6.0
|
|
34
34
|
def initialize(test_path)
|
|
35
|
-
@spec =
|
|
35
|
+
@spec = ::Utils.load_spec_yaml_file(test_path)
|
|
36
36
|
@description = File.basename(test_path)
|
|
37
37
|
@spec_tests = @spec['tests']
|
|
38
38
|
@collection_name = @spec['collection_name']
|
data/spec/runners/cmap.rb
CHANGED
|
@@ -40,7 +40,7 @@ module Mongo
|
|
|
40
40
|
#
|
|
41
41
|
# @param [ String ] test_path The path to the file.
|
|
42
42
|
def initialize(test_path)
|
|
43
|
-
@test =
|
|
43
|
+
@test = ::Utils.load_spec_yaml_file(test_path)
|
|
44
44
|
|
|
45
45
|
@description = @test['description']
|
|
46
46
|
@pool_options = ::Utils.snakeize_hash(process_options(@test['poolOptions']))
|
data/spec/runners/crud/spec.rb
CHANGED
|
@@ -12,9 +12,7 @@ module Mongo
|
|
|
12
12
|
#
|
|
13
13
|
# @since 2.0.0
|
|
14
14
|
def initialize(test_path)
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
@spec = YAML.load(contents)
|
|
15
|
+
@spec = ::Utils.load_spec_yaml_file(test_path)
|
|
18
16
|
@description = File.basename(test_path)
|
|
19
17
|
@data = BSON::ExtJSON.parse_obj(@spec['data'])
|
|
20
18
|
@tests = @spec['tests']
|
|
@@ -110,8 +110,7 @@ EOT
|
|
|
110
110
|
expected_command = expected_event.delete('command')
|
|
111
111
|
actual_command = actual_event.delete('command')
|
|
112
112
|
|
|
113
|
-
|
|
114
|
-
expected_presence = expected_command.select { |k, v| !v.nil? }
|
|
113
|
+
expected_presence = expected_command.compact
|
|
115
114
|
expected_absence = expected_command.select { |k, v| v.nil? }
|
|
116
115
|
|
|
117
116
|
expected_presence.each do |k, v|
|
data/spec/runners/gridfs.rb
CHANGED
data/spec/runners/sdam.rb
CHANGED
|
@@ -64,7 +64,7 @@ module Mongo
|
|
|
64
64
|
#
|
|
65
65
|
# @since 2.0.0
|
|
66
66
|
def initialize(test_path)
|
|
67
|
-
@test =
|
|
67
|
+
@test = ::Utils.load_spec_yaml_file(test_path)
|
|
68
68
|
@description = "#{@test['topology_description']['type']}: #{File.basename(test_path)}"
|
|
69
69
|
@heartbeat_frequency = @test['heartbeatFrequencyMS'] / 1000 if @test['heartbeatFrequencyMS']
|
|
70
70
|
@read_preference = @test['read_preference']
|
|
@@ -28,7 +28,7 @@ module Mongo
|
|
|
28
28
|
#
|
|
29
29
|
# @since 2.0.0
|
|
30
30
|
def initialize(test_path)
|
|
31
|
-
@test =
|
|
31
|
+
@test = ::Utils.load_spec_yaml_file(test_path)
|
|
32
32
|
@description = "#{File.basename(test_path)}: avg_rtt_ms: #{@test['avg_rtt_ms']}, new_rtt_ms: #{@test['new_rtt_ms']}," +
|
|
33
33
|
" new_avg_rtt: #{@test['new_avg_rtt']}"
|
|
34
34
|
@average_rtt = @test['avg_rtt_ms'] == 'NULL' ? nil : @test['avg_rtt_ms'].to_f / 1000
|
|
@@ -62,7 +62,7 @@ module Unified
|
|
|
62
62
|
def assert_outcome
|
|
63
63
|
return unless outcome
|
|
64
64
|
|
|
65
|
-
client = ClientRegistry.instance.global_client('
|
|
65
|
+
client = ClientRegistry.instance.global_client('root_authorized')
|
|
66
66
|
outcome.each do |spec|
|
|
67
67
|
spec = UsingHash[spec]
|
|
68
68
|
collection = client.use(spec.use!('databaseName'))[spec.use!('collectionName')]
|
|
@@ -217,6 +217,8 @@ module Unified
|
|
|
217
217
|
BSON::ObjectId === object
|
|
218
218
|
when 'date'
|
|
219
219
|
Time === object
|
|
220
|
+
when 'double'
|
|
221
|
+
Float === object
|
|
220
222
|
else
|
|
221
223
|
raise NotImplementedError, "Unhandled type #{type}"
|
|
222
224
|
end
|
|
@@ -8,7 +8,9 @@ module Unified
|
|
|
8
8
|
def find(op)
|
|
9
9
|
collection = entities.get(:collection, op.use!('object'))
|
|
10
10
|
use_arguments(op) do |args|
|
|
11
|
-
opts = {
|
|
11
|
+
opts = {
|
|
12
|
+
let: args.use('let'),
|
|
13
|
+
}
|
|
12
14
|
if session = args.use('session')
|
|
13
15
|
opts[:session] = entities.get(:session, session)
|
|
14
16
|
end
|
|
@@ -29,7 +31,11 @@ module Unified
|
|
|
29
31
|
def count_documents(op)
|
|
30
32
|
collection = entities.get(:collection, op.use!('object'))
|
|
31
33
|
use_arguments(op) do |args|
|
|
32
|
-
|
|
34
|
+
opts = {}
|
|
35
|
+
if session = args.use('session')
|
|
36
|
+
opts[:session] = entities.get(:session, session)
|
|
37
|
+
end
|
|
38
|
+
collection.find(args.use!('filter')).count_documents(**opts)
|
|
33
39
|
end
|
|
34
40
|
end
|
|
35
41
|
|
|
@@ -47,7 +53,11 @@ module Unified
|
|
|
47
53
|
def distinct(op)
|
|
48
54
|
collection = entities.get(:collection, op.use!('object'))
|
|
49
55
|
use_arguments(op) do |args|
|
|
50
|
-
|
|
56
|
+
opts = {}
|
|
57
|
+
if session = args.use('session')
|
|
58
|
+
opts[:session] = entities.get(:session, session)
|
|
59
|
+
end
|
|
60
|
+
req = collection.find(args.use!('filter'), **opts).distinct(args.use!('fieldName'), **opts)
|
|
51
61
|
result = req.to_a
|
|
52
62
|
end
|
|
53
63
|
end
|
|
@@ -57,10 +67,15 @@ module Unified
|
|
|
57
67
|
use_arguments(op) do |args|
|
|
58
68
|
filter = args.use!('filter')
|
|
59
69
|
update = args.use!('update')
|
|
60
|
-
opts = {
|
|
70
|
+
opts = {
|
|
71
|
+
let: args.use('let'),
|
|
72
|
+
}
|
|
61
73
|
if return_document = args.use('returnDocument')
|
|
62
74
|
opts[:return_document] = return_document.downcase.to_sym
|
|
63
75
|
end
|
|
76
|
+
if session = args.use('session')
|
|
77
|
+
opts[:session] = entities.get(:session, session)
|
|
78
|
+
end
|
|
64
79
|
collection.find_one_and_update(filter, update, **opts)
|
|
65
80
|
end
|
|
66
81
|
end
|
|
@@ -70,7 +85,13 @@ module Unified
|
|
|
70
85
|
use_arguments(op) do |args|
|
|
71
86
|
filter = args.use!('filter')
|
|
72
87
|
update = args.use!('replacement')
|
|
73
|
-
|
|
88
|
+
opts = {
|
|
89
|
+
let: args.use('let'),
|
|
90
|
+
}
|
|
91
|
+
if session = args.use('session')
|
|
92
|
+
opts[:session] = entities.get(:session, session)
|
|
93
|
+
end
|
|
94
|
+
collection.find_one_and_replace(filter, update, **opts)
|
|
74
95
|
end
|
|
75
96
|
end
|
|
76
97
|
|
|
@@ -78,7 +99,13 @@ module Unified
|
|
|
78
99
|
collection = entities.get(:collection, op.use!('object'))
|
|
79
100
|
use_arguments(op) do |args|
|
|
80
101
|
filter = args.use!('filter')
|
|
81
|
-
|
|
102
|
+
opts = {
|
|
103
|
+
let: args.use('let'),
|
|
104
|
+
}
|
|
105
|
+
if session = args.use('session')
|
|
106
|
+
opts[:session] = entities.get(:session, session)
|
|
107
|
+
end
|
|
108
|
+
collection.find_one_and_delete(filter, **opts)
|
|
82
109
|
end
|
|
83
110
|
end
|
|
84
111
|
|
|
@@ -96,25 +123,37 @@ module Unified
|
|
|
96
123
|
def insert_many(op)
|
|
97
124
|
collection = entities.get(:collection, op.use!('object'))
|
|
98
125
|
use_arguments(op) do |args|
|
|
99
|
-
|
|
126
|
+
opts = {}
|
|
100
127
|
unless (ordered = args.use('ordered')).nil?
|
|
101
|
-
|
|
128
|
+
opts[:ordered] = ordered
|
|
129
|
+
end
|
|
130
|
+
if session = args.use('session')
|
|
131
|
+
opts[:session] = entities.get(:session, session)
|
|
102
132
|
end
|
|
103
|
-
collection.insert_many(args.use!('documents'), **
|
|
133
|
+
collection.insert_many(args.use!('documents'), **opts)
|
|
104
134
|
end
|
|
105
135
|
end
|
|
106
136
|
|
|
107
137
|
def update_one(op)
|
|
108
138
|
collection = entities.get(:collection, op.use!('object'))
|
|
109
139
|
use_arguments(op) do |args|
|
|
110
|
-
|
|
140
|
+
opts = {
|
|
141
|
+
let: args.use('let'),
|
|
142
|
+
}
|
|
143
|
+
if session = args.use('session')
|
|
144
|
+
opts[:session] = entities.get(:session, session)
|
|
145
|
+
end
|
|
146
|
+
collection.update_one(args.use!('filter'), args.use!('update'), **opts)
|
|
111
147
|
end
|
|
112
148
|
end
|
|
113
149
|
|
|
114
150
|
def update_many(op)
|
|
115
151
|
collection = entities.get(:collection, op.use!('object'))
|
|
116
152
|
use_arguments(op) do |args|
|
|
117
|
-
|
|
153
|
+
opts = {
|
|
154
|
+
let: args.use('let'),
|
|
155
|
+
}
|
|
156
|
+
collection.update_many(args.use!('filter'), args.use!('update'), **opts)
|
|
118
157
|
end
|
|
119
158
|
end
|
|
120
159
|
|
|
@@ -132,14 +171,23 @@ module Unified
|
|
|
132
171
|
def delete_one(op)
|
|
133
172
|
collection = entities.get(:collection, op.use!('object'))
|
|
134
173
|
use_arguments(op) do |args|
|
|
135
|
-
|
|
174
|
+
opts = {
|
|
175
|
+
let: args.use('let'),
|
|
176
|
+
}
|
|
177
|
+
if session = args.use('session')
|
|
178
|
+
opts[:session] = entities.get(:session, session)
|
|
179
|
+
end
|
|
180
|
+
collection.delete_one(args.use!('filter'), **opts)
|
|
136
181
|
end
|
|
137
182
|
end
|
|
138
183
|
|
|
139
184
|
def delete_many(op)
|
|
140
185
|
collection = entities.get(:collection, op.use!('object'))
|
|
141
186
|
use_arguments(op) do |args|
|
|
142
|
-
|
|
187
|
+
opts = {
|
|
188
|
+
let: args.use('let'),
|
|
189
|
+
}
|
|
190
|
+
collection.delete_many(args.use!('filter'), **opts)
|
|
143
191
|
end
|
|
144
192
|
end
|
|
145
193
|
|
|
@@ -157,6 +205,22 @@ module Unified
|
|
|
157
205
|
end
|
|
158
206
|
end
|
|
159
207
|
|
|
208
|
+
def aggregate(op)
|
|
209
|
+
obj = entities.get_any(op.use!('object'))
|
|
210
|
+
args = op.use!('arguments')
|
|
211
|
+
pipeline = args.use!('pipeline')
|
|
212
|
+
opts = {
|
|
213
|
+
let: args.use('let'),
|
|
214
|
+
}
|
|
215
|
+
if session = args.use('session')
|
|
216
|
+
opts[:session] = entities.get(:session, session)
|
|
217
|
+
end
|
|
218
|
+
unless args.empty?
|
|
219
|
+
raise NotImplementedError, "Unhandled spec keys: #{args} in #{test_spec}"
|
|
220
|
+
end
|
|
221
|
+
obj.aggregate(pipeline, **opts).to_a
|
|
222
|
+
end
|
|
223
|
+
|
|
160
224
|
private
|
|
161
225
|
|
|
162
226
|
def convert_bulk_write_spec(spec)
|
|
@@ -192,15 +256,5 @@ module Unified
|
|
|
192
256
|
end
|
|
193
257
|
{Utils.underscore(op) =>out}
|
|
194
258
|
end
|
|
195
|
-
|
|
196
|
-
def aggregate(op)
|
|
197
|
-
obj = entities.get_any(op.use!('object'))
|
|
198
|
-
args = op.use!('arguments')
|
|
199
|
-
pipeline = args.use!('pipeline')
|
|
200
|
-
unless args.empty?
|
|
201
|
-
raise NotImplementedError, "Unhandled spec keys: #{test_spec}"
|
|
202
|
-
end
|
|
203
|
-
obj.aggregate(pipeline).to_a
|
|
204
|
-
end
|
|
205
259
|
end
|
|
206
260
|
end
|
|
@@ -7,7 +7,13 @@ module Unified
|
|
|
7
7
|
|
|
8
8
|
def list_databases(op)
|
|
9
9
|
client = entities.get(:client, op.use!('object'))
|
|
10
|
-
|
|
10
|
+
use_arguments(op) do |args|
|
|
11
|
+
opts = {}
|
|
12
|
+
if session = args.use('session')
|
|
13
|
+
opts[:session] = entities.get(:session, session)
|
|
14
|
+
end
|
|
15
|
+
client.list_databases({}, false, **opts)
|
|
16
|
+
end
|
|
11
17
|
end
|
|
12
18
|
|
|
13
19
|
def create_collection(op)
|
|
@@ -28,6 +34,17 @@ module Unified
|
|
|
28
34
|
end
|
|
29
35
|
end
|
|
30
36
|
|
|
37
|
+
def list_collections(op)
|
|
38
|
+
database = entities.get(:database, op.use!('object'))
|
|
39
|
+
use_arguments(op) do |args|
|
|
40
|
+
opts = {}
|
|
41
|
+
if session = args.use('session')
|
|
42
|
+
opts[:session] = entities.get(:session, session)
|
|
43
|
+
end
|
|
44
|
+
database.list_collections(**opts)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
31
48
|
def drop_collection(op)
|
|
32
49
|
database = entities.get(:database, op.use!('object'))
|
|
33
50
|
use_arguments(op) do |args|
|
|
@@ -58,6 +75,17 @@ module Unified
|
|
|
58
75
|
assert_collection_exists(op, false)
|
|
59
76
|
end
|
|
60
77
|
|
|
78
|
+
def list_indexes(op)
|
|
79
|
+
collection = entities.get(:collection, op.use!('object'))
|
|
80
|
+
use_arguments(op) do |args|
|
|
81
|
+
opts = {}
|
|
82
|
+
if session = args.use('session')
|
|
83
|
+
opts[:session] = entities.get(:session, session)
|
|
84
|
+
end
|
|
85
|
+
collection.indexes(**opts).to_a
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
61
89
|
def create_index(op)
|
|
62
90
|
collection = entities.get(:collection, op.use!('object'))
|
|
63
91
|
use_arguments(op) do |args|
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
|
|
4
4
|
module Unified
|
|
5
5
|
class EntityMap
|
|
6
|
+
extend Forwardable
|
|
7
|
+
|
|
6
8
|
def initialize
|
|
7
9
|
@map = {}
|
|
8
10
|
end
|
|
@@ -35,8 +37,6 @@ module Unified
|
|
|
35
37
|
raise Error::EntityMissing, "There is no #{id} known"
|
|
36
38
|
end
|
|
37
39
|
|
|
38
|
-
|
|
39
|
-
@map[type]
|
|
40
|
-
end
|
|
40
|
+
def_delegators :@map, :[], :fetch
|
|
41
41
|
end
|
|
42
42
|
end
|
|
@@ -160,13 +160,24 @@ module Unified
|
|
|
160
160
|
end
|
|
161
161
|
when 'database'
|
|
162
162
|
client = entities.get(:client, spec.use!('client'))
|
|
163
|
-
|
|
163
|
+
opts = Utils.snakeize_hash(spec.use('databaseOptions') || {})
|
|
164
|
+
.merge(database: spec.use!('databaseName'))
|
|
165
|
+
if opts.key?(:read_preference)
|
|
166
|
+
opts[:read] = opts.delete(:read_preference)
|
|
167
|
+
if opts[:read].key?(:max_staleness_seconds)
|
|
168
|
+
opts[:read][:max_staleness] = opts[:read].delete(:max_staleness_seconds)
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
client.with(opts).database
|
|
164
172
|
when 'collection'
|
|
165
173
|
database = entities.get(:database, spec.use!('database'))
|
|
166
174
|
# TODO verify
|
|
167
175
|
opts = Utils.snakeize_hash(spec.use('collectionOptions') || {})
|
|
168
176
|
if opts.key?(:read_preference)
|
|
169
177
|
opts[:read] = opts.delete(:read_preference)
|
|
178
|
+
if opts[:read].key?(:max_staleness_seconds)
|
|
179
|
+
opts[:read][:max_staleness] = opts[:read].delete(:max_staleness_seconds)
|
|
180
|
+
end
|
|
170
181
|
end
|
|
171
182
|
database[spec.use!('collectionName'), opts]
|
|
172
183
|
when 'bucket'
|
|
@@ -195,7 +206,8 @@ module Unified
|
|
|
195
206
|
def set_initial_data
|
|
196
207
|
@spec['initialData']&.each do |entity_spec|
|
|
197
208
|
spec = UsingHash[entity_spec]
|
|
198
|
-
collection = root_authorized_client.
|
|
209
|
+
collection = root_authorized_client.with(write_concern: {w: :majority}).
|
|
210
|
+
use(spec.use!('databaseName'))[spec.use!('collectionName')]
|
|
199
211
|
collection.drop
|
|
200
212
|
docs = spec.use!('documents')
|
|
201
213
|
if docs.any?
|
|
@@ -268,7 +280,7 @@ module Unified
|
|
|
268
280
|
end
|
|
269
281
|
if expected_error = op.use('expectError')
|
|
270
282
|
begin
|
|
271
|
-
|
|
283
|
+
public_send(method_name, op)
|
|
272
284
|
rescue Mongo::Error, BSON::String::IllegalKey => e
|
|
273
285
|
if expected_error.use('isClientError')
|
|
274
286
|
# isClientError doesn't actually mean a client error.
|