mongo 0.18.3 → 0.19

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 (62) hide show
  1. data/README.rdoc +41 -50
  2. data/Rakefile +14 -4
  3. data/examples/gridfs.rb +25 -70
  4. data/lib/mongo.rb +4 -2
  5. data/lib/mongo/collection.rb +70 -89
  6. data/lib/mongo/connection.rb +203 -43
  7. data/lib/mongo/cursor.rb +7 -7
  8. data/lib/mongo/db.rb +61 -18
  9. data/lib/mongo/exceptions.rb +7 -1
  10. data/lib/mongo/gridfs.rb +8 -1
  11. data/lib/mongo/gridfs/chunk.rb +2 -1
  12. data/lib/mongo/gridfs/grid.rb +90 -0
  13. data/lib/mongo/gridfs/grid_file_system.rb +113 -0
  14. data/lib/mongo/gridfs/grid_io.rb +339 -0
  15. data/lib/mongo/gridfs/grid_store.rb +43 -18
  16. data/lib/mongo/types/binary.rb +5 -1
  17. data/lib/mongo/types/code.rb +1 -1
  18. data/lib/mongo/types/dbref.rb +3 -1
  19. data/lib/mongo/types/min_max_keys.rb +1 -1
  20. data/lib/mongo/types/objectid.rb +16 -55
  21. data/lib/mongo/types/regexp_of_holding.rb +1 -1
  22. data/lib/mongo/util/bson_c.rb +2 -2
  23. data/lib/mongo/util/bson_ruby.rb +22 -11
  24. data/lib/mongo/util/byte_buffer.rb +1 -1
  25. data/lib/mongo/util/conversions.rb +1 -1
  26. data/lib/mongo/util/ordered_hash.rb +6 -1
  27. data/lib/mongo/util/server_version.rb +1 -1
  28. data/lib/mongo/util/support.rb +1 -1
  29. data/mongo-ruby-driver.gemspec +1 -1
  30. data/test/auxillary/authentication_test.rb +68 -0
  31. data/test/auxillary/autoreconnect_test.rb +41 -0
  32. data/test/binary_test.rb +15 -0
  33. data/test/{test_bson.rb → bson_test.rb} +63 -6
  34. data/test/{test_byte_buffer.rb → byte_buffer_test.rb} +0 -0
  35. data/test/{test_chunk.rb → chunk_test.rb} +0 -0
  36. data/test/{test_collection.rb → collection_test.rb} +35 -39
  37. data/test/{test_connection.rb → connection_test.rb} +33 -3
  38. data/test/{test_conversions.rb → conversions_test.rb} +0 -0
  39. data/test/{test_cursor.rb → cursor_test.rb} +0 -7
  40. data/test/{test_db_api.rb → db_api_test.rb} +3 -6
  41. data/test/{test_db_connection.rb → db_connection_test.rb} +0 -0
  42. data/test/{test_db.rb → db_test.rb} +33 -15
  43. data/test/grid_file_system_test.rb +210 -0
  44. data/test/grid_io_test.rb +78 -0
  45. data/test/{test_grid_store.rb → grid_store_test.rb} +33 -2
  46. data/test/grid_test.rb +87 -0
  47. data/test/{test_objectid.rb → objectid_test.rb} +2 -33
  48. data/test/{test_ordered_hash.rb → ordered_hash_test.rb} +4 -0
  49. data/test/{test_slave_connection.rb → slave_connection_test.rb} +0 -0
  50. data/test/test_helper.rb +2 -2
  51. data/test/{test_threading.rb → threading_test.rb} +0 -0
  52. data/test/unit/collection_test.rb +12 -3
  53. data/test/unit/connection_test.rb +85 -24
  54. data/test/unit/cursor_test.rb +1 -2
  55. data/test/unit/db_test.rb +70 -69
  56. metadata +27 -23
  57. data/bin/objectid_benchmark.rb +0 -23
  58. data/bin/perf.rb +0 -30
  59. data/lib/mongo/admin.rb +0 -95
  60. data/lib/mongo/util/xml_to_ruby.rb +0 -112
  61. data/test/test_admin.rb +0 -67
  62. data/test/test_round_trip.rb +0 -114
