mongo 0.17.1 → 0.18

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.
@@ -27,8 +27,17 @@ module Mongo
27
27
  # Raised when invalid arguments are sent to Mongo Ruby methods.
28
28
  class MongoArgumentError < MongoRubyError; end
29
29
 
30
+ # Raised on failures in connection to the database server.
31
+ class ConnectionError < MongoRubyError; end
32
+
33
+ # Raised on failures in connection to the database server.
34
+ class ConnectionTimeoutError < MongoRubyError; end
35
+
30
36
  # Raised when a database operation fails.
31
37
  class OperationFailure < MongoDBError; end
38
+
39
+ # Raised when a database operation fails.
40
+ class ConnectionFailure < MongoDBError; end
32
41
 
33
42
  # Raised when a client attempts to perform an invalid operation.
34
43
  class InvalidOperation < MongoDBError; end
@@ -442,7 +442,7 @@ module GridFS
442
442
  md5_command = OrderedHash.new
443
443
  md5_command['filemd5'] = @files_id
444
444
  md5_command['root'] = @root
445
- h['md5'] = @db.db_command(md5_command)['md5']
445
+ h['md5'] = @db.command(md5_command)['md5']
446
446
  h
447
447
  end
448
448
 
@@ -19,7 +19,7 @@ module Mongo #:nodoc:
19
19
  # objects to mongo-friendly parameters.
20
20
  module Conversions
21
21
 
22
- ASCENDING = ["ascending", "asc", "1"]
22
+ ASCENDING = ["ascending", "asc", "1"]
23
23
  DESCENDING = ["descending", "desc", "-1"]
24
24
 
25
25
  # Converts the supplied +Array+ to a +Hash+ to pass to mongo as
@@ -28,17 +28,9 @@ module Mongo #:nodoc:
28
28
  #
29
29
  # Example:
30
30
  #
31
- # *DEPRECATED
32
- #
33
- # <tt>array_as_sort_parameters(["field1", "field2"])</tt> =>
34
- # <tt>{ "field1" => "1", "field2" => "1" }</tt>
35
- #
36
- # *New Syntax:
37
- #
38
31
  # <tt>array_as_sort_parameters([["field1", :asc], ["field2", :desc]])</tt> =>
39
32
  # <tt>{ "field1" => 1, "field2" => -1}</tt>
40
33
  def array_as_sort_parameters(value)
41
- warn_if_deprecated(value)
42
34
  order_by = OrderedHash.new
43
35
  value.each do |param|
44
36
  if (param.class.name == "String")
@@ -50,7 +42,7 @@ module Mongo #:nodoc:
50
42
  order_by
51
43
  end
52
44
 
53
- # Converts the supplied +String+ to a +Hash+ to pass to mongo as
45
+ # Converts the supplied +String+ or +Symbol+ to a +Hash+ to pass to mongo as
54
46
  # a sorting parameter with ascending order. If the +String+
55
47
  # is empty then an empty +Hash+ will be returned.
56
48
  #
@@ -61,22 +53,8 @@ module Mongo #:nodoc:
61
53
  # <tt>string_as_sort_parameters("field")</tt> => <tt>{ "field" => 1 }</tt>
62
54
  # <tt>string_as_sort_parameters("")</tt> => <tt>{}</tt>
63
55
  def string_as_sort_parameters(value)
64
- warn_if_deprecated(value)
65
- return {} if value.empty?
66
- { value => 1 }
67
- end
68
-
69
- # Converts the supplied +Symbol+ to a +Hash+ to pass to mongo as
70
- # a sorting parameter with ascending order.
71
- #
72
- # Example:
73
- #
74
- # *DEPRECATED
75
- #
76
- # <tt>symbol_as_sort_parameters(:field)</tt> => <tt>{ "field" => 1 }</tt>
77
- def symbol_as_sort_parameters(value)
78
- warn_if_deprecated(value)
79
- { value.to_s => 1 }
56
+ return {} if (str = value.to_s).empty?
57
+ { str => 1 }
80
58
  end
81
59
 
82
60
  # Converts the +String+, +Symbol+, or +Integer+ to the
@@ -96,15 +74,5 @@ module Mongo #:nodoc:
96
74
  "#{self} was supplied as a sort direction when acceptable values are: " +
97
75
  "Mongo::ASCENDING, 'ascending', 'asc', :ascending, :asc, 1, Mongo::DESCENDING, 'descending', 'desc', :descending, :desc, -1.")
98
76
  end
