mongo 2.0.4 → 2.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/lib/mongo/address.rb +1 -1
  5. data/lib/mongo/address/ipv4.rb +8 -4
  6. data/lib/mongo/address/ipv6.rb +8 -4
  7. data/lib/mongo/address/unix.rb +2 -2
  8. data/lib/mongo/auth/user/view.rb +5 -1
  9. data/lib/mongo/bulk_write/bulk_writable.rb +5 -0
  10. data/lib/mongo/bulk_write/deletable.rb +0 -4
  11. data/lib/mongo/bulk_write/insertable.rb +0 -4
  12. data/lib/mongo/client.rb +30 -2
  13. data/lib/mongo/collection/view/aggregation.rb +17 -4
  14. data/lib/mongo/collection/view/map_reduce.rb +19 -2
  15. data/lib/mongo/database.rb +12 -0
  16. data/lib/mongo/database/view.rb +12 -0
  17. data/lib/mongo/grid/fs.rb +5 -5
  18. data/lib/mongo/loggable.rb +5 -3
  19. data/lib/mongo/logger.rb +21 -5
  20. data/lib/mongo/operation/aggregate.rb +18 -11
  21. data/lib/mongo/operation/aggregate/result.rb +16 -1
  22. data/lib/mongo/operation/map_reduce.rb +7 -9
  23. data/lib/mongo/operation/read/query.rb +1 -1
  24. data/lib/mongo/operation/read_preferrable.rb +11 -5
  25. data/lib/mongo/operation/result.rb +5 -1
  26. data/lib/mongo/operation/write.rb +1 -0
  27. data/lib/mongo/operation/write/command.rb +1 -0
  28. data/lib/mongo/operation/write/command/update_user.rb +43 -0
  29. data/lib/mongo/operation/write/update_user.rb +75 -0
  30. data/lib/mongo/protocol/reply.rb +12 -0
  31. data/lib/mongo/server/connection_pool/queue.rb +3 -3
  32. data/lib/mongo/socket.rb +22 -11
  33. data/lib/mongo/socket/ssl.rb +6 -3
  34. data/lib/mongo/version.rb +1 -1
  35. data/spec/mongo/auth/user/view_spec.rb +42 -0
  36. data/spec/mongo/client_spec.rb +19 -0
  37. data/spec/mongo/cluster_spec.rb +2 -1
  38. data/spec/mongo/collection/view/aggregation_spec.rb +34 -1
  39. data/spec/mongo/collection/view/map_reduce_spec.rb +92 -0
  40. data/spec/mongo/collection/view_spec.rb +14 -11
  41. data/spec/mongo/collection_spec.rb +13 -0
  42. data/spec/mongo/database_spec.rb +29 -0
  43. data/spec/mongo/grid/fs_spec.rb +32 -1
  44. data/spec/mongo/loggable_spec.rb +2 -1
  45. data/spec/mongo/operation/read/query_spec.rb +19 -0
  46. data/spec/mongo/operation/read_preferrable_spec.rb +192 -0
  47. data/spec/mongo/operation/write/update_user_spec.rb +46 -0
  48. data/spec/mongo/server/connection_pool/queue_spec.rb +4 -0
  49. data/spec/mongo/socket/ssl_spec.rb +21 -1
  50. data/spec/spec_helper.rb +4 -0
  51. data/spec/support/authorization.rb +6 -4
  52. data/spec/support/shared/operation.rb +12 -0
  53. metadata +9 -3
  54. metadata.gz.sig +0 -0
@@ -569,4 +569,23 @@ describe Mongo::Client do
569
569
  end
570
570
  end
571
571
  end
572
+
573
+ describe '#database_names' do
574
+
575
+ it 'returns a list of database names' do
576
+ expect(root_authorized_client.database_names).to include(
577
+ 'admin'
578
+ )
579
+ end
580
+ end
581
+
582
+ describe '#list_databases' do
583
+
584
+ it 'returns a list of database info documents' do
585
+ expect(
586
+ root_authorized_client.list_databases.collect do |i|
587
+ i['name']
588
+ end).to include('admin')
589
+ end
590
+ end
572
591
  end
@@ -76,7 +76,8 @@ describe Mongo::Cluster do
76
76
  context 'when the option is provided' do
77
77
 
78
78
  let(:cluster) do
79
- described_class.new([ '127.0.0.1:27017' ], TEST_OPTIONS.merge(:replica_set => 'testing'))
79
+ described_class.new([ '127.0.0.1:27017' ], TEST_OPTIONS.merge(:connect => :replica_set,
80
+ :replica_set => 'testing'))
80
81
  end
