mongo 1.8.0 → 1.8.2

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 (80) hide show
  1. data/README.md +14 -29
  2. data/VERSION +1 -1
  3. data/lib/mongo.rb +3 -0
  4. data/lib/mongo/collection.rb +99 -49
  5. data/lib/mongo/cursor.rb +17 -17
  6. data/lib/mongo/db.rb +30 -14
  7. data/lib/mongo/gridfs/grid.rb +5 -3
  8. data/lib/mongo/gridfs/grid_file_system.rb +5 -3
  9. data/lib/mongo/gridfs/grid_io.rb +5 -3
  10. data/lib/mongo/legacy.rb +9 -2
  11. data/lib/mongo/mongo_client.rb +100 -72
  12. data/lib/mongo/mongo_replica_set_client.rb +46 -60
  13. data/lib/mongo/mongo_sharded_client.rb +5 -66
  14. data/lib/mongo/networking.rb +2 -1
  15. data/lib/mongo/util/node.rb +41 -42
  16. data/lib/mongo/util/pool.rb +15 -43
  17. data/lib/mongo/util/pool_manager.rb +16 -65
  18. data/lib/mongo/util/read_preference.rb +82 -0
  19. data/lib/mongo/util/sharding_pool_manager.rb +0 -86
  20. data/lib/mongo/util/ssl_socket.rb +2 -1
  21. data/lib/mongo/util/support.rb +8 -18
  22. data/lib/mongo/util/tcp_socket.rb +5 -4
  23. data/lib/mongo/util/thread_local_variable_manager.rb +29 -0
  24. data/lib/mongo/util/unix_socket.rb +23 -0
  25. data/lib/mongo/util/uri_parser.rb +31 -18
  26. data/lib/mongo/util/write_concern.rb +7 -2
  27. data/mongo.gemspec +1 -1
  28. data/test/auxillary/repl_set_auth_test.rb +2 -2
  29. data/test/bson/bson_test.rb +1 -1
  30. data/test/bson/byte_buffer_test.rb +24 -26
  31. data/test/bson/hash_with_indifferent_access_test.rb +11 -1
  32. data/test/functional/collection_test.rb +16 -16
  33. data/test/functional/connection_test.rb +1 -4
  34. data/test/functional/db_api_test.rb +14 -10
  35. data/test/functional/pool_test.rb +23 -31
  36. data/test/functional/timeout_test.rb +3 -5
  37. data/test/functional/uri_test.rb +10 -5
  38. data/test/replica_set/basic_test.rb +3 -8
  39. data/test/replica_set/client_test.rb +47 -31
  40. data/test/replica_set/complex_connect_test.rb +12 -10
  41. data/test/replica_set/connection_test.rb +8 -151
  42. data/test/replica_set/count_test.rb +9 -5
  43. data/test/replica_set/cursor_test.rb +17 -27
  44. data/test/replica_set/insert_test.rb +5 -10
  45. data/test/replica_set/query_test.rb +4 -9
  46. data/test/replica_set/read_preference_test.rb +200 -0
  47. data/test/replica_set/refresh_test.rb +54 -65
  48. data/test/replica_set/replication_ack_test.rb +16 -14
  49. data/test/sharded_cluster/basic_test.rb +30 -0
  50. data/test/test_helper.rb +33 -15
  51. data/test/threading/basic_test.rb +79 -0
  52. data/test/tools/mongo_config.rb +62 -22
  53. data/test/unit/client_test.rb +36 -14
  54. data/test/unit/collection_test.rb +23 -0
  55. data/test/unit/connection_test.rb +30 -14
  56. data/test/unit/cursor_test.rb +137 -7
  57. data/test/unit/db_test.rb +17 -4
  58. data/test/unit/grid_test.rb +2 -2
  59. data/test/unit/node_test.rb +2 -1
  60. data/test/unit/pool_manager_test.rb +29 -1
  61. data/test/unit/read_test.rb +15 -15
  62. data/test/unit/safe_test.rb +4 -4
  63. data/test/unit/write_concern_test.rb +4 -4
  64. metadata +134 -143
  65. data/examples/admin.rb +0 -43
  66. data/examples/capped.rb +0 -22
  67. data/examples/cursor.rb +0 -48
  68. data/examples/gridfs.rb +0 -44
  69. data/examples/index_test.rb +0 -126
  70. data/examples/info.rb +0 -31
  71. data/examples/queries.rb +0 -74
  72. data/examples/replica_set.rb +0 -26
  73. data/examples/simple.rb +0 -25
  74. data/examples/strict.rb +0 -35
  75. data/examples/types.rb +0 -36
  76. data/examples/web/thin/load.rb +0 -23
  77. data/examples/web/unicorn/load.rb +0 -25
  78. data/test/support/hash_with_indifferent_access.rb +0 -186
  79. data/test/support/keys.rb +0 -45
  80. data/test/threading/threading_with_large_pool_test.rb +0 -90
