mongo 0.18.3 → 0.19

Sign up to get free protection for your applications and to get access to all the features.
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}) }