81
82
 
82
83
  it 'returns the name' do
@@ -39,7 +39,7 @@ describe Mongo::Collection::View::Aggregation do
39
39
 
40
40
  describe '#each' do
41
41
 
42
- let(:documents) do
42
+ let(:documents) do
43
43
  [
44
44
  { city: "Berlin", pop: 18913, neighborhood: "Kreuzberg" },
45
45
  { city: "Berlin", pop: 84143, neighborhood: "Mitte" },
@@ -145,4 +145,37 @@ describe Mongo::Collection::View::Aggregation do
145
145
  expect(aggregation.options).not_to be(options)
146
146
  end
147
147
  end
148
+
149
+ describe '#explain' do
150
+
151
+ it 'executes an explain' do
152
+ expect(aggregation.explain).to_not be_empty
153
+ end
154
+ end
155
+
156
+ describe '#aggregate_spec' do
157
+
158
+ context 'when the collection has a read preference' do
159
+
160
+ let(:read_preference) do
161
+ Mongo::ServerSelector.get(mode: :secondary)
162
+ end
163
+
164
+ it 'includes the read preference in the spec' do
165
+ allow(authorized_collection).to receive(:read_preference).and_return(read_preference)
166
+ expect(aggregation.send(:aggregate_spec)[:read]).to eq(read_preference)
167
+ end
168
+ end
169
+
170
+ context 'when allow_disk_use is set' do
171
+
172
+ let(:aggregation) do
173
+ described_class.new(view, pipeline, options).allow_disk_use(true)
174
+ end
175
+
176
+ it 'includes the option in the spec' do
177
+ expect(aggregation.send(:aggregate_spec)[:selector][:allowDiskUse]).to eq(true)
178
+ end
179
+ end
180
+ end
148
181
  end
@@ -150,6 +150,10 @@ describe Mongo::Collection::View::MapReduce do
150
150
  expect(document[:_id]).to eq('Berlin')
151
151
  end
152
152
  end
153
+
154
+ it 'includes the selector in the operation spec' do
155
+ expect(map_reduce.send(:map_reduce_spec)[:selector][:query]).to eq(selector)
156
+ end
153
157
  end
154
158
 
155
159
  context 'when the selector is advanced' do
@@ -163,6 +167,10 @@ describe Mongo::Collection::View::MapReduce do
163
167
  expect(document[:_id]).to eq('Berlin')
164
168
  end
165
169
  end
170
+
171
+ it 'includes the selector in the operation spec' do
172
+ expect(map_reduce.send(:map_reduce_spec)[:selector][:query]).to eq(selector[:$query])
173
+ end
166
174
  end
167
175
  end
168
176
 
@@ -197,6 +205,10 @@ describe Mongo::Collection::View::MapReduce do
197
205
  it 'sets the finalize function' do
198
206
  expect(new_map_reduce.finalize).to eq(finalize)
199
207
  end
208
+
209
+ it 'includes the finalize function in the operation spec' do
210
+ expect(new_map_reduce.send(:map_reduce_spec)[:selector][:finalize]).to eq(finalize)
211
+ end
200
212
  end
201
213
 
202
214
  describe '#js_mode' do
@@ -208,6 +220,10 @@ describe Mongo::Collection::View::MapReduce do
208
220
  it 'sets the js mode value' do
209
221
  expect(new_map_reduce.js_mode).to be true
210
222
  end
223
+
224
+ it 'includes the js mode value in the operation spec' do
225
+ expect(new_map_reduce.send(:map_reduce_spec)[:selector][:jsMode]).to be(true)
226
+ end
211
227
  end
212
228
 
213
229
  describe '#out' do
@@ -223,6 +239,17 @@ describe Mongo::Collection::View::MapReduce do
223
239
  it 'sets the out value' do
224
240
  expect(new_map_reduce.out).to eq(location)
225
241
  end
242
+
243
+ it 'includes the out value in the operation spec' do
244
+ expect(new_map_reduce.send(:map_reduce_spec)[:selector][:out]).to be(location)
245
+ end
246
+
247
+ context 'when out is not defined' do
248
+
249
+ it 'defaults to inline' do
250
+ expect(map_reduce.send(:map_reduce_spec)[:selector][:out]).to eq(inline: 1)
251
+ end
252
+ end
226
253
  end
227
254
 
228
255
  describe '#scope' do
@@ -238,5 +265,70 @@ describe Mongo::Collection::View::MapReduce do
238
265
  it 'sets the scope object' do
239
266
  expect(new_map_reduce.scope).to eq(object)
240
267
  end
268
+
269
+ it 'includes the scope object in the operation spec' do
270
+ expect(new_map_reduce.send(:map_reduce_spec)[:selector][:scope]).to be(object)
271
+ end
272
+ end
273
+
274
+ describe '#verbose' do
275
+
276
+ let(:verbose) do
277
+ false
278
+ end
279
+
280
+ let(:new_map_reduce) do
281
+ map_reduce.verbose(verbose)
282
+ end
283
+
284
+ it 'sets the verbose value' do
285
+ expect(new_map_reduce.verbose).to be(false)
286
+ end
287
+
288
+ it 'includes the verbose option in the operation spec' do
289
+ expect(new_map_reduce.send(:map_reduce_spec)[:selector][:verbose]).to eq(verbose)
290
+ end
291
+ end
292
+
293
+ context 'when limit is set on the view' do
294
+
295
+ let(:limit) do
296
+ 3
297
+ end
298
+
299
+ let(:view_options) do
300
+ { limit: limit }
301
+ end
302
+
303
+ it 'includes the limit in the operation spec' do
304
+ expect(map_reduce.send(:map_reduce_spec)[:selector][:limit]).to be(limit)
305
+ end
306
+ end
307
+
308
+ context 'when sort is set on the view' do
309
+
310
+ let(:sort) do
311
+ { name: -1 }
312
+ end
313
+
314
+ let(:view_options) do
315
+ { sort: sort }
316
+ end
317
+
318
+ it 'includes the sort object in the operation spec' do
319
+ expect(map_reduce.send(:map_reduce_spec)[:selector][:sort]).to be(sort)
320
+ end
321
+ end
322
+
323
+ context 'when the collection has a read preference' do
324
+
325
+ let(:read_preference) do
326
+ Mongo::ServerSelector.get(mode: :secondary)
327
+ end
328
+
329
+ it 'includes the read preference in the spec' do
330
+ allow(authorized_collection).to receive(:read_preference).and_return(read_preference)
331
+ expect(map_reduce.send(:map_reduce_spec)[:read]).to eq(read_preference)
332
+ end
241
333
  end
242
334
  end
@@ -334,19 +334,22 @@ describe Mongo::Collection::View do
334
334
 
335
335
  context 'when providing a hint' do
336
336
 
337
- let(:options) do
338
- { :hint => { 'x' => Mongo::Index::ASCENDING }}
339
- end
337
+ context 'when the hint is bad' do
340
338
 
341
- before do
342
- expect(Mongo::Operation::Read::Query).to receive(:new) do |spec|
343
- expect(spec[:selector][:$query]).to eq(selector)
344
- end.and_call_original
345
- end
339
+ let(:options) do
340
+ { :hint => { 'x' => Mongo::Index::ASCENDING }}
341
+ end
346
342
 
347
- it'creates a special query selector' do
348
- view.each do |doc|
349
- expect(doc).to have_key('$err')
343
+ before do
344
+ expect(Mongo::Operation::Read::Query).to receive(:new) do |spec|
345
+ expect(spec[:selector][:$query]).to eq(selector)
346
+ end.and_call_original
347
+ end
348
+
349
+ it'creates a special query selector' do
350
+ expect {
351
+ view.to_a
352
+ }.to raise_error(Mongo::Error::OperationFailure)
350
353
  end
351
354
  end
352
355
  end
@@ -262,6 +262,19 @@ describe Mongo::Collection do
262
262
  end
263
263
  end
264
264
 
265
+ context 'when providing a bad selector' do
266
+
267
+ let(:view) do
268
+ authorized_collection.find('$or' => [])
269
+ end
270
+
271
+ it 'raises an exception when iterating' do
272
+ expect {
273
+ view.to_a
274
+ }.to raise_exception(Mongo::Error::OperationFailure)
275
+ end
276
+ end
277
+
265
278
  context 'when iterating the authorized_collection view' do
266
279
 
267
280
  before do
@@ -95,6 +95,35 @@ describe Mongo::Database do
95
95
  end
96
96
  end
97
97
 
98
+ describe '#list_collections' do
99
+
100
+ let(:database) do
101
+ described_class.new(authorized_client, TEST_DB)
102
+ end
103
+
104
+ let(:result) do
105
+ database.list_collections.map do |info|
106
+ info['name']
107
+ end
108
+ end
109
+
110
+ before do
111
+ database[:users].create
112
+ end
113
+
114
+ after do
115
+ database[:users].drop
116
+ end
117
+
118
+ it 'returns a list of the collections info', if: list_command_enabled? do
119
+ expect(result).to include('users')
120
+ end
121
+
122
+ it 'returns a list of the collections info', unless: list_command_enabled? do
123
+ expect(result).to include("#{TEST_DB}.users")
124
+ end
125
+ end
126
+
98
127
  describe '#collections' do
99
128
 
100
129
  context 'when the database exists' do
@@ -65,7 +65,7 @@ describe Mongo::Grid::FS do
65
65
 
66
66
  context 'when inserting the file once' do
67
67
 
68
- before do
68
+ let!(:result) do
69
69
  fs.insert_one(file)
70
70
  end
71
71
 
@@ -85,6 +85,10 @@ describe Mongo::Grid::FS do
85
85
  it 'includes the chunks and data with the file' do
86
86
  expect(from_db.data).to eq('Hello!')
87
87
  end
88
+
89
+ it 'returns the file id' do
90
+ expect(result).to eq(file.id)
91
+ end
88
92
  end
89
93
 
90
94
  context 'when inserting the file more than once' do
@@ -101,6 +105,33 @@ describe Mongo::Grid::FS do
101
105
  }.to raise_error(Mongo::Error::OperationFailure)