99
-
100
- # This is the method to call when the client needs to be warned of
101
- # deprecation in the way sorting parameters are supplied.
102
- def warn_if_deprecated(value)
103
- unless value.is_a?(Array) && value.first.is_a?(Array)
104
- warn("Specifying sort order as #{value.inspect} has been deprecated in favor of a new syntax: \n" +
105
- " :sort => [['field1', '(ascending|descending)'], ['field2', '(ascending|descending)']]")
106
- end
107
- end
108
-
109
77
  end
110
78
  end
@@ -0,0 +1,34 @@
1
+ $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ require 'mongo'
3
+ require 'test/unit'
4
+ require 'test/test_helper'
5
+
6
+ # NOTE: this test should be run only if a replica pair is running.
7
+ class ReplicaPairCountTest < Test::Unit::TestCase
8
+ include Mongo
9
+
10
+ def setup
11
+ @conn = Mongo::Connection.new({:left => ["localhost", 27017], :right => ["localhost", 27018]}, nil)
12
+ @db = @conn.db('mongo-ruby-test')
13
+ @db.drop_collection("test-pairs")
14
+ @coll = @db.collection("test-pairs")
15
+ end
16
+
17
+ def test_correct_count_after_insertion_reconnect
18
+ @coll.insert({:a => 20}, :safe => true)
19
+ assert_equal 1, @coll.count
20
+
21
+ # Sleep to allow resync
22
+ sleep(3)
23
+
24
+ puts "Please disconnect the current master."
25
+ gets
26
+
27
+ rescue_connection_failure do
28
+ @coll.insert({:a => 30}, :safe => true)
29
+ end
30
+ @coll.insert({:a => 40}, :safe => true)
31
+ assert_equal 3, @coll.count, "Second count failed"
32
+ end
33
+
34
+ end
@@ -0,0 +1,50 @@
1
+ $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ require 'mongo'
3
+ require 'test/unit'
4
+ require 'test/test_helper'
5
+
6
+ # NOTE: this test should be run only if a replica pair is running.
7
+ class ReplicaPairInsertTest < Test::Unit::TestCase
8
+ include Mongo
9
+
10
+ def setup
11
+ @conn = Mongo::Connection.new({:left => ["localhost", 27017], :right => ["localhost", 27018]}, nil)
12
+ @db = @conn.db('mongo-ruby-test')
13
+ @db.drop_collection("test-pairs")
14
+ @coll = @db.collection("test-pairs")
15
+ end
16
+
17
+ def test_insert
18
+ @coll.save({:a => 20}, :safe => true)
19
+ puts "Please disconnect the current master."
20
+ gets
21
+
22
+ rescue_connection_failure do
23
+ @coll.save({:a => 30}, :safe => true)
24
+ end
25
+
26
+ @coll.save({:a => 40}, :safe => true)
27
+ @coll.save({:a => 50}, :safe => true)
28
+ @coll.save({:a => 60}, :safe => true)
29
+ @coll.save({:a => 70}, :safe => true)
30
+
31
+ puts "Please reconnect the old master to make sure that the new master " +
32
+ "has synced with the previous master. Note: this may have happened already."
33
+ gets
34
+ results = []
35
+
36
+ rescue_connection_failure do
37
+ @coll.find.each {|r| results << r}
38
+ [20, 30, 40, 50, 60, 70].each do |a|
39
+ assert results.any? {|r| r['a'] == a}, "Could not find record for a => #{a}"
40
+ end
41
+ end
42
+
43
+ @coll.save({:a => 80}, :safe => true)
44
+ @coll.find.each {|r| results << r}
45
+ [20, 30, 40, 50, 60, 70, 80].each do |a|
46
+ assert results.any? {|r| r['a'] == a}, "Could not find record for a => #{a} on second find"
47
+ end
48
+ end
49
+
50
+ end
@@ -0,0 +1,54 @@
1
+ $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ require 'mongo'
3
+ require 'test/unit'
4
+ require 'test/test_helper'
5
+
6
+ # NOTE: this test should be run only if a replica pair is running.
7
+ class ReplicaPairPooledInsertTest < Test::Unit::TestCase
8
+ include Mongo
9
+
10
+ def setup
11
+ @conn = Mongo::Connection.new({:left => ["localhost", 27017], :right => ["localhost", 27018]}, nil, :pool_size => 10, :timeout => 5)
12
+ @db = @conn.db('mongo-ruby-test')
13
+ @db.drop_collection("test-pairs")
14
+ @coll = @db.collection("test-pairs")
15
+ end
16
+
17
+ def test_insert
18
+ expected_results = [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
19
+ @coll.save({:a => -1}, :safe => true)
20
+ puts "Please disconnect the current master."
21
+ gets
22
+
23
+ threads = []
24
+ 10.times do |i|
25
+ threads[i] = Thread.new do
26
+ rescue_connection_failure do
27
+ @coll.save({:a => i}, :safe => true)
28
+ end
29
+ end
30
+ end
31
+
32
+ puts "Please reconnect the old master to make sure that the new master " +
33
+ "has synced with the previous master. Note: this may have happened already." +
34
+ "Note also that when connection with multiple threads, you may need to wait a few seconds" +
35
+ "after restarting the old master so that all the data has had a chance to sync." +
36
+ "This is a case of eventual consistency."
37
+ gets
38
+ results = []
39
+
40
+ rescue_connection_failure do
41
+ @coll.find.each {|r| results << r}
42
+ expected_results.each do |a|
43
+ assert results.any? {|r| r['a'] == a}, "Could not find record for a => #{a}"
44
+ end
45
+ end
46
+
47
+ @coll.save({:a => 10}, :safe => true)
48
+ @coll.find.each {|r| results << r}
49
+ (expected_results + [10]).each do |a|
50
+ assert results.any? {|r| r['a'] == a}, "Could not find record for a => #{a} on second find"
51
+ end
52
+ end
53
+
54
+ end
@@ -0,0 +1,39 @@
1
+ $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ require 'mongo'
3
+ require 'test/unit'
4
+ require 'test/test_helper'
5
+
6
+ # NOTE: this test should be run only if a replica pair is running.
7
+ class ReplicaPairQueryTest < Test::Unit::TestCase
8
+ include Mongo
9
+
10
+ def setup
11
+ @conn = Mongo::Connection.new({:left => ["localhost", 27017], :right => ["localhost", 27018]}, nil)
12
+ @db = @conn.db('mongo-ruby-test')
13
+ @db.drop_collection("test-pairs")
14
+ @coll = @db.collection("test-pairs")
15
+ end
16
+
17
+ def test_query
18
+ @coll.save({:a => 20})
19
+ @coll.save({:a => 30})
20
+ @coll.save({:a => 40})
21
+ results = []
22
+ @coll.find.each {|r| results << r}
23
+ [20, 30, 40].each do |a|
24
+ assert results.any? {|r| r['a'] == a}, "Could not find record for a => #{a}"
25
+ end
26
+
27
+ puts "Please disconnect the current master."
28
+ gets
29
+
30
+ results = []
31
+ rescue_connection_failure do
32
+ @coll.find.each {|r| results << r}
33
+ [20, 30, 40].each do |a|
34
+ assert results.any? {|r| r['a'] == a}, "Could not find record for a => #{a}"
35
+ end
36
+ end
37
+ end
38
+
39
+ end
@@ -144,7 +144,7 @@ class TestCollection < Test::Unit::TestCase
144
144
 
145
145
  # Can't duplicate an index.
146
146
  assert_raise OperationFailure do
147
- @@test.update({}, {"x" => 10}, :safe => true, :upsert => true)
147
+ @@test.update({}, {"x" => 10}, :safe => true)
148
148
  end
149
149
  end
150
150
  end
@@ -154,7 +154,6 @@ class TestCollection < Test::Unit::TestCase
154
154
 
155
155
  @@test.save("hello" => "world")
156
156
  @@test.save("hello" => "world")
157
- assert(@@db.error.include?("E11000"))
158
157
 
159
158
  assert_raise OperationFailure do
160
159
  @@test.save({"hello" => "world"}, :safe => true)
@@ -266,6 +265,28 @@ class TestCollection < Test::Unit::TestCase
266
265
  assert c.closed?
267
266
  end
268
267
 
268
+ def test_mapreduce
269
+ @@test << { "user_id" => 1 }
270
+ @@test << { "user_id" => 2 }
271
+
272
+ m = "function() { emit(this.user_id, 1); }"
273
+ r = "function(k,vals) { return 1; }"
274
+ res = @@test.map_reduce(m, r);
275
+ assert res.find_one({"_id" => 1})
276
+ assert res.find_one({"_id" => 2})
277
+ end
278
+
279
+ def test_mapreduce_with_code_objects
280
+ @@test << { "user_id" => 1 }
281
+ @@test << { "user_id" => 2 }
282
+
283
+ m = Code.new("function() { emit(this.user_id, 1); }")
284
+ r = Code.new("function(k,vals) { return 1; }")
285
+ res = @@test.map_reduce(m, r);
286
+ assert res.find_one({"_id" => 1})
287
+ assert res.find_one({"_id" => 2})
288
+ end
289
+
269
290
  def test_saving_dates_pre_epoch
270
291
  begin
271
292
  @@test.save({'date' => Time.utc(1600)})
@@ -291,9 +312,6 @@ class TestCollection < Test::Unit::TestCase
291
312
  @@test.save(:foo => i)
292
313
  end
293
314
 
294
- # TODO remove test for deprecated :offset option
295
- assert_equal 5, @@test.find({}, :offset => 5).next_object()["foo"]
296
-
297
315
  assert_equal 5, @@test.find({}, :skip => 5).next_object()["foo"]
298
316
  assert_equal nil, @@test.find({}, :skip => 10).next_object()
299
317
 
@@ -388,11 +406,6 @@ class TestCollection < Test::Unit::TestCase
388
406
  assert_equal 0, @collection.find.count
389
407
  end
390
408
 
391
- should "remove all records if deprecated clear is used" do
392
- @collection.clear
393
- assert_equal 0, @collection.find.count
394
- end
395
-
396
409
  should "remove only matching records" do
397
410
  @collection.remove({:name => "Jones"})
398
411
  assert_equal 1, @collection.size
@@ -79,8 +79,7 @@ class TestConnection < Test::Unit::TestCase
79
79
  logger = Logger.new(output)
80
80
  logger.level = Logger::DEBUG
81
81
  db = Connection.new(@host, @port, :logger => logger).db('ruby-mongo-test')
82
-
83
- assert output.string.include?("$cmd.find")
82
+ assert output.string.include?("admin.$cmd.find")
84
83
  end
85
84
 
86
85
  def test_connection_logger
@@ -106,23 +105,23 @@ class TestConnection < Test::Unit::TestCase
106
105
  assert !@mongo.database_names.include?('ruby-mongo-will-be-deleted')
107
106
  end
108
107
 
109
- def test_pair
110
- db = Connection.new({:left => ['foo', 123]})
111
- pair = db.instance_variable_get('@pair')
112
- assert_equal 2, pair.length
113
- assert_equal ['foo', 123], pair[0]
114
- assert_equal ['localhost', Connection::DEFAULT_PORT], pair[1]
115
-
116
- db = Connection.new({:right => 'bar'})
117
- pair = db.instance_variable_get('@pair')
118
- assert_equal 2, pair.length
119
- assert_equal ['localhost', Connection::DEFAULT_PORT], pair[0]
120
- assert_equal ['bar', Connection::DEFAULT_PORT], pair[1]
121
-
122
- db = Connection.new({:right => ['foo', 123], :left => 'bar'})
123
- pair = db.instance_variable_get('@pair')
124
- assert_equal 2, pair.length
125
- assert_equal ['bar', Connection::DEFAULT_PORT], pair[0]
126
- assert_equal ['foo', 123], pair[1]
108
+ def test_nodes
109
+ db = Connection.new({:left => ['foo', 123]}, nil, :connect => false)
110
+ nodes = db.nodes
111
+ assert_equal 2, db.nodes.length
112
+ assert_equal ['foo', 123], nodes[0]
113
+ assert_equal ['localhost', Connection::DEFAULT_PORT], nodes[1]
114
+
115
+ db = Connection.new({:right => 'bar'}, nil, :connect => false)
116
+ nodes = db.nodes
117
+ assert_equal 2, nodes.length
118
+ assert_equal ['localhost', Connection::DEFAULT_PORT], nodes[0]
119
+ assert_equal ['bar', Connection::DEFAULT_PORT], nodes[1]
120
+
121
+ db = Connection.new({:right => ['foo', 123], :left => 'bar'}, nil, :connect => false)
122
+ nodes = db.nodes
123
+ assert_equal 2, nodes.length
124
+ assert_equal ['bar', Connection::DEFAULT_PORT], nodes[0]
125
+ assert_equal ['foo', 123], nodes[1]
127
126
  end
128
127
  end
@@ -28,7 +28,7 @@ class ConversionsTest < Test::Unit::TestCase
28
28
  end
29
29
 
30
30
  def test_symbol_as_sort_parameters
31
- params = symbol_as_sort_parameters(:field)
31
+ params = string_as_sort_parameters(:field)
32
32
  assert_equal({ "field" => 1 }, params)
33
33
  end
34
34
 
@@ -118,4 +118,4 @@ class ConversionsTest < Test::Unit::TestCase
118
118
  end
119
119
  end
120
120
 
121
- end
121
+ end
@@ -246,26 +246,26 @@ class CursorTest < Test::Unit::TestCase
246
246
  def test_kill_cursors
247
247
  @@coll.drop
248
248
 
249
- client_cursors = @@db.db_command("cursorInfo" => 1)["clientCursors_size"]
250
- by_location = @@db.db_command("cursorInfo" => 1)["byLocation_size"]
249
+ client_cursors = @@db.command("cursorInfo" => 1)["clientCursors_size"]
250
+ by_location = @@db.command("cursorInfo" => 1)["byLocation_size"]
251
251
 
252
252
  10000.times do |i|
253
253
  @@coll.insert("i" => i)
254
254
  end
255
255
 
256
256
  assert_equal(client_cursors,
257
- @@db.db_command("cursorInfo" => 1)["clientCursors_size"])
257
+ @@db.command("cursorInfo" => 1)["clientCursors_size"])
258
258
  assert_equal(by_location,
259
- @@db.db_command("cursorInfo" => 1)["byLocation_size"])
259
+ @@db.command("cursorInfo" => 1)["byLocation_size"])
260
260
 
