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,69 @@
1
+ # --
2
+ # Copyright (C) 2008-2009 10gen Inc.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ # ++
16
+ module Mongo
17
+ # Simple class for comparing server versions.
18
+ class ServerVersion
19
+ include Comparable
20
+
21
+ def initialize(version)
22
+ @version = version
23
+ end
24
+
25
+ # Implements comparable.
26
+ def <=>(new)
27
+ local, new = self.to_a, to_array(new)
28
+ for n in 0...local.size do
29
+ break if elements_include_mods?(local[n], new[n])
30
+ if local[n] < new[n].to_i
31
+ result = -1
32
+ break;
33
+ elsif local[n] > new[n].to_i
34
+ result = 1
35
+ break;
36
+ end
37
+ end
38
+ result || 0
39
+ end
40
+
41
+ # Return an array representation of this server version.
42
+ def to_a
43
+ to_array(@version)
44
+ end
45
+
46
+ # Return a string representation of this server version.
47
+ def to_s
48
+ @version
49
+ end
50
+
51
+ private
52
+
53
+ # Returns true if any elements include mod symbols (-, +)
54
+ def elements_include_mods?(*elements)
55
+ elements.any? { |n| n =~ /[\-\+]/ }
56
+ end
57
+
58
+ # Converts argument to an array of integers,
59
+ # appending any mods as the final element.
60
+ def to_array(version)
61
+ array = version.split(".").map {|n| (n =~ /^\d+$/) ? n.to_i : n }
62
+ if array.last =~ /(\d+)([\-\+])/
63
+ array[array.length-1] = $1.to_i
64
+ array << $2
65
+ end
66
+ array
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,26 @@
1
+ # --
2
+ # Copyright (C) 2008-2009 10gen Inc.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ # ++
16
+
17
+ #:nodoc:
18
+ class Object
19
+
20
+ #:nodoc:
21
+ def returning(value)
22
+ yield value
23
+ value
24
+ end
25
+
26
+ end
@@ -0,0 +1,112 @@
1
+ # --
2
+ # Copyright (C) 2008-2009 10gen Inc.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ # ++
16
+
17
+ require 'rexml/document'
18
+ require 'mongo'
19
+
20
+ # @deprecated
21
+ # Converts a .xson file (an XML file that describes a Mongo-type document) to
22
+ # an OrderedHash.
23
+ class XMLToRuby
24
+
25
+ include Mongo
26
+
27
+ def xml_to_ruby(io)
28
+ warn "XMLToRuby is deprecated. The .xson format is not longer in use."
29
+ doc = REXML::Document.new(io)
30
+ doc_to_ruby(doc.root.elements['doc'])
31
+ end
32
+
33
+ protected
34
+
35
+ def element_to_ruby(e)
36
+ warn "XMLToRuby is deprecated. The .xson format is not longer in use."
37
+ type = e.name
38
+ child = e.elements[1]
39
+ case type
40
+ when 'oid'
41
+ ObjectID.from_string(e.text)
42
+ when 'ref'
43
+ dbref_to_ruby(e.elements)
44
+ when 'int'
45
+ e.text.to_i
46
+ when 'number'
47
+ e.text.to_f
48
+ when 'string'
49
+ e.text.to_s
50
+ when 'code'
51
+ Code.new(e.text.to_s)
52
+ when 'binary'
53
+ bin = Binary.new
54
+ decoded = Base64.decode64(e.text.to_s)
55
+ decoded.each_byte { |b| bin.put(b) }
56
+ bin
57
+ when 'symbol'
58
+ e.text.to_s.intern
59
+ when 'boolean'
60
+ e.text.to_s == 'true'
61
+ when 'array'
62
+ array_to_ruby(e.elements)
63
+ when 'date'
64
+ Time.at(e.text.to_f / 1000.0)
65
+ when 'regex'
66
+ regex_to_ruby(e.elements)
67
+ when 'null'
68
+ nil
69
+ when 'doc'
70
+ doc_to_ruby(e)
71
+ else
72
+ raise "Unknown type #{type} in element with name #{e.attributes['name']}"
73
+ end
74
+ end
75
+
76
+ def doc_to_ruby(element)
77
+ warn "XMLToRuby is deprecated. The .xson format is not longer in use."
78
+ oh = OrderedHash.new
79
+ element.elements.each { |e| oh[e.attributes['name']] = element_to_ruby(e) }
80
+ oh
81
+ end
82
+
83
+ def array_to_ruby(elements)
84
+ warn "XMLToRuby is deprecated. The .xson format is not longer in use."
85
+ a = []
86
+ elements.each { |e|
87
+ index_str = e.attributes['name']
88
+ a[index_str.to_i] = element_to_ruby(e)
89
+ }
90
+ a
91
+ end
92
+
93
+ def regex_to_ruby(elements)
94
+ warn "XMLToRuby is deprecated. The .xson format is not longer in use."
95
+ pattern = elements['pattern'].text
96
+ options_str = elements['options'].text || ''
97
+
98
+ options = 0
99
+ options |= Regexp::IGNORECASE if options_str.include?('i')
100
+ options |= Regexp::MULTILINE if options_str.include?('m')
101
+ options |= Regexp::EXTENDED if options_str.include?('x')
102
+ Regexp.new(pattern, options)
103
+ end
104
+
105
+ def dbref_to_ruby(elements)
106
+ warn "XMLToRuby is deprecated. The .xson format is not longer in use."
107
+ ns = elements['ns'].text
108
+ oid_str = elements['oid'].text
109
+ DBRef.new(ns, ObjectID.from_string(oid_str))
110
+ end
111
+
112
+ end
@@ -0,0 +1,28 @@
1
+ require "lib/mongo"
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = 'mongo-find_replace'
5
+
6
+ s.version = Mongo::VERSION
7
+
8
+ s.platform = Gem::Platform::RUBY
9
+ s.summary = 'Ruby driver for the MongoDB implementing find_replace mongo 1.3.0 feature'
10
+ s.description = 'A Ruby driver for MongoDB. For more information about Mongo, see http://www.mongodb.org.'
11
+
12
+ s.require_paths = ['lib']
13
+
14
+ s.files = ['README.rdoc', 'Rakefile', 'mongo-ruby-driver.gemspec', 'LICENSE.txt']
15
+ s.files += Dir['lib/**/*.rb'] + Dir['examples/**/*.rb'] + Dir['bin/**/*.rb']
16
+ s.test_files = Dir['test/**/*.rb']
17
+
18
+ s.has_rdoc = true
19
+ s.test_files = Dir['test/**/*.rb']
20
+
21
+ s.has_rdoc = true
22
+ s.rdoc_options = ['--main', 'README.rdoc', '--inline-source']
23
+ s.extra_rdoc_files = ['README.rdoc']
24
+
25
+ s.authors = ['Jim Menard', 'Mike Dirolf']
26
+ s.email = 'mongodb-dev@googlegroups.com'
27
+ s.homepage = 'http://www.mongodb.org'
28
+ 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
@@ -0,0 +1,67 @@
1
+ require 'test/test_helper'
2
+
3
+ # NOTE: assumes Mongo is running
4
+ class AdminTest < Test::Unit::TestCase
5
+
6
+ include Mongo
7
+
8
+ @@db = Connection.new(ENV['MONGO_RUBY_DRIVER_HOST'] || 'localhost',
9
+ ENV['MONGO_RUBY_DRIVER_PORT'] || Connection::DEFAULT_PORT).db('ruby-mongo-test')
10
+ @@coll = @@db.collection('test')
11
+
12
+ def setup
13
+ # Insert some data to make sure the database itself exists.
14
+ @@coll.remove
15
+ @r1 = @@coll.insert('a' => 1) # collection not created until it's used
16
+ @@coll_full_name = 'ruby-mongo-test.test'
17
+ @admin = @@db.admin
18
+ end
19
+
20
+ def teardown
21
+ @admin.profiling_level = :off
22
+ @@coll.remove if @@coll
23
+ @@db.error
24
+ end
25
+
26
+ def test_default_profiling_level
27
+ assert_equal :off, @admin.profiling_level
28
+ end
29
+
30
+ def test_change_profiling_level
31
+ @admin.profiling_level = :slow_only
32
+ assert_equal :slow_only, @admin.profiling_level
33
+ @admin.profiling_level = :off
34
+ assert_equal :off, @admin.profiling_level
35
+ @admin.profiling_level = :all
36
+ assert_equal :all, @admin.profiling_level
37
+ begin
38
+ @admin.profiling_level = :medium
39
+ fail "shouldn't be able to do this"
40
+ rescue
41
+ end
42
+ end
43
+
44
+ def test_profiling_info
45
+ # Perform at least one query while profiling so we have something to see.
46
+ @admin.profiling_level = :all
47
+ @@coll.find()
48
+ @admin.profiling_level = :off
49
+
50
+ info = @admin.profiling_info
51
+ assert_kind_of Array, info
52
+ assert info.length >= 1
53
+ first = info.first
54
+ assert_kind_of String, first['info']
55
+ assert_kind_of Time, first['ts']
56
+ assert_kind_of Numeric, first['millis']
57
+ end
58
+
59
+ def test_validate_collection
60
+ doc = @admin.validate_collection(@@coll.name)
61
+ assert_not_nil doc
62
+ result = doc['result']
63
+ assert_not_nil result
64
+ assert_match /firstExtent/, result
65
+ end
66
+
67
+ end