102
106
  end
103
107
  end
108
+
109
+ context 'when the file exceeds the max bson size' do
110
+
111
+ let(:fs) do
112
+ described_class.new(authorized_client.database)
113
+ end
114
+
115
+ let(:file) do
116
+ str = 'y' * 16777216
117
+ Mongo::Grid::File.new(str, :filename => 'large-file.txt')
118
+ end
119
+
120
+ before do
121
+ fs.insert_one(file)
122
+ end
123
+
124
+ after do
125
+ fs.files_collection.find.delete_many
126
+ fs.chunks_collection.find.delete_many
127
+ end
128
+
129
+ it 'successfully inserts the file' do
130
+ expect(
131
+ fs.find_one(:filename => 'large-file.txt').chunks
132
+ ).to eq(file.chunks)
133
+ end
134
+ end
104
135
  end
105
136
 
106
137
  describe '#delete_one' do
@@ -23,8 +23,9 @@ describe Mongo::Loggable do
23
23
  end
24
24
 
25
25
  before do
26
+ Mongo::Logger.level = Logger::DEBUG
26
27
  expect(operation).to receive(:log_message).and_return('test')
27
- expect(Mongo::Logger).to receive(:debug).with('MONGO', 'test', anything())
28
+ expect(Mongo::Logger).to receive(:log).with(:debug, 'MONGO', 'test', anything())
28
29
  end