261
261
  10.times do |i|
262
262
  @@coll.find_one()
263
263
  end
264
264
 
265
265
  assert_equal(client_cursors,
266
- @@db.db_command("cursorInfo" => 1)["clientCursors_size"])
266
+ @@db.command("cursorInfo" => 1)["clientCursors_size"])
267
267
  assert_equal(by_location,
268
- @@db.db_command("cursorInfo" => 1)["byLocation_size"])
268
+ @@db.command("cursorInfo" => 1)["byLocation_size"])
269
269
 
270
270
  10.times do |i|
271
271
  a = @@coll.find()
@@ -274,49 +274,49 @@ class CursorTest < Test::Unit::TestCase
274
274
  end
275
275
 
276
276
  assert_equal(client_cursors,
277
- @@db.db_command("cursorInfo" => 1)["clientCursors_size"])
277
+ @@db.command("cursorInfo" => 1)["clientCursors_size"])
278
278
  assert_equal(by_location,
279
- @@db.db_command("cursorInfo" => 1)["byLocation_size"])
279
+ @@db.command("cursorInfo" => 1)["byLocation_size"])
280
280
 
281
281
  a = @@coll.find()
282
282
  a.next_object()
283
283
 
284
284
  assert_not_equal(client_cursors,
285
- @@db.db_command("cursorInfo" => 1)["clientCursors_size"])
285
+ @@db.command("cursorInfo" => 1)["clientCursors_size"])
286
286
  assert_not_equal(by_location,
287
- @@db.db_command("cursorInfo" => 1)["byLocation_size"])
287
+ @@db.command("cursorInfo" => 1)["byLocation_size"])
288
288
 
