mongo-find_replace 0.18.3

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