mongo 1.8.0 → 1.8.2

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