mongo 2.4.0 → 2.4.1
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/collection.rb +7 -7
- data/lib/mongo/collection/view.rb +9 -2
- data/lib/mongo/collection/view/aggregation.rb +2 -2
- data/lib/mongo/collection/view/builder/map_reduce.rb +11 -3
- data/lib/mongo/collection/view/iterable.rb +1 -1
- data/lib/mongo/collection/view/map_reduce.rb +2 -2
- data/lib/mongo/collection/view/readable.rb +27 -25
- data/lib/mongo/collection/view/writable.rb +15 -23
- data/lib/mongo/index/view.rb +2 -1
- data/lib/mongo/uri.rb +5 -4
- data/lib/mongo/version.rb +1 -1
- data/mongo.gemspec +1 -1
- data/spec/mongo/collection/view/aggregation_spec.rb +25 -7
- data/spec/mongo/collection/view/map_reduce_spec.rb +111 -13
- data/spec/mongo/collection/view/readable_spec.rb +207 -1
- data/spec/mongo/collection/view/writable_spec.rb +398 -5
- data/spec/mongo/collection_spec.rb +48 -39
- data/spec/mongo/sdam_spec.rb +17 -10
- data/spec/mongo/uri_spec.rb +25 -0
- data/spec/spec_helper.rb +5 -1
- data/spec/support/sdam/rs/primary_mismatched_me.yml +2 -2
- data/spec/support/sdam/rs/secondary_mismatched_me.yml +2 -2
- metadata +20 -14
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9112b76649bf922ef773b7a9018ad8b46de12760
|
4
|
+
data.tar.gz: d152ad097652a5c4ec4351f9c86a58de77c44977
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dbdc8eeb2763a4ce969c20323188997bdc37e7f8b1f0b54fe8ef4288141ec3a43bd61f1e3f8d89b46bae2c8ae875068bc583e3b17eff1631319da2342c283c86
|
7
|
+
data.tar.gz: 6ca6c80afad5e7882d5c31f5a6c2446a01fb5ed46c1de13f5d8df6dd78d47636ce9253522150dcbf7844f768a07f56670a15bcb264e5c4a9c03475437f302c22
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/lib/mongo/collection.rb
CHANGED
@@ -291,7 +291,7 @@ module Mongo
|
|
291
291
|
#
|
292
292
|
# @since 2.1.0
|
293
293
|
def count(filter = nil, options = {})
|
294
|
-
View.new(self, filter || {}).count(options)
|
294
|
+
View.new(self, filter || {}, options).count(options)
|
295
295
|
end
|
296
296
|
|
297
297
|
# Get a list of distinct values for a specific field.
|
@@ -311,7 +311,7 @@ module Mongo
|
|
311
311
|
#
|
312
312
|
# @since 2.1.0
|
313
313
|
def distinct(field_name, filter = nil, options = {})
|
314
|
-
View.new(self, filter || {}).distinct(field_name, options)
|
314
|
+
View.new(self, filter || {}, options).distinct(field_name, options)
|
315
315
|
end
|
316
316
|
|
317
317
|
# Get a view of all indexes for this collection. Can be iterated or has
|
@@ -418,7 +418,7 @@ module Mongo
|
|
418
418
|
#
|
419
419
|
# @since 2.1.0
|
420
420
|
def delete_one(filter = nil, options = {})
|
421
|
-
find(filter).delete_one(options)
|
421
|
+
find(filter, options).delete_one(options)
|
422
422
|
end
|
423
423
|
|
424
424
|
# Remove documents from the collection.
|
@@ -435,7 +435,7 @@ module Mongo
|
|
435
435
|
#
|
436
436
|
# @since 2.1.0
|
437
437
|
def delete_many(filter = nil, options = {})
|
438
|
-
find(filter).delete_many(options)
|
438
|
+
find(filter, options).delete_many(options)
|
439
439
|
end
|
440
440
|
|
441
441
|
# Execute a parallel scan on the collection view.
|
@@ -479,7 +479,7 @@ module Mongo
|
|
479
479
|
#
|
480
480
|
# @since 2.1.0
|
481
481
|
def replace_one(filter, replacement, options = {})
|
482
|
-
find(filter).replace_one(replacement, options)
|
482
|
+
find(filter, options).replace_one(replacement, options)
|
483
483
|
end
|
484
484
|
|
485
485
|
# Update documents in the collection.
|
@@ -501,7 +501,7 @@ module Mongo
|
|
501
501
|
#
|
502
502
|
# @since 2.1.0
|
503
503
|
def update_many(filter, update, options = {})
|
504
|
-
find(filter).update_many(update, options)
|
504
|
+
find(filter, options).update_many(update, options)
|
505
505
|
end
|
506
506
|
|
507
507
|
# Update a single document in the collection.
|
@@ -523,7 +523,7 @@ module Mongo
|
|
523
523
|
#
|
524
524
|
# @since 2.1.0
|
525
525
|
def update_one(filter, update, options = {})
|
526
|
-
find(filter).update_one(update, options)
|
526
|
+
find(filter, options).update_one(update, options)
|
527
527
|
end
|
528
528
|
|
529
529
|
# Finds a single document in the database via findAndModify and deletes
|
@@ -177,8 +177,15 @@ module Mongo
|
|
177
177
|
View.new(collection, filter, options)
|
178
178
|
end
|
179
179
|
|
180
|
-
def
|
181
|
-
if
|
180
|
+
def apply_collation!(doc, server, opts = {})
|
181
|
+
if coll = opts[:collation] || opts['collation'] || collation
|
182
|
+
validate_collation!(server, coll)
|
183
|
+
doc[:collation] = coll
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
def validate_collation!(server, coll)
|
188
|
+
if coll &&!server.features.collation_enabled?
|
182
189
|
raise Error::UnsupportedCollation.new
|
183
190
|
end
|
184
191
|
end
|
@@ -73,7 +73,7 @@ module Mongo
|
|
73
73
|
def initialize(view, pipeline, options = {})
|
74
74
|
@view = view
|
75
75
|
@pipeline = pipeline.dup
|
76
|
-
@options = options.
|
76
|
+
@options = BSON::Document.new(options).freeze
|
77
77
|
end
|
78
78
|
|
79
79
|
# Get the explain plan for the aggregation.
|
@@ -120,7 +120,7 @@ module Mongo
|
|
120
120
|
end
|
121
121
|
|
122
122
|
def validate_collation!(server)
|
123
|
-
if
|
123
|
+
if options[:collation] && !server.features.collation_enabled?
|
124
124
|
raise Error::UnsupportedCollation.new
|
125
125
|
end
|
126
126
|
end
|
@@ -80,7 +80,7 @@ module Mongo
|
|
80
80
|
def command_specification
|
81
81
|
{
|
82
82
|
selector: find_command,
|
83
|
-
db_name:
|
83
|
+
db_name: query_database,
|
84
84
|
read: read
|
85
85
|
}
|
86
86
|
end
|
@@ -94,7 +94,7 @@ module Mongo
|
|
94
94
|
#
|
95
95
|
# @since 2.2.0
|
96
96
|
def query_specification
|
97
|
-
{ selector: {}, options: {}, db_name:
|
97
|
+
{ selector: {}, options: {}, db_name: query_database, coll_name: query_collection }
|
98
98
|
end
|
99
99
|
|
100
100
|
# Get the specification to pass to the map/reduce operation.
|
@@ -116,6 +116,8 @@ module Mongo
|
|
116
116
|
|
117
117
|
private
|
118
118
|
|
119
|
+
OUT_ACTIONS = [ :replace, :merge, :reduce ].freeze
|
120
|
+
|
119
121
|
def write?(spec)
|
120
122
|
if out = spec[:selector][:out]
|
121
123
|
out.is_a?(String) ||
|
@@ -141,8 +143,14 @@ module Mongo
|
|
141
143
|
command
|
142
144
|
end
|
143
145
|
|
146
|
+
def query_database
|
147
|
+
options[:out].respond_to?(:keys) && options[:out][:db] ? options[:out][:db] : database.name
|
148
|
+
end
|
149
|
+
|
144
150
|
def query_collection
|
145
|
-
options[:out].respond_to?(:keys)
|
151
|
+
if options[:out].respond_to?(:keys)
|
152
|
+
options[:out][OUT_ACTIONS.find { |action| options[:out][action] }]
|
153
|
+
end || options[:out]
|
146
154
|
end
|
147
155
|
end
|
148
156
|
end
|
@@ -107,7 +107,7 @@ module Mongo
|
|
107
107
|
@view = view
|
108
108
|
@map = map.freeze
|
109
109
|
@reduce = reduce.freeze
|
110
|
-
@options = options.freeze
|
110
|
+
@options = BSON::Document.new(options).freeze
|
111
111
|
end
|
112
112
|
|
113
113
|
# Set or get the jsMode flag for the operation.
|
@@ -237,7 +237,7 @@ module Mongo
|
|
237
237
|
end
|
238
238
|
|
239
239
|
def validate_collation!(server)
|
240
|
-
if (options[:collation] || options[
|
240
|
+
if (view.options[:collation] || options[:collation]) && !server.features.collation_enabled?
|
241
241
|
raise Error::UnsupportedCollation.new
|
242
242
|
end
|
243
243
|
end
|
@@ -112,31 +112,30 @@ module Mongo
|
|
112
112
|
# @example Get the number of documents in the collection.
|
113
113
|
# collection_view.count
|
114
114
|
#
|
115
|
-
# @param [ Hash ]
|
115
|
+
# @param [ Hash ] opts Options for the count command.
|
116
116
|
#
|
117
|
-
# @option
|
118
|
-
# @option
|
117
|
+
# @option opts :skip [ Integer ] The number of documents to skip.
|
118
|
+
# @option opts :hint [ Hash ] Override default index selection and force
|
119
119
|
# MongoDB to use a specific index for the query.
|
120
|
-
# @option
|
121
|
-
# @option
|
120
|
+
# @option opts :limit [ Integer ] Max number of docs to return.
|
121
|
+
# @option opts :max_time_ms [ Integer ] The maximum amount of time to allow the
|
122
122
|
# command to run.
|
123
|
-
# @option
|
124
|
-
# @option
|
123
|
+
# @option opts [ Hash ] :read The read preference options.
|
124
|
+
# @option opts [ Hash ] :collation The collation to use.
|
125
125
|
#
|
126
126
|
# @return [ Integer ] The document count.
|
127
127
|
#
|
128
128
|
# @since 2.0.0
|
129
|
-
def count(
|
129
|
+
def count(opts = {})
|
130
130
|
cmd = { :count => collection.name, :query => filter }
|
131
|
-
cmd[:skip] =
|
132
|
-
cmd[:hint] =
|
133
|
-
cmd[:limit] =
|
134
|
-
cmd[:maxTimeMS] =
|
131
|
+
cmd[:skip] = opts[:skip] if opts[:skip]
|
132
|
+
cmd[:hint] = opts[:hint] if opts[:hint]
|
133
|
+
cmd[:limit] = opts[:limit] if opts[:limit]
|
134
|
+
cmd[:maxTimeMS] = opts[:max_time_ms] if opts[:max_time_ms]
|
135
135
|
cmd[:readConcern] = collection.read_concern if collection.read_concern
|
136
|
-
preference = ServerSelector.get(
|
136
|
+
preference = ServerSelector.get(opts[:read] || read)
|
137
137
|
server = preference.select_server(cluster)
|
138
|
-
|
139
|
-
cmd[:collation] = options[:collation] if options[:collation]
|
138
|
+
apply_collation!(cmd, server, opts)
|
140
139
|
read_with_retry do
|
141
140
|
Operation::Commands::Command.new({
|
142
141
|
:selector => cmd,
|
@@ -154,26 +153,25 @@ module Mongo
|
|
154
153
|
# collection_view.distinct('name')
|
155
154
|
#
|
156
155
|
# @param [ String, Symbol ] field_name The name of the field.
|
157
|
-
# @param [ Hash ]
|
156
|
+
# @param [ Hash ] opts Options for the distinct command.
|
158
157
|
#
|
159
|
-
# @option
|
158
|
+
# @option opts :max_time_ms [ Integer ] The maximum amount of time to allow the
|
160
159
|
# command to run.
|
161
|
-
# @option
|
162
|
-
# @option
|
160
|
+
# @option opts [ Hash ] :read The read preference options.
|
161
|
+
# @option opts [ Hash ] :collation The collation to use.
|
163
162
|
#
|
164
163
|
# @return [ Array<Object> ] The list of distinct values.
|
165
164
|
#
|
166
165
|
# @since 2.0.0
|
167
|
-
def distinct(field_name,
|
166
|
+
def distinct(field_name, opts = {})
|
168
167
|
cmd = { :distinct => collection.name,
|
169
168
|
:key => field_name.to_s,
|
170
169
|
:query => filter }
|
171
|
-
cmd[:maxTimeMS] =
|
170
|
+
cmd[:maxTimeMS] = opts[:max_time_ms] if opts[:max_time_ms]
|
172
171
|
cmd[:readConcern] = collection.read_concern if collection.read_concern
|
173
|
-
preference = ServerSelector.get(
|
172
|
+
preference = ServerSelector.get(opts[:read] || read)
|
174
173
|
server = preference.select_server(cluster)
|
175
|
-
|
176
|
-
cmd[:collation] = options[:collation] if options[:collation]
|
174
|
+
apply_collation!(cmd, server, opts)
|
177
175
|
read_with_retry do
|
178
176
|
Operation::Commands::Command.new({
|
179
177
|
:selector => cmd,
|
@@ -455,8 +453,12 @@ module Mongo
|
|
455
453
|
|
456
454
|
private
|
457
455
|
|
456
|
+
def collation(doc = nil)
|
457
|
+
configure(:collation, doc)
|
458
|
+
end
|
459
|
+
|
458
460
|
def default_read
|
459
|
-
options[:read] || read_preference
|
461
|
+
options[:read] || collection.read_preference
|
460
462
|
end
|
461
463
|
|
462
464
|
def parallel_scan(cursor_count, options = {})
|
@@ -27,10 +27,14 @@ module Mongo
|
|
27
27
|
# @example Find one document and delete it.
|
28
28
|
# view.find_one_and_delete
|
29
29
|
#
|
30
|
+
# @param [ Hash ] opts The options.
|
31
|
+
#
|
32
|
+
# @option opts [ Hash ] :collation The collation to use.
|
33
|
+
#
|
30
34
|
# @return [ BSON::Document, nil ] The document, if found.
|
31
35
|
#
|
32
36
|
# @since 2.0.0
|
33
|
-
def find_one_and_delete
|
37
|
+
def find_one_and_delete(opts = {})
|
34
38
|
cmd = { :findandmodify => collection.name, :query => filter, :remove => true }
|
35
39
|
cmd[:fields] = projection if projection
|
36
40
|
cmd[:sort] = sort if sort
|
@@ -38,8 +42,7 @@ module Mongo
|
|
38
42
|
cmd[:writeConcern] = write_concern.options if write_concern
|
39
43
|
|
40
44
|
server = next_primary
|
41
|
-
|
42
|
-
cmd[:collation] = options[:collation] if options[:collation]
|
45
|
+
apply_collation!(cmd, server, opts)
|
43
46
|
|
44
47
|
write_with_retry do
|
45
48
|
Operation::Commands::Command.new({
|
@@ -66,6 +69,7 @@ module Mongo
|
|
66
69
|
# not to skip document level validation.
|
67
70
|
# @option options [ Hash ] :write_concern The write concern options.
|
68
71
|
# Defaults to the collection's write concern.
|
72
|
+
# @option opts [ Hash ] :collation The collation to use.
|
69
73
|
#
|
70
74
|
# @return [ BSON::Document ] The document.
|
71
75
|
#
|
@@ -88,6 +92,7 @@ module Mongo
|
|
88
92
|
# not to skip document level validation.
|
89
93
|
# @option opts [ Hash ] :write_concern The write concern options.
|
90
94
|
# Defaults to the collection's write concern.
|
95
|
+
# @option opts [ Hash ] :collation The collation to use.
|
91
96
|
#
|
92
97
|
# @return [ BSON::Document ] The document.
|
93
98
|
#
|
@@ -104,9 +109,8 @@ module Mongo
|
|
104
109
|
cmd[:writeConcern] = write_concern.options if write_concern
|
105
110
|
|
106
111
|
server = next_primary
|
107
|
-
|
108
|
-
|
109
|
-
|
112
|
+
apply_collation!(cmd, server, opts)
|
113
|
+
|
110
114
|
value = write_with_retry do
|
111
115
|
Operation::Commands::Command.new({
|
112
116
|
:selector => cmd,
|
@@ -207,16 +211,10 @@ module Mongo
|
|
207
211
|
|
208
212
|
private
|
209
213
|
|
210
|
-
def remove(value, opts)
|
211
|
-
server = next_primary
|
212
|
-
validate_collation!(server, opts)
|
214
|
+
def remove(value, opts = {})
|
213
215
|
delete_doc = { Operation::Q => filter, Operation::LIMIT => value }
|
214
|
-
|
215
|
-
|
216
|
-
# Otherwise, the collation will silently not be sent.
|
217
|
-
if collation = opts[:collation] || opts[Operation::COLLATION]
|
218
|
-
delete_doc[:collation] = collation
|
219
|
-
end
|
216
|
+
server = next_primary
|
217
|
+
apply_collation!(delete_doc, server, opts)
|
220
218
|
write_with_retry do
|
221
219
|
Operation::Write::Delete.new(
|
222
220
|
:delete => delete_doc,
|
@@ -228,18 +226,12 @@ module Mongo
|
|
228
226
|
end
|
229
227
|
|
230
228
|
def update(spec, multi, opts)
|
231
|
-
server = next_primary
|
232
|
-
validate_collation!(server, opts)
|
233
229
|
update_doc = { Operation::Q => filter,
|
234
230
|
Operation::U => spec,
|
235
231
|
Operation::MULTI => multi,
|
236
232
|
Operation::UPSERT => !!opts[:upsert] }
|
237
|
-
|
238
|
-
|
239
|
-
# Otherwise, the collation will silently not be sent.
|
240
|
-
if collation = opts[:collation] || opts[Operation::COLLATION]
|
241
|
-
update_doc[:collation] = collation
|
242
|
-
end
|
233
|
+
server = next_primary
|
234
|
+
apply_collation!(update_doc, server, opts)
|
243
235
|
write_with_retry do
|
244
236
|
Operation::Write::Update.new(
|
245
237
|
:update => update_doc,
|
data/lib/mongo/index/view.rb
CHANGED
@@ -271,7 +271,8 @@ module Mongo
|
|
271
271
|
end
|
272
272
|
|
273
273
|
def validate_collation!(model, server)
|
274
|
-
if (model[:collation] || model[Operation::COLLATION]) &&
|
274
|
+
if (model[:collation] || model[Operation::COLLATION]) &&
|
275
|
+
!server.features.collation_enabled?
|
275
276
|
raise Error::UnsupportedCollation.new
|
276
277
|
end
|
277
278
|
end
|
data/lib/mongo/uri.rb
CHANGED
@@ -168,10 +168,11 @@ module Mongo
|
|
168
168
|
#
|
169
169
|
# @since 2.0.0
|
170
170
|
AUTH_MECH_MAP = {
|
171
|
-
'PLAIN'
|
172
|
-
'MONGODB-CR'
|
173
|
-
'GSSAPI'
|
174
|
-
'
|
171
|
+
'PLAIN' => :plain,
|
172
|
+
'MONGODB-CR' => :mongodb_cr,
|
173
|
+
'GSSAPI' => :gssapi,
|
174
|
+
'MONGODB-X509' => :mongodb_x509,
|
175
|
+
'SCRAM-SHA-1' => :scram
|
175
176
|
}.freeze
|
176
177
|
|
177
178
|
# Options that are allowed to appear more than once in the uri.
|
data/lib/mongo/version.rb
CHANGED
data/mongo.gemspec
CHANGED
@@ -189,7 +189,7 @@ describe Mongo::Collection::View::Aggregation do
|
|
189
189
|
end
|
190
190
|
|
191
191
|
it 'sets the options' do
|
192
|
-
expect(aggregation.options).to eq(options)
|
192
|
+
expect(aggregation.options).to eq(BSON::Document.new(options))
|
193
193
|
end
|
194
194
|
|
195
195
|
it 'dups the options' do
|
@@ -213,23 +213,41 @@ describe Mongo::Collection::View::Aggregation do
|
|
213
213
|
[{ "$match" => { "name" => "BANG" } }]
|
214
214
|
end
|
215
215
|
|
216
|
-
let(:options) do
|
217
|
-
{ collation: { locale: 'en_US', strength: 2 } }
|
218
|
-
end
|
219
|
-
|
220
216
|
let(:result) do
|
221
217
|
aggregation.explain['$cursor']['queryPlanner']['collation']['locale']
|
222
218
|
end
|
223
219
|
|
224
220
|
context 'when the server selected supports collations', if: collation_enabled? do
|
225
221
|
|
226
|
-
|
227
|
-
|
222
|
+
context 'when the collation key is a String' do
|
223
|
+
|
224
|
+
let(:options) do
|
225
|
+
{ 'collation' => { locale: 'en_US', strength: 2 } }
|
226
|
+
end
|
227
|
+
|
228
|
+
it 'applies the collation' do
|
229
|
+
expect(result).to eq('en_US')
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
context 'when the collation key is a Symbol' do
|
234
|
+
|
235
|
+
let(:options) do
|
236
|
+
{ collation: { locale: 'en_US', strength: 2 } }
|
237
|
+
end
|
238
|
+
|
239
|
+
it 'applies the collation' do
|
240
|
+
expect(result).to eq('en_US')
|
241
|
+
end
|
228
242
|
end
|
229
243
|
end
|
230
244
|
|
231
245
|
context 'when the server selected does not support collations', unless: collation_enabled? do
|
232
246
|
|
247
|
+
let(:options) do
|
248
|
+
{ collation: { locale: 'en_US', strength: 2 } }
|
249
|
+
end
|
250
|
+
|
233
251
|
it 'raises an exception' do
|
234
252
|
expect {
|
235
253
|
result
|