289
289
  a.close()
290
290
 
291
291
  assert_equal(client_cursors,
292
- @@db.db_command("cursorInfo" => 1)["clientCursors_size"])
292
+ @@db.command("cursorInfo" => 1)["clientCursors_size"])
293
293
  assert_equal(by_location,
294
- @@db.db_command("cursorInfo" => 1)["byLocation_size"])
294
+ @@db.command("cursorInfo" => 1)["byLocation_size"])
295
295
 
296
296
  a = @@coll.find({}, :limit => 10).next_object()
297
297
 
298
298
  assert_equal(client_cursors,
299
- @@db.db_command("cursorInfo" => 1)["clientCursors_size"])
299
+ @@db.command("cursorInfo" => 1)["clientCursors_size"])
300
300
  assert_equal(by_location,
301
- @@db.db_command("cursorInfo" => 1)["byLocation_size"])
301
+ @@db.command("cursorInfo" => 1)["byLocation_size"])
302
302
 
303
303
  @@coll.find() do |cursor|
304
304
  cursor.next_object()
305
305
  end
306
306
 
307
307
  assert_equal(client_cursors,
308
- @@db.db_command("cursorInfo" => 1)["clientCursors_size"])
308
+ @@db.command("cursorInfo" => 1)["clientCursors_size"])
309
309
  assert_equal(by_location,
310
- @@db.db_command("cursorInfo" => 1)["byLocation_size"])
310
+ @@db.command("cursorInfo" => 1)["byLocation_size"])
311
311
 
312
312
  @@coll.find() { |cursor|
313
313
  cursor.next_object()
314
314
  }
315
315
 
316
316
  assert_equal(client_cursors,
317
- @@db.db_command("cursorInfo" => 1)["clientCursors_size"])
317
+ @@db.command("cursorInfo" => 1)["clientCursors_size"])
318
318
  assert_equal(by_location,
319
- @@db.db_command("cursorInfo" => 1)["byLocation_size"])
319
+ @@db.command("cursorInfo" => 1)["byLocation_size"])
320
320
  end
321
321
 
322
322
  def test_count_with_fields