29
30
 
30
31
  context 'when a block is provided' do
@@ -58,6 +58,25 @@ describe Mongo::Operation::Read::Query do
58
58
  end
59
59
  end
60
60
 
61
+ describe '#message' do
62
+
63
+ let(:query_options) do
64
+ { :flags => [ :no_cursor_timeout ]}
65
+ end
66
+
67
+ let(:query) do
68
+ described_class.new(spec)
69
+ end
70
+
71
+ let(:message) do
72
+ query.send(:message, secondary_context_slave)
73
+ end
74
+
75
+ it 'does not lose flags' do
76
+ expect(message.flags).to eq([ :no_cursor_timeout, :slave_ok ])
77
+ end
78
+ end
79
+
61
80
  describe '#execute' do
62
81
 
63
82
  context 'message' do
@@ -0,0 +1,192 @@
1
+ require 'spec_helper'
2
+
3
+ describe Mongo::Operation::ReadPreferrable do
4
+
5
+ let(:selector) do
6
+ { name: 'test' }
7
+ end
8
+
9
+ let(:options) do
10
+ {}
11
+ end
12
+
13
+ let(:mongos) do
14
+ false
15
+ end
16
+
17
+ let(:slave_ok) do
18
+ false
19
+ end
20
+
21
+ let(:read_preferrable) do
22
+ Class.new do
23
+ include Mongo::Operation::ReadPreferrable
24
+ end.new.tap do |rp|
25
+ allow(rp).to receive(:read).and_return(read_pref)
26
+ allow(rp).to receive(:selector).and_return(selector)
27
+ allow(rp).to receive(:options).and_return(options)
28
+ end
29
+ end
30
+
31
+ let(:context) do
32
+ double('context').tap do |c|
33
+ allow(c).to receive(:slave_ok?).and_return(slave_ok)
34
+ allow(c).to receive(:mongos?).and_return(mongos)
35
+ end
36
+ end
37
+
38
+ shared_context 'a selector updater' do
39
+
40
+ let(:read_pref) do
41
+ Mongo::ServerSelector.get(:mode => mode)
42
+ end
43
+
44
+ let(:expected) do
45
+ { :$query => selector, :$readPreference => read_pref.to_mongos }
46
+ end
47
+
48
+ it 'returns a special selector' do
49
+ expect(read_preferrable.send(:update_selector, context)).to eq(expected)
50
+ end
51
+
52
+ context 'when the selector already has $query in it' do
53
+
54
+ let(:selector) do
55
+ { :$query => { :name => 'test' },
56
+ :$orderby => { :name => -1 } }
57
+ end
58
+
59
+ let(:expected) do
60
+ selector.merge(:$readPreference => read_pref.to_mongos)
61
+ end
62
+
63
+ it 'returns a special selector' do
64
+ expect(read_preferrable.send(:update_selector, context)).to eq(expected)
65
+ end
66
+ end
67
+ end
68
+
69
+ shared_context 'not a selector updater' do
70
+
71
+ let(:read_pref) do
72
+ Mongo::ServerSelector.get(:mode => mode)
73
+ end
74
+
75
+ it 'returns a special selector' do
76
+ expect(read_preferrable.send(:update_selector, context)).to eq(selector)
77
+ end
78
+ end
79
+
80
+ context 'when the server is a mongos' do
81
+
82
+ let(:mongos) do
83
+ true
84
+ end
85
+
86
+ context 'when the read preference mode is primary' do
87
+
88
+ let(:mode) do
89
+ :primary
90
+ end
91
+
92
+ it_behaves_like 'not a selector updater'
93
+ end
94
+
95
+ context 'when the read preference mode is primary_preferred' do
96
+
97
+ let(:mode) do
98
+ :primary_preferred
99
+ end
100
+
101
+ it_behaves_like 'a selector updater'
102
+ end
103
+
104
+ context 'when the read preference mode is secondary' do
105
+
106
+ let(:mode) do
107
+ :secondary
108
+ end
109
+
110
+ it_behaves_like 'a selector updater'
111
+ end
112
+
113
+ context 'when the read preference mode is secondary_preferred' do
114
+
115
+ let(:mode) do
116
+ :secondary_preferred
117
+ end
118
+
119
+ it_behaves_like 'not a selector updater'
120
+ end
121
+
122
+ context 'when the read preference mode is nearest' do
123
+
124
+ let(:mode) do
125
+ :nearest
126
+ end
127
+
128
+ it_behaves_like 'a selector updater'
129
+ end
130
+ end
131
+
132
+ context 'when the server is not a mongos' do
133
+
134
+ let(:mode) do
135
+ :secondary_preferred
136
+ end
137
+
138
+ it_behaves_like 'not a selector updater'
139
+ end
140
+
141
+ context 'when the server context requires the slaveOk bit to be set' do
142
+
143
+ let(:read_pref) do
144
+ Mongo::ServerSelector.get(:mode => :secondary)
145
+ end
146
+
147
+ let(:expected) do
148
+ { :flags => [ :slave_ok ] }
149
+ end
150
+
151
+ let(:slave_ok) do
152
+ true
153
+ end
154
+
155
+ it 'sets the slave_ok flag' do
156
+ expect(read_preferrable.send(:update_options, context)).to eq(expected)
157
+ end
158
+ end
159
+
160
+ context 'when the server is not a mongos' do
161
+
162
+ context 'when the read preference requires the slaveOk bit to be set' do
163
+
164
+ let(:read_pref) do
165
+ Mongo::ServerSelector.get(:mode => :secondary)
166
+ end
167
+
168
+ let(:expected) do
169
+ { :flags => [ :slave_ok ] }
170
+ end
171
+
172
+ it 'sets the slave_ok flag' do
173
+ expect(read_preferrable.send(:update_options, context)).to eq(expected)
174
+ end
175
+ end
176
+
177
+ context 'when the read preference does not require the slaveOk bit to be set' do
178
+
179
+ let(:read_pref) do
180
+ Mongo::ServerSelector.get(:mode => :primary)
181
+ end
182
+
183
+ let(:expected) do
184
+ { }
185
+ end
186
+
187
+ it 'sets the slave_ok flag' do
188
+ expect(read_preferrable.send(:update_options, context)).to eq(expected)
189
+ end
190
+ end
191
+ end
192
+ end