mongo-find_replace 0.18.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. data/LICENSE.txt +202 -0
  2. data/README.rdoc +358 -0
  3. data/Rakefile +133 -0
  4. data/bin/bson_benchmark.rb +59 -0
  5. data/bin/fail_if_no_c.rb +11 -0
  6. data/examples/admin.rb +42 -0
  7. data/examples/capped.rb +22 -0
  8. data/examples/cursor.rb +48 -0
  9. data/examples/gridfs.rb +88 -0
  10. data/examples/index_test.rb +126 -0
  11. data/examples/info.rb +31 -0
  12. data/examples/queries.rb +70 -0
  13. data/examples/simple.rb +24 -0
  14. data/examples/strict.rb +35 -0
  15. data/examples/types.rb +36 -0
  16. data/lib/mongo.rb +61 -0
  17. data/lib/mongo/admin.rb +95 -0
  18. data/lib/mongo/collection.rb +664 -0
  19. data/lib/mongo/connection.rb +555 -0
  20. data/lib/mongo/cursor.rb +393 -0
  21. data/lib/mongo/db.rb +527 -0
  22. data/lib/mongo/exceptions.rb +60 -0
  23. data/lib/mongo/gridfs.rb +22 -0
  24. data/lib/mongo/gridfs/chunk.rb +90 -0
  25. data/lib/mongo/gridfs/grid_store.rb +555 -0
  26. data/lib/mongo/types/binary.rb +48 -0
  27. data/lib/mongo/types/code.rb +36 -0
  28. data/lib/mongo/types/dbref.rb +38 -0
  29. data/lib/mongo/types/min_max_keys.rb +58 -0
  30. data/lib/mongo/types/objectid.rb +219 -0
  31. data/lib/mongo/types/regexp_of_holding.rb +45 -0
  32. data/lib/mongo/util/bson_c.rb +18 -0
  33. data/lib/mongo/util/bson_ruby.rb +595 -0
  34. data/lib/mongo/util/byte_buffer.rb +222 -0
  35. data/lib/mongo/util/conversions.rb +97 -0
  36. data/lib/mongo/util/ordered_hash.rb +135 -0
  37. data/lib/mongo/util/server_version.rb +69 -0
  38. data/lib/mongo/util/support.rb +26 -0
  39. data/lib/mongo/util/xml_to_ruby.rb +112 -0
  40. data/mongo-ruby-driver.gemspec +28 -0
  41. data/test/replica/count_test.rb +34 -0
  42. data/test/replica/insert_test.rb +50 -0
  43. data/test/replica/pooled_insert_test.rb +54 -0
  44. data/test/replica/query_test.rb +39 -0
  45. data/test/test_admin.rb +67 -0
  46. data/test/test_bson.rb +397 -0
  47. data/test/test_byte_buffer.rb +81 -0
  48. data/test/test_chunk.rb +82 -0
  49. data/test/test_collection.rb +534 -0
  50. data/test/test_connection.rb +160 -0
  51. data/test/test_conversions.rb +120 -0
  52. data/test/test_cursor.rb +386 -0
  53. data/test/test_db.rb +254 -0
  54. data/test/test_db_api.rb +783 -0
  55. data/test/test_db_connection.rb +16 -0
  56. data/test/test_grid_store.rb +306 -0
  57. data/test/test_helper.rb +42 -0
  58. data/test/test_objectid.rb +156 -0
  59. data/test/test_ordered_hash.rb +168 -0
  60. data/test/test_round_trip.rb +114 -0
  61. data/test/test_slave_connection.rb +36 -0
  62. data/test/test_threading.rb +87 -0
  63. data/test/threading/test_threading_large_pool.rb +90 -0
  64. data/test/unit/collection_test.rb +52 -0
  65. data/test/unit/connection_test.rb +59 -0
  66. data/test/unit/cursor_test.rb +94 -0
  67. data/test/unit/db_test.rb +97 -0
  68. metadata +123 -0