@@ -1,5 +1,5 @@
1
1
  # --
2
- # Copyright (C) 2008-2009 10gen Inc.
2
+ # Copyright (C) 2008-2010 10gen Inc.
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License");
5
5
  # you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  # --
2
- # Copyright (C) 2008-2009 10gen Inc.
2
+ # Copyright (C) 2008-2010 10gen Inc.
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License");
5
5
  # you may not use this file except in compliance with the License.
@@ -22,7 +22,7 @@ Gem::Specification.new do |s|
22
22
  s.rdoc_options = ['--main', 'README.rdoc', '--inline-source']
23
23
  s.extra_rdoc_files = ['README.rdoc']
24
24
 
25
- s.authors = ['Jim Menard', 'Mike Dirolf']
25
+ s.authors = ['Jim Menard', 'Mike Dirolf', 'Kyle Banker']
26
26
  s.email = 'mongodb-dev@googlegroups.com'
27
27
  s.homepage = 'http://www.mongodb.org'
28
28
  end
@@ -0,0 +1,68 @@
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 requires bouncing the server.
7
+ # It also requires that a user exists on the admin database.
8
+ class AuthenticationTest < Test::Unit::TestCase
9
+ include Mongo
10
+
11
+ def setup
12
+ @conn = Mongo::Connection.new
13
+ @db1 = @conn.db('mongo-ruby-test-auth1')
14
+ @db2 = @conn.db('mongo-ruby-test-auth2')
15
+ @admin = @conn.db('admin')
16
+ end
17
+
18
+ def teardown
19
+ @db1.authenticate('user1', 'secret')
20
+ @db2.authenticate('user2', 'secret')
21
+ @conn.drop_database('mongo-ruby-test-auth1')
22
+ @conn.drop_database('mongo-ruby-test-auth2')
23
+ end
24
+
25
+ def test_authenticate
26
+ @admin.authenticate('bob', 'secret')
27
+ @db1.add_user('user1', 'secret')
28
+ @db2.add_user('user2', 'secret')
29
+ @admin.logout
30
+
31
+ assert_raise Mongo::OperationFailure do
32
+ @db1['stuff'].insert({:a => 2}, :safe => true)
33
+ end
34
+
35
+ assert_raise Mongo::OperationFailure do
36
+ @db2['stuff'].insert({:a => 2}, :safe => true)
37
+ end
38
+
39
+ @db1.authenticate('user1', 'secret')
40
+ @db2.authenticate('user2', 'secret')
41
+
42
+ assert @db1['stuff'].insert({:a => 2}, :safe => true)
43
+ assert @db2['stuff'].insert({:a => 2}, :safe => true)
44
+
45
+ puts "Please bounce the server."
46
+ gets
47
+
48
+ # Here we reconnect.
49
+ begin
50
+ @db1['stuff'].find.to_a
51
+ rescue Mongo::ConnectionFailure
52
+ end
53
+
54
+ assert @db1['stuff'].insert({:a => 2}, :safe => true)
55
+ assert @db2['stuff'].insert({:a => 2}, :safe => true)
56
+
57
+ @db1.logout
58
+ assert_raise Mongo::OperationFailure do
59
+ @db1['stuff'].insert({:a => 2}, :safe => true)
60
+ end
61
+
62
+ @db2.logout
63
+ assert_raise Mongo::OperationFailure do
64
+ assert @db2['stuff'].insert({:a => 2}, :safe => true)
65
+ end
66
+ end
67
+
68
+ end
@@ -0,0 +1,41 @@
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 requires bouncing the server
7
+ class AutoreconnectTest < Test::Unit::TestCase
8
+ include Mongo
9
+
10
+ def setup
11
+ @conn = Mongo::Connection.new
12
+ @db = @conn.db('mongo-ruby-test')
13
+ @db.drop_collection("test-connect")
14
+ @coll = @db.collection("test-connect")
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 and then reconnect the current master."
28
+ gets
29
+
30
+ begin
31
+ @coll.find.to_a
32
+ rescue Mongo::ConnectionFailure
33
+ end
34
+
35
+ results = []
36
+ @coll.find.each {|r| results << r}
37
+ [20, 30, 40].each do |a|
38
+ assert results.any? {|r| r['a'] == a}, "Could not find record for a => #{a}"
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,15 @@
1
+ # encoding:utf-8
2
+ require 'test/test_helper'
3
+
4
+ class BinaryTest < Test::Unit::TestCase
5
+ context "Inspecting" do
6
+ setup do
7
+ @data = ("THIS IS BINARY " * 50).unpack("c*")
8
+ end
9
+
10
+ should "not display actual data" do
11
+ binary = Mongo::Binary.new(@data)
12
+ assert_equal "<Mongo::Binary:#{binary.object_id}>", binary.inspect
13
+ end
14
+ end
15
+ end
@@ -138,10 +138,9 @@ class BSONTest < Test::Unit::TestCase
138
138
  assert_equal doc, doc2
