mongo 2.0.4 → 2.0.5

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.
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