@@ -0,0 +1,168 @@
1
+ require 'test/test_helper'
2
+
3
+ class OrderedHashTest < Test::Unit::TestCase
4
+
5
+ def setup
6
+ @oh = OrderedHash.new
7
+ @oh['c'] = 1
8
+ @oh['a'] = 2
9
+ @oh['z'] = 3
10
+ @ordered_keys = %w(c a z)
11
+ end
12
+
13
+ def test_initialize
14
+ a = OrderedHash.new
15
+ a['x'] = 1
16
+ a['y'] = 2
17
+
18
+ b = OrderedHash['x' => 1, 'y' => 2]
19
+ assert_equal a, b
20
+ end
21
+
22
+ def test_hash_code
23
+ o = OrderedHash.new
24
+ o['number'] = 50
25
+ assert o.hash
26
+ end
27
+
28
+ def test_empty
29
+ assert_equal [], OrderedHash.new.keys
30
+ end
31
+
32
+ def test_uniq
33
+ list = []
34
+ doc = OrderedHash.new
35
+ doc['_id'] = 'ab12'
36
+ doc['name'] = 'test'
37
+
38
+ same_doc = OrderedHash.new
39
+ same_doc['_id'] = 'ab12'
40
+ same_doc['name'] = 'test'
41
+ list << doc
42
+ list << same_doc
43
+
44
+ assert_equal 2, list.size
45
+ assert_equal 1, list.uniq.size
46
+ end
47
+
48
+ def test_equality
49
+ a = OrderedHash.new
50
+ a['x'] = 1
51
+ a['y'] = 2
52
+
53
+ b = OrderedHash.new
54
+ b['y'] = 2
55
+ b['x'] = 1
56
+
57
+ c = OrderedHash.new
58
+ c['x'] = 1
59
+ c['y'] = 2
60
+
61
+ d = OrderedHash.new
62
+ d['x'] = 2
63
+ d['y'] = 3
64
+
65
+ e = OrderedHash.new
66
+ e['z'] = 1
67
+ e['y'] = 2
68
+
69
+ assert_equal a, c
70
+ assert_not_equal a, b
71
+ assert_not_equal a, d
72
+ assert_not_equal a, e
73
+ end
74
+
75
+ def test_order_preserved
76
+ assert_equal @ordered_keys, @oh.keys
77
+ end
78
+
79
+ def test_order_preserved_after_replace
80
+ @oh['a'] = 42
81
+ assert_equal @ordered_keys, @oh.keys
82
+ @oh['c'] = 'foobar'
83
+ assert_equal @ordered_keys, @oh.keys
84
+ @oh['z'] = /huh?/
85
+ assert_equal @ordered_keys, @oh.keys
86
+ end
87
+
88
+ def test_each
89
+ keys = []
90
+ @oh.each { |k, v| keys << k }
91
+ assert_equal keys, @oh.keys
92
+
93
+ @oh['z'] = 42
94
+ assert_equal keys, @oh.keys
95
+
96
+ assert_equal @oh, @oh.each {|k,v|}
97
+ end
98
+
99
+ def test_values
100
+ assert_equal [1, 2, 3], @oh.values
101
+ end
102
+
103
+ def test_merge
104
+ other = OrderedHash.new
105
+ other['f'] = 'foo'
106
+ noob = @oh.merge(other)
107
+ assert_equal @ordered_keys + ['f'], noob.keys
108
+ assert_equal [1, 2, 3, 'foo'], noob.values
109
+ end
110
+
111
+ def test_merge_bang
112
+ other = OrderedHash.new
113
+ other['f'] = 'foo'
114
+ @oh.merge!(other)
115
+ assert_equal @ordered_keys + ['f'], @oh.keys
116
+ assert_equal [1, 2, 3, 'foo'], @oh.values
117
+ end
118
+
119
+ def test_merge_bang_with_overlap
120
+ other = OrderedHash.new
121
+ other['a'] = 'apple'
122
+ other['c'] = 'crab'
123
+ other['f'] = 'foo'
124
+ @oh.merge!(other)
125
+ assert_equal @ordered_keys + ['f'], @oh.keys
126
+ assert_equal ['crab', 'apple', 3, 'foo'], @oh.values
127
+ end
128
+
129
+ def test_merge_bang_with_hash_with_overlap
130
+ other = Hash.new
131
+ other['a'] = 'apple'
132
+ other['c'] = 'crab'
133
+ other['f'] = 'foo'
134
+ @oh.merge!(other)
135
+ assert_equal @ordered_keys + ['f'], @oh.keys
136
+ assert_equal ['crab', 'apple', 3, 'foo'], @oh.values
137
+ end
138
+
139
+ def test_update
140
+ other = OrderedHash.new
141
+ other['f'] = 'foo'
142
+ noob = @oh.update(other)
143
+ assert_equal @ordered_keys + ['f'], noob.keys
144
+ assert_equal [1, 2, 3, 'foo'], noob.values
145
+ end
146
+
147
+ def test_inspect_retains_order
148
+ assert_equal '{"c"=>1, "a"=>2, "z"=>3}', @oh.inspect
149
+ end
150
+
151
+ def test_clear
152
+ @oh.clear
153
+ assert @oh.keys.empty?
154
+ end
155
+
156
+ def test_delete
157
+ assert @oh.keys.include?('z')
158
+ @oh.delete('z')
159
+ assert !@oh.keys.include?('z')
160
+ end
161
+
162
+ def test_delete_if
163
+ assert @oh.keys.include?('z')
164
+ @oh.delete_if { |k,v| k == 'z' }
165
+ assert !@oh.keys.include?('z')
166
+ end
167
+
168
+ end
@@ -0,0 +1,114 @@
1
+ HERE = File.dirname(__FILE__)
2
+ $LOAD_PATH[0,0] = File.join(HERE, '..', 'lib')
3
+ require 'test/test_helper'
4
+ require 'mongo/util/xml_to_ruby'
5
+
6
+ # For each xml/bson file in the data subdirectory, we turn the XML into an
7
+ # OrderedHash and then test both Ruby-to-BSON and BSON-to-Ruby translations.
8
+ #
9
+ # There is a whole other project that includes similar tests
10
+ # (http://github.com/mongodb/mongo-qa). If the directory ../../mongo-qa
11
+ # exists, (that is, the top-level dir of mongo-qa is next to the top-level dir
12
+ # of this project), then we find the BSON test files there and use those, too.
13
+ class RoundTripTest < Test::Unit::TestCase
14
+
15
+ include Mongo
16
+
17
+ @@ruby = nil
18
+
19
+ def setup
20
+ unless @@ruby
21
+ names = Dir[File.join(HERE, 'data', '*.xml')].collect {|f| File.basename(f).sub(/\.xml$/, '') }
22
+ @@ruby = {}
23
+ names.each { |name|
24
+ File.open(File.join(HERE, 'data', "#{name}.xml")) { |f|
25
+ @@ruby[name] = XMLToRuby.new.xml_to_ruby(f)
26
+ }
27
+ }
28
+ end
29
+ end
30
+
31
+ def test_dummy
32
+ assert true
33
+ end
34
+
35
+ def self.create_test_for_round_trip_files_in_dir(dir)
36
+ names = Dir[File.join(dir, '*.xson')].collect {|f| File.basename(f).sub(/\.xson$/, '') }
37
+ names.each { |name|
38
+ eval <<EOS
39
+ def test_#{name}_#{dir.gsub(/[^a-zA-Z0-9_]/, '_')}
40
+ one_round_trip("#{dir}", "#{name}")
41
+ end
42
+ EOS
43
+ }
44
+ end
45
+
46
+ # Dynamically generate one test for each test file. This way, if one test
47
+ # fails the others will still run.
48
+ create_test_for_round_trip_files_in_dir(File.join(HERE, 'data'))
49
+ mongo_qa_dir = File.join(HERE, '../..', 'mongo-qa/modules/bson_tests/tests')
50
+ if File.exist?(mongo_qa_dir)
51
+ %w(basic_types complex single_types).each { |subdir_name|
52
+ create_test_for_round_trip_files_in_dir(File.join(mongo_qa_dir, subdir_name))
53
+ }
54
+ end
55
+
56
+ # Round-trip comparisons of Ruby-to-BSON and back.
57
+ # * Take the objects that were read from XML
58
+ # * Turn them into BSON bytes
59
+ # * Compare that with the BSON files we have
60
+ # * Turn those BSON bytes back in to Ruby objects
61
+ # * Turn them back into BSON bytes
62
+ # * Compare that with the BSON files we have (or the bytes that were already
63
+ # generated)
64
+ def one_round_trip(dir, name)
65
+ obj = File.open(File.join(dir, "#{name}.xson")) { |f|
66
+ begin
67
+ XMLToRuby.new.xml_to_ruby(f)
68
+ rescue => ex # unsupported type
69
+ return
70
+ end
71
+ }
72
+
73
+ File.open(File.join(dir, "#{name}.bson"), 'rb') { |f|
74
+ # Read the BSON from the file
75
+ bson = f.read
76
+
77
+ # Turn the Ruby object into BSON bytes and compare with the BSON bytes
78
+ # from the file.
79
+ bson_from_ruby = BSON.serialize(obj)
80
+
81
+ begin
82
+ assert_equal bson.length, bson_from_ruby.to_s.length
83
+ assert_equal bson, bson_from_ruby.to_s
84
+ rescue => ex
85
+ # File.open(File.join(dir, "#{name}_out_a.bson"), 'wb') { |f| # DEBUG
86
+ # bson_from_ruby.each { |b| f.putc(b) }
87
+ # }
88
+ raise ex
89
+ end
90
+
91
+ # Turn those BSON bytes back into a Ruby object.
92
+ #
93
+ # We're passing a nil db to the contructor here, but that's OK because
94
+ # the BSON DBRef bytes don't contain the db object in any case, and we
95
+ # don't care what the database is.
96
+ obj_from_bson = BSON.deserialize(bson_from_ruby)
97
+ assert_kind_of OrderedHash, obj_from_bson
98
+
99
+ # Turn that Ruby object into BSON and compare it to the original BSON
100
+ # bytes.
101
+ bson_from_ruby = BSON.serialize(obj_from_bson)
102
+ begin
103
+ assert_equal bson.length, bson_from_ruby.to_s.length
104
+ assert_equal bson, bson_from_ruby.to_s
105
+ rescue => ex
106
+ # File.open(File.join(dir, "#{name}_out_b.bson"), 'wb') { |f| # DEBUG
107
+ # bson_from_ruby.each { |b| f.putc(b) }
108
+ # }
109
+ raise ex
110
+ end
111
+ }
112
+ end
113
+
114
+ end
@@ -0,0 +1,36 @@
1
+ require 'test/test_helper'
2
+
3
+ # NOTE: these tests are run only if we can connect to a single MongoDB in slave mode.
4
+ class SlaveConnectionTest < Test::Unit::TestCase
5
+ include Mongo
6
+
7
+ def self.connect_to_slave
8
+ @@host = ENV['MONGO_RUBY_DRIVER_HOST'] || 'localhost'
9
+ @@port = ENV['MONGO_RUBY_DRIVER_PORT'] || Connection::DEFAULT_PORT
10
+ conn = Connection.new(@@host, @@port, :slave_ok => true)
11
+ cmd = conn['admin'].command(:ismaster => 1)
12
+ cmd['ok'] == 1 && cmd['ismaster'] != 1
13
+ end
14
+
15
+ if self.connect_to_slave
16
+ puts "Connected to slave; running slave tests."
17
+
18
+ def test_connect_to_slave
19
+ assert_raise Mongo::ConfigurationError do
20
+ @db = Connection.new(@@host, @@port, :slave_ok => false).db('ruby-mongo-demo')
21
+ end
22
+ end
23
+
24
+ def test_slave_ok_sent_to_queries
25
+ @db = Connection.new(@@host, @@port, :slave_ok => true).db('ruby-mongo-demo')
26
+ assert_equal true, @db.slave_ok?
27
+ end
28
+ else
29
+ puts "Not connected to slave; skipping slave connection tests."
30
+
31
+ def test_slave_ok_false_on_queries
32
+ @conn = Connection.new(@@host, @@port)
33
+ assert !@conn.slave_ok?
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,87 @@
1
+ require 'test/test_helper'
2
+
3
+ class TestThreading < Test::Unit::TestCase
4
+
5
+ include Mongo
6
+
7
+ @@db = Connection.new('localhost', 27017, :pool_size => 1, :timeout => 30).db('ruby-mongo-test')
8
+ @@coll = @@db.collection('thread-test-collection')
9
+
10
+ def set_up_safe_data
11
+ @@db.drop_collection('duplicate')
12
+ @@db.drop_collection('unique')
13
+ @duplicate = @@db.collection('duplicate')
14
+ @unique = @@db.collection('unique')
15
+
16
+ @duplicate.insert("test" => "insert")
17
+ @duplicate.insert("test" => "update")
18
+ @unique.insert("test" => "insert")
19
+ @unique.insert("test" => "update")
20
+ @unique.create_index("test", true)
21
+ end
22
+
23
+ def test_safe_update
24
+ set_up_safe_data
25
+ threads = []
26
+ 100.times do |i|
27
+ threads[i] = Thread.new do
28
+ if i % 2 == 0
29
+ assert_raise Mongo::OperationFailure do
30
+ @unique.update({"test" => "insert"}, {"$set" => {"test" => "update"}}, :safe => true)
31
+ end
32
+ else
33
+ @duplicate.update({"test" => "insert"}, {"$set" => {"test" => "update"}}, :safe => true)
34
+ end
35
+ end
36
+ end
37
+
38
+ 100.times do |i|
39
+ threads[i].join
40
+ end
41
+ end
42
+
43
+ def test_safe_insert
44
+ set_up_safe_data
45
+ threads = []
46
+ 100.times do |i|
47
+ threads[i] = Thread.new do
48
+ if i % 2 == 0
49
+ assert_raise Mongo::OperationFailure do
50
+ @unique.insert({"test" => "insert"}, :safe => true)
51
+ end
52
+ else
53
+ @duplicate.insert({"test" => "insert"}, :safe => true)
54
+ end
55
+ end
56
+ end
57
+
58
+ 100.times do |i|
59
+ threads[i].join
60
+ end
61
+ end
62
+
63
+ def test_threading
64
+ @@coll.drop
65
+ @@coll = @@db.collection('thread-test-collection')
66
+
67
+ 1000.times do |i|
68
+ @@coll.insert("x" => i)
69
+ end
70
+
71
+ threads = []
72
+
73
+ 10.times do |i|
74
+ threads[i] = Thread.new do
75
+ sum = 0
76
+ @@coll.find().each do |document|
77
+ sum += document["x"]
78
+ end
79
+ assert_equal 499500, sum
80
+ end
81
+ end
82
+
83
+ 10.times do |i|
84
+ threads[i].join
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,90 @@
1
+ require 'test/test_helper'
2
+
3
+ # Essentialy the same as test_threading.rb but with an expanded pool for
4
+ # testing multiple connections.
5
+ class TestThreadingLargePool < Test::Unit::TestCase
6
+
7
+ include Mongo
8
+
9
+ @@db = Connection.new('localhost', 27017, :pool_size => 50, :timeout => 60).db('ruby-mongo-test')
10
+ @@coll = @@db.collection('thread-test-collection')
11
+
12
+ def set_up_safe_data
13
+ @@db.drop_collection('duplicate')
14
+ @@db.drop_collection('unique')
15
+ @duplicate = @@db.collection('duplicate')
16
+ @unique = @@db.collection('unique')
17
+
18
+ @duplicate.insert("test" => "insert")
19
+ @duplicate.insert("test" => "update")
20
+ @unique.insert("test" => "insert")
21
+ @unique.insert("test" => "update")
22
+ @unique.create_index("test", true)
23
+ end
24
+
25
+ def test_safe_update
26
+ set_up_safe_data
27
+ threads = []
28
+ 300.times do |i|
29
+ threads[i] = Thread.new do
30
+ if i % 2 == 0
31
+ assert_raise Mongo::OperationFailure do
32
+ @unique.update({"test" => "insert"}, {"$set" => {"test" => "update"}}, :safe => true)
33
+ end
34
+ else
35
+ @duplicate.update({"test" => "insert"}, {"$set" => {"test" => "update"}}, :safe => true)
36
+ end
37
+ end
38
+ end
39
+
40
+ 300.times do |i|
41
+ threads[i].join
42
+ end
43
+ end
44
+
45
+ def test_safe_insert
46
+ set_up_safe_data
47
+ threads = []
48
+ 300.times do |i|
49
+ threads[i] = Thread.new do
50
+ if i % 2 == 0
51
+ assert_raise Mongo::OperationFailure do
52
+ @unique.insert({"test" => "insert"}, :safe => true)
53
+ end
54
+ else
55
+ @duplicate.insert({"test" => "insert"}, :safe => true)
56
+ end
57
+ end
58
+ end
59
+
60
+ 300.times do |i|
61
+ threads[i].join
62
+ end
63
+ end
64
+
65
+ def test_threading
66
+ @@coll.drop
67
+ @@coll = @@db.collection('thread-test-collection')
68
+
69
+ 1000.times do |i|
70
+ @@coll.insert("x" => i)
71
+ end
72
+
73
+ threads = []
74
+
75
+ 10.times do |i|
76
+ threads[i] = Thread.new do
77
+ sum = 0
78
+ @@coll.find().each do |document|
79
+ sum += document["x"]
80
+ end
81
+ assert_equal 499500, sum
82
+ end
83
+ end
84
+
85
+ 10.times do |i|
86
+ threads[i].join
87
+ end
88
+ end
89
+
90
+ end