139
139
 
140
140
  r = doc2['doc']
141
- assert_kind_of RegexpOfHolding, r
142
- assert_equal '', r.extra_options_str
141
+ assert_kind_of Regexp, r
143
142
 
144
- r.extra_options_str << 'zywcab'
143
+ r = RegexpOfHolding.new('st', 0, 'zywcab')
145
144
  assert_equal 'zywcab', r.extra_options_str
146
145
 
147
146
  doc = {'doc' => r}
@@ -263,19 +262,19 @@ class BSONTest < Test::Unit::TestCase
263
262
  val = OrderedHash.new
264
263
  val['not_id'] = 1
265
264
  val['_id'] = 2
266
- roundtrip = BSON.deserialize(BSON.serialize(val).to_a)
265
+ roundtrip = BSON.deserialize(BSON.serialize(val, false, true).to_a)
267
266
  assert_kind_of OrderedHash, roundtrip
268
267
  assert_equal '_id', roundtrip.keys.first
269
268
 
270
269
  val = {'a' => 'foo', 'b' => 'bar', :_id => 42, 'z' => 'hello'}
271
- roundtrip = BSON.deserialize(BSON.serialize(val).to_a)
270
+ roundtrip = BSON.deserialize(BSON.serialize(val, false, true).to_a)
272
271
  assert_kind_of OrderedHash, roundtrip
273
272
  assert_equal '_id', roundtrip.keys.first
274
273
  end
275
274
 
276
275
  def test_nil_id
277
276
  doc = {"_id" => nil}
278
- assert_equal doc, BSON.deserialize(bson = BSON.serialize(doc).to_a)
277
+ assert_equal doc, BSON.deserialize(bson = BSON.serialize(doc, false, true).to_a)
279
278
  end
280
279
 
281
280
  def test_timestamp
@@ -357,6 +356,13 @@ class BSONTest < Test::Unit::TestCase
357
356
  assert_equal BSON.serialize(one).to_a, BSON.serialize(dup).to_a
358
357
  end
359
358
 
359
+ def test_no_duplicate_id_when_moving_id
360
+ dup = {"_id" => "foo", :_id => "foo"}
361
+ one = {:_id => "foo"}
362
+
363
+ assert_equal BSON.serialize(one, false, true).to_s, BSON.serialize(dup, false, true).to_s
364
+ end
365
+
360
366
  def test_null_character
361
367
  doc = {"a" => "\x00"}
362
368
 
@@ -394,4 +400,55 @@ class BSONTest < Test::Unit::TestCase
394
400
  end