@@ -1,35 +0,0 @@
1
- $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
-
3
- require 'mongo'
4
-
5
- include Mongo
6
-
7
- host = ENV['MONGO_RUBY_DRIVER_HOST'] || 'localhost'
8
- port = ENV['MONGO_RUBY_DRIVER_PORT'] || MongoClient::DEFAULT_PORT
9
-
10
- puts "Connecting to #{host}:#{port}"
11
- db = MongoClient.new(host, port).db('ruby-mongo-examples')
12
-
13
- db.drop_collection('does-not-exist')
14
- db.create_collection('test')
15
-
16
- db.strict = true
17
-
18
- begin
19
- # Can't reference collection that does not exist
20
- db.collection('does-not-exist')
21
- puts "error: expected exception"
22
- rescue => ex
23
- puts "expected exception: #{ex}"
24
- end
25
-
26
- begin
27
- # Can't create collection that already exists
28
- db.create_collection('test')
29
- puts "error: expected exception"
30
- rescue => ex
31
- puts "expected exception: #{ex}"
32
- end
33
-
34
- db.strict = false
35
- db.drop_collection('test')
@@ -1,36 +0,0 @@
1
- $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
-
3
- require 'mongo'
4
- require 'pp'
5
-
6
- include Mongo
7
-
8
- host = ENV['MONGO_RUBY_DRIVER_HOST'] || 'localhost'
9
- port = ENV['MONGO_RUBY_DRIVER_PORT'] || MongoClient::DEFAULT_PORT
10
-
11
- puts "Connecting to #{host}:#{port}"
12
- db = MongoClient.new(host, port).db('ruby-mongo-examples')
13
- coll = db.collection('test')
14
-
15
- # Remove all records, if any
16
- coll.remove
17
-
18
- # Insert record with all sorts of values
19
- coll.insert('array' => [1, 2, 3],
20
- 'string' => 'hello',
21
- 'hash' => {'a' => 1, 'b' => 2},
22
- 'date' => Time.now, # milliseconds only; microseconds are not stored
23
- 'oid' => ObjectID.new,
24
- 'binary' => Binary.new([1, 2, 3]),
25
- 'int' => 42,
26
- 'float' => 33.33333,
27
- 'regex' => /foobar/i,
28
- 'boolean' => true,
29
- 'where' => Code.new('this.x == 3'),
30
- 'dbref' => DBRef.new(coll.name, ObjectID.new),
31
- 'null' => nil,
32
- 'symbol' => :zildjian)
33
-
34
- pp coll.find().next_document
35
-
36
- coll.remove
@@ -1,23 +0,0 @@
1
- require File.join(File.dirname(__FILE__), '..', '..', '..', 'lib', 'mongo')
2
- require 'logger'
3
-
4
- include Mongo
5
-
6
- $con = MongoReplicaSetClient.new(['localhost:30000', 'localhost:30001'], :read => :secondary, :refresh_mode => :sync, :refresh_interval => 30)
7
- $db = $con['foo']
8
-
9
- class Load < Sinatra::Base
10
-
11
- configure do
12
- LOGGER = Logger.new("sinatra.log")
13
- enable :logging, :dump_errors
14
- set :raise_errors, true
15
- end
16
-
17
- get '/' do
18
- $db['test'].insert({:a => rand(1000)})
19
- $db['test'].find({:a => {'$gt' => rand(2)}}, :read => :secondary).limit(2).to_a
20
- "ok"
21
- end
22
-
23
- end
@@ -1,25 +0,0 @@
1
- require File.join(File.dirname(__FILE__), '..', '..', 'lib', 'mongo')
2
-
3
- include Mongo
4
-
5
- $client = MongoClient.new('localhost', 27017)
6
- $db = $client['foo']
7
-
8
- class Load < Sinatra::Base
9
-
10
- configure do
11
- LOGGER = Logger.new("sinatra.log")
12
- enable :logging, :dump_errors
13
- set :raise_errors, true
14
- end
15
-
16
- get '/' do
17
- 3.times do |n|
18
- if (v=$db.eval("1 + #{n}")) != 1 + n
19
- STDERR << "#{1 + n} expected but got #{v}"
20
- raise StandardError, "#{1 + n} expected but got #{v}"
21
- end
22
- end
23
- end
24
-
25
- end
@@ -1,186 +0,0 @@
1
- # Note: HashWithIndifferentAccess is so commonly used
2
- # that we always need to make sure that the driver works
3
- # with it.
4
- #require File.join(File.dirname(__FILE__), 'keys.rb')
5
-
6
- # This class has dubious semantics and we only have it so that
7
- # people can write params[:key] instead of params['key']
8
- # and they get the same value for both keys.
9
-
10
- class Hash
11
- # Return a new hash with all keys converted to strings.
12
- def stringify_keys
13
- dup.stringify_keys!
14
- end
15
-
16
- # Destructively convert all keys to strings.
17
- def stringify_keys!
18
- keys.each do |key|
19
- self[key.to_s] = delete(key)
20
- end
21
- self
22
- end
23
-
24
- # Return a new hash with all keys converted to symbols, as long as
25
- # they respond to +to_sym+.
26
- def symbolize_keys
27
- dup.symbolize_keys!
28
- end
29
-
30
- # Destructively convert all keys to symbols, as long as they respond
31
- # to +to_sym+.
32
- def symbolize_keys!
33
- keys.each do |key|
34
- self[(key.to_sym rescue key) || key] = delete(key)
35
- end
36
- self
37
- end
38
-
39
- alias_method :to_options, :symbolize_keys
40
- #alias_method :to_options!, :symbolize_keys!
41
- end
42
-
43
- module ActiveSupport
44
- class HashWithIndifferentAccess < Hash
45
- def extractable_options?
46
- true
47
- end
48
-
49
- def initialize(constructor = {})
50
- if constructor.is_a?(Hash)
51
- super()
52
- update(constructor)
53
- else
54
- super(constructor)
55
- end
56
- end
57
-
58
- def default(key = nil)
59
- if key.is_a?(Symbol) && include?(key = key.to_s)
60
- self[key]
61
- else
62
- super
63
- end
64
- end
65
-
66
- def self.new_from_hash_copying_default(hash)
67
- ActiveSupport::HashWithIndifferentAccess.new(hash).tap do |new_hash|
68
- new_hash.default = hash.default
69
- end
70
- end
71
-
72
- alias_method :regular_writer, :[]= unless method_defined?(:regular_writer)
73
- alias_method :regular_update, :update unless method_defined?(:regular_update)
74
-
75
- # Assigns a new value to the hash:
76
- #
77
- # hash = HashWithIndifferentAccess.new
78
- # hash[:key] = "value"
79
- #
80
- def []=(key, value)
81
- regular_writer(convert_key(key), convert_value(value))
82
- end
83
-
84
- # Updates the instantized hash with values from the second:
85
- #
86
- # hash_1 = HashWithIndifferentAccess.new
87
- # hash_1[:key] = "value"
88
- #
89
- # hash_2 = HashWithIndifferentAccess.new
90
- # hash_2[:key] = "New Value!"
91
- #
92
- # hash_1.update(hash_2) # => {"key"=>"New Value!"}
93
- #
94
- def update(other_hash)
95
- other_hash.each_pair { |key, value| regular_writer(convert_key(key), convert_value(value)) }
96
- self
97
- end
98
-
99
- alias_method :merge!, :update
100
-
101
- # Checks the hash for a key matching the argument passed in:
102
- #
103
- # hash = HashWithIndifferentAccess.new
104
- # hash["key"] = "value"
105
- # hash.key? :key # => true
106
- # hash.key? "key" # => true
107
- #
108
- def key?(key)
109
- super(convert_key(key))
110
- end
111
-
112
- alias_method :include?, :key?
113
- alias_method :has_key?, :key?
114
- alias_method :member?, :key?
115
-
116
- # Fetches the value for the specified key, same as doing hash[key]
117
- def fetch(key, *extras)
118
- super(convert_key(key), *extras)
119
- end
120
-
121
- # Returns an array of the values at the specified indices:
122
- #
123
- # hash = HashWithIndifferentAccess.new
124
- # hash[:a] = "x"
125
- # hash[:b] = "y"
126
- # hash.values_at("a", "b") # => ["x", "y"]
127
- #
128
- def values_at(*indices)
129
- indices.collect {|key| self[convert_key(key)]}
130
- end
131
-
132
- # Returns an exact copy of the hash.
133
- def dup
134
- HashWithIndifferentAccess.new(self)
135
- end
136
-
137
- # Merges the instantized and the specified hashes together, giving precedence to the values from the second hash
138
- # Does not overwrite the existing hash.
139
- def merge(hash)
140
- self.dup.update(hash)
141
- end
142
-
143
- # Performs the opposite of merge, with the keys and values from the first hash taking precedence over the second.
144
- # This overloaded definition prevents returning a regular hash, if reverse_merge is called on a HashWithDifferentAccess.
145
- def reverse_merge(other_hash)
146
- super self.class.new_from_hash_copying_default(other_hash)
147
- end
148
-
149
- def reverse_merge!(other_hash)
150
- replace(reverse_merge( other_hash ))
151
- end
152
-
153
- # Removes a specified key from the hash.
154
- def delete(key)
155
- super(convert_key(key))
156
- end
157
-
158
- def stringify_keys!; self end
159
- def stringify_keys; dup end
160
- def symbolize_keys; to_hash.symbolize_keys end
161
- def to_options!; self end
162
-
163
- # Convert to a Hash with String keys.
164
- def to_hash
165
- Hash.new(default).merge!(self)
166
- end
167
-
168
- protected
169
- def convert_key(key)
170
- key.kind_of?(Symbol) ? key.to_s : key
171
- end
172
-
173
- def convert_value(value)
174
- case value
175
- when Hash
176
- self.class.new_from_hash_copying_default(value)
177
- when Array
178
- value.collect { |e| e.is_a?(Hash) ? self.class.new_from_hash_copying_default(e) : e }
179
- else
180
- value
181
- end
182
- end
183
- end
184
- end
185
-
186
- #HashWithIndifferentAccess = ActiveSupport::HashWithIndifferentAccess
@@ -1,45 +0,0 @@
1
- class Hash
2
- # Return a new hash with all keys converted to strings.
3
- def stringify_keys
4
- dup.stringify_keys!
5
- end
6
-
7
- # Destructively convert all keys to strings.
8
- def stringify_keys!
9
- keys.each do |key|
10
- self[key.to_s] = delete(key)
11
- end
12
- self
13
- end
14
-
15
- # Return a new hash with all keys converted to symbols, as long as
16
- # they respond to +to_sym+.
17
- def symbolize_keys
18
- dup.symbolize_keys!
19
- end
20
-
21
- # Destructively convert all keys to symbols, as long as they respond
22
- # to +to_sym+.
23
- def symbolize_keys!
24
- keys.each do |key|
25
- self[(key.to_sym rescue key) || key] = delete(key)
26
- end
27
- self
28
- end
29
-
30
- alias_method :to_options, :symbolize_keys
31
- #alias_method :to_options!, :symbolize_keys!
32
-
33
- # Validate all keys in a hash match *valid keys, raising ArgumentError on a mismatch.
34
- # Note that keys are NOT treated indifferently, meaning if you use strings for keys but assert symbols
35
- # as keys, this will fail.
36
- #
37
- # ==== Examples
38
- # { :name => "Rob", :years => "28" }.assert_valid_keys(:name, :age) # => raises "ArgumentError: Unknown key(s): years"
39
- # { :name => "Rob", :age => "28" }.assert_valid_keys("name", "age") # => raises "ArgumentError: Unknown key(s): name, age"
40
- # { :name => "Rob", :age => "28" }.assert_valid_keys(:name, :age) # => passes, raises nothing
41
- def assert_valid_keys(*valid_keys)
42
- unknown_keys = keys - [valid_keys].flatten
43
- raise(ArgumentError, "Unknown key(s): #{unknown_keys.join(", ")}") unless unknown_keys.empty?
44
- end
45
- end
@@ -1,90 +0,0 @@
1
- require '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
- @@client = standard_connection(:pool_size => 50, :pool_timeout => 60)
10
- @@db = @@client.db(MONGO_TEST_DB)
11
- @@coll = @@db.collection('thread-test-collection')
12
-
13
- def set_up_safe_data
14
- @@db.drop_collection('duplicate')
15
- @@db.drop_collection('unique')
16
- @duplicate = @@db.collection('duplicate')
17
- @unique = @@db.collection('unique')
18
-
19
- @duplicate.insert("test" => "insert")
20
- @duplicate.insert("test" => "update")
21
- @unique.insert("test" => "insert")
22
- @unique.insert("test" => "update")
23
- @unique.create_index("test", :unique => true)
24
- end
25
-
26
- def test_safe_update
27
- set_up_safe_data
28
- threads = []
29
- 300.times do |i|
30
- threads[i] = Thread.new do
31
- if i % 2 == 0
32
- assert_raise Mongo::OperationFailure do
33
- @unique.update({"test" => "insert"}, {"$set" => {"test" => "update"}})
34
- end
35
- else
36
- @duplicate.update({"test" => "insert"}, {"$set" => {"test" => "update"}})
37
- end
38
- end
39
- end
40
-
41
- 300.times do |i|
42
- threads[i].join
43
- end
44
- end
45
-
46
- def test_safe_insert
47
- set_up_safe_data
48
- threads = []
49
- 300.times do |i|
50
- threads[i] = Thread.new do
51
- if i % 2 == 0
52
- assert_raise Mongo::OperationFailure do
53
- @unique.insert({"test" => "insert"})
54
- end
55
- else
56
- @duplicate.insert({"test" => "insert"})
57
- end
58
- end
59
- end
60
-
61
- 300.times do |i|
62
- threads[i].join
63
- end
64
- end
65
-
66
- def test_threading
67
- @@coll.drop
68
- @@coll = @@db.collection('thread-test-collection')
69
-
70
- 1000.times do |i|
71
- @@coll.insert({ "x" => i })
72
- end
73
-
74
- threads = []
75
-
76
- 10.times do |i|
77
- threads[i] = Thread.new do
78
- sum = 0
79
- @@coll.find().each do |document|
80
- sum += document["x"]
81
- end
82
- assert_equal 499500, sum
83
- end
84
- end
85
-
86
- 10.times do |i|
87
- threads[i].join
88
- end
89
- end
90
- end