395
401
  end
396
402
 
403
+ def test_move_id
404
+ a = OrderedHash.new
405
+ a['text'] = 'abc'
406
+ a['key'] = 'abc'
407
+ a['_id'] = 1
408
+
409
+
410
+ assert_equal ")\000\000\000\020_id\000\001\000\000\000\002text" +
411
+ "\000\004\000\000\000abc\000\002key\000\004\000\000\000abc\000\000",
412
+ BSON.serialize(a, false, true).to_s
413
+ assert_equal ")\000\000\000\002text\000\004\000\000\000abc\000\002key" +
414
+ "\000\004\000\000\000abc\000\020_id\000\001\000\000\000\000",
415
+ BSON.serialize(a, false, false).to_s
416
+ end
417
+
418
+ def test_move_id_with_nested_doc
419
+ b = OrderedHash.new
420
+ b['text'] = 'abc'
421
+ b['_id'] = 2
422
+ c = OrderedHash.new
423
+ c['text'] = 'abc'
424
+ c['hash'] = b
425
+ c['_id'] = 3
426
+ assert_equal ">\000\000\000\020_id\000\003\000\000\000\002text" +
427
+ "\000\004\000\000\000abc\000\003hash\000\034\000\000" +
428
+ "\000\002text\000\004\000\000\000abc\000\020_id\000\002\000\000\000\000\000",
429
+ BSON.serialize(c, false, true).to_s
430
+ assert_equal ">\000\000\000\002text\000\004\000\000\000abc\000\003hash" +
431
+ "\000\034\000\000\000\002text\000\004\000\000\000abc\000\020_id" +
432
+ "\000\002\000\000\000\000\020_id\000\003\000\000\000\000",
433
+ BSON.serialize(c, false, false).to_s
434
+ end
435
+
436
+ begin
437
+ require 'active_support'
438
+ rescue LoadError
439
+ warn 'Could not test BSON with HashWithIndifferentAccess.'
440
+ end
441
+
442
+ if defined?(HashWithIndifferentAccess)
443
+ def test_keep_id_with_hash_with_indifferent_access
444
+ doc = HashWithIndifferentAccess.new
445
+ doc[:_id] = ObjectID.new
446
+ BSON.serialize(doc, false, false).to_a
447
+ assert doc.has_key?("_id")
448
+
449
+ doc['_id'] = ObjectID.new
450
+ BSON.serialize(doc, false, false).to_a
451
+ assert doc.has_key?("_id")
452
+ end
453
+ end
397
454
  end
File without changes
File without changes
@@ -1,7 +1,7 @@
1
1
  require 'test/test_helper'
2
2
 
3
3
  class TestCollection < Test::Unit::TestCase
4
- @@connection = Connection.new(ENV['MONGO_RUBY_DRIVER_HOST'] || 'localhost', ENV['MONGO_RUBY_DRIVER_PORT'] || Connection::DEFAULT_PORT)
4
+ @@connection ||= Connection.new(ENV['MONGO_RUBY_DRIVER_HOST'] || 'localhost', ENV['MONGO_RUBY_DRIVER_PORT'] || Connection::DEFAULT_PORT)
5
5
  @@db = @@connection.db('ruby-mongo-test')
6
6
  @@test = @@db.collection("test")
7
7
  @@version = @@connection.server_version
@@ -75,32 +75,31 @@ class TestCollection < Test::Unit::TestCase
75
75
  end
76
76
 
77
77
  if @@version > "1.1"
78
- context "distinct queries" do
79
- setup do
80
- @@test.remove
81
- @@test.insert([{:a => 0, :b => {:c => "a"}},
82
- {:a => 1, :b => {:c => "b"}},
83
- {:a => 1, :b => {:c => "c"}},
84
- {:a => 2, :b => {:c => "a"}},
85
- {:a => 3},
86
- {:a => 3}])
87
- end
88
-
89
- should "return distinct values" do
90
- assert_equal [0, 1, 2, 3], @@test.distinct(:a).sort
91
- assert_equal ["a", "b", "c"], @@test.distinct("b.c").sort
92
- end
93
-
94
- if @@version >= "1.2"
78
+ def setup_for_distinct
79
+ @@test.remove
80
+ @@test.insert([{:a => 0, :b => {:c => "a"}},
81
+ {:a => 1, :b => {:c => "b"}},
82
+ {:a => 1, :b => {:c => "c"}},
83
+ {:a => 2, :b => {:c => "a"}},
84
+ {:a => 3},
85
+ {:a => 3}])
86
+ end
95
87
 
96
- should "filter collection with query" do
97
- assert_equal [2, 3], @@test.distinct(:a, {:a => {"$gt" => 1}}).sort
98
- end
88
+ def test_distinct_queries
89
+ setup_for_distinct
90
+ assert_equal [0, 1, 2, 3], @@test.distinct(:a).sort
91
+ assert_equal ["a", "b", "c"], @@test.distinct("b.c").sort
92
+ end
99
93
 
100
- should "filter nested objects" do
101
- assert_equal ["a", "b"], @@test.distinct("b.c", {"b.c" => {"$ne" => "c"}}).sort
102
- end
94
+ if @@version >= "1.2"
95
+ def test_filter_collection_with_query
96
+ setup_for_distinct
97
+ assert_equal [2, 3], @@test.distinct(:a, {:a => {"$gt" => 1}}).sort
98
+ end
103
99
 
100
+ def test_filter_nested_objects
101
+ setup_for_distinct
102
+ assert_equal ["a", "b"], @@test.distinct("b.c", {"b.c" => {"$ne" => "c"}}).sort
104
103
  end
105
104
  end
106
105
  end
@@ -191,7 +190,7 @@ class TestCollection < Test::Unit::TestCase
191
190
  end
192
191
  end
193
192
 
194
- def test_safe_remove
193
+ def test_mocked_safe_remove
195
194
  @conn = Connection.new
196
195
  @db = @conn['mongo-ruby-test']
197
196
  @test = @db['test-safe-remove']
@@ -204,6 +203,15 @@ class TestCollection < Test::Unit::TestCase
204
203
  @test.drop
205
204
  end
206
205
 
206
+ def test_safe_remove
207
+ @conn = Connection.new
208
+ @db = @conn['mongo-ruby-test']
209
+ @test = @db['test-safe-remove']
210
+ @test.save({:a => 50})
211
+ @test.remove({}, :safe => true)
212
+ @test.drop
213
+ end
214
+
207
215
  def test_count
208
216
  @@test.drop
209
217
 
@@ -429,15 +437,9 @@ class TestCollection < Test::Unit::TestCase
429
437
  assert_equal 4, @@test.group([], {}, @initial, Code.new(@reduce_function, {"inc_value" => 2}))[0]["count"]
430
438
  end
431
439
 
432
- should "group results using command form" do
433
- assert_equal 1, @@test.group([], {}, @initial, Code.new(@reduce_function, {"inc_value" => 0.5}), true)[0]["count"]
434
- assert_equal 2, @@test.group([], {}, @initial, Code.new(@reduce_function, {"inc_value" => 1}), true)[0]["count"]
435
- assert_equal 4, @@test.group([], {}, @initial, Code.new(@reduce_function, {"inc_value" => 2}), true)[0]["count"]
436
- end
437
-
438
440
  should "finalize grouped results" do
439
441
  @finalize = "function(doc) {doc.f = doc.count + 200; }"
440
- assert_equal 202, @@test.group([], {}, @initial, Code.new(@reduce_function, {"inc_value" => 1}), true, @finalize)[0]["f"]
442
+ assert_equal 202, @@test.group([], {}, @initial, Code.new(@reduce_function, {"inc_value" => 1}), @finalize)[0]["f"]
441
443
  end
442
444
  end
443
445
 
@@ -455,16 +457,10 @@ class TestCollection < Test::Unit::TestCase
455
457
  end
456
458
 
457
459
  should "group results" do
458
- results = @@test.group(@keyf, {}, @initial, @reduce, true).sort {|a, b| a['count'] <=> b['count']}
460
+ results = @@test.group(@keyf, {}, @initial, @reduce).sort {|a, b| a['count'] <=> b['count']}
459
461
  assert results[0]['even'] && results[0]['count'] == 2.0
460
462
  assert results[1]['odd'] && results[1]['count'] == 3.0
461
463
  end
462
-
463
- should "raise an error if trying to use keyf as a group eval" do
464
- assert_raise OperationFailure do
465
- @@test.group(@keyf, {}, @initial, @reduce)
466
- end
467
- end
468
464
  end
469
465
 
470
466
  context "A collection with two records" do
@@ -69,8 +69,6 @@ class TestConnection < Test::Unit::TestCase
69
69
  assert_kind_of Array, names
70
70
  assert names.length >= 1
71
71
  assert names.include?('ruby-mongo-info-test')
72
-
73
- @mongo.drop_database('ruby-mongo-info-test')
74
72
  end
75
73
 
76
74
  def test_logging
@@ -80,7 +78,7 @@ class TestConnection < Test::Unit::TestCase
80
78
  db = Connection.new(@host, @port, :logger => logger).db('ruby-mongo-test')
81
79
  assert output.string.include?("admin.$cmd.find")
82
80
  end
83
-
81
+
84
82
  def test_connection_logger
85
83
  output = StringIO.new
86
84
  logger = Logger.new(output)
@@ -124,6 +122,38 @@ class TestConnection < Test::Unit::TestCase
124
122
  assert_equal ['foo', 123], nodes[1]
125
123
  end
126
124
 
125
+ context "Saved authentications" do
126
+ setup do
127
+ @conn = Mongo::Connection.new
128
+ @auth = {'db_name' => 'test', 'username' => 'bob', 'password' => 'secret'}
129
+ @conn.add_auth(@auth['db_name'], @auth['username'], @auth['password'])
130
+ end
131
+
132
+ should "save the authentication" do
133
+ assert_equal @auth, @conn.auths[0]
134
+ end
135
+
136
+ should "replace the auth if given a new auth for the same db" do
137
+ auth = {'db_name' => 'test', 'username' => 'mickey', 'password' => 'm0u53'}
138
+ @conn.add_auth(auth['db_name'], auth['username'], auth['password'])
139
+ assert_equal 1, @conn.auths.length
140
+ assert_equal auth, @conn.auths[0]
141
+ end
142
+
143
+ should "remove auths by database" do
144
+ @conn.remove_auth('non-existent database')
145
+ assert_equal 1, @conn.auths.length
146
+
147
+ @conn.remove_auth('test')
148
+ assert_equal 0, @conn.auths.length
149
+ end
150
+
151
+ should "remove all auths" do
152
+ @conn.clear_auths
153
+ assert_equal 0, @conn.auths.length
154
+ end
155
+ end
156
+
127
157
  context "Connection exceptions" do
128
158
  setup do
129
159
  @conn = Mongo::Connection.new('localhost', 27017, :pool_size => 10, :timeout => 10)
File without changes
@@ -54,13 +54,6 @@ class CursorTest < Test::Unit::TestCase
54
54
  assert_equal 0, @@db['acollectionthatdoesn'].count()
55
55
  end
56
56
 
57
- def test_next_object_deprecation
58
- @@coll.remove
59
- @@coll.insert({"a" => 1})
60
-
61
- assert_equal 1, @@coll.find().next_object["a"]
62
- end
63
-
64
57
  def test_sort
65
58
  @@coll.remove
66
59
  5.times{|x| @@coll.insert({"age" => x}) }