mongo 1.8.4 → 1.8.5

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 (51) hide show
  1. checksums.yaml +6 -14
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/README.md +2 -0
  5. data/VERSION +1 -1
  6. data/lib/mongo.rb +11 -9
  7. data/lib/mongo/collection.rb +26 -19
  8. data/lib/mongo/cursor.rb +7 -2
  9. data/lib/mongo/db.rb +1 -1
  10. data/lib/mongo/mongo_client.rb +1 -1
  11. data/lib/mongo/mongo_replica_set_client.rb +2 -3
  12. data/lib/mongo/mongo_sharded_client.rb +1 -2
  13. data/lib/mongo/util/node.rb +12 -14
  14. data/lib/mongo/util/pool.rb +1 -1
  15. data/lib/mongo/util/pool_manager.rb +13 -15
  16. data/lib/mongo/util/sharding_pool_manager.rb +5 -2
  17. data/lib/mongo/util/support.rb +14 -0
  18. data/mongo.gemspec +7 -3
  19. data/test/functional/authentication_test.rb +21 -0
  20. data/test/functional/collection_test.rb +0 -1
  21. data/test/functional/connection_test.rb +1 -1
  22. data/test/functional/db_test.rb +1 -56
  23. data/test/functional/support_test.rb +30 -0
  24. data/test/replica_set/authentication_test.rb +23 -0
  25. data/test/replica_set/max_values_test.rb +61 -0
  26. data/test/sharded_cluster/basic_test.rb +18 -0
  27. data/test/shared/authentication.rb +49 -0
  28. data/test/tools/mongo_config.rb +21 -26
  29. data/test/unit/node_test.rb +3 -0
  30. data/test/unit/pool_manager_test.rb +3 -1
  31. data/test/unit/read_test.rb +4 -0
  32. data/test/unit/sharding_pool_manager_test.rb +88 -0
  33. metadata +38 -69
  34. metadata.gz.sig +0 -0
  35. data/test/auxillary/1.4_feature_test.rb +0 -165
  36. data/test/auxillary/authentication_test.rb +0 -74
  37. data/test/auxillary/autoreconnect_test.rb +0 -39
  38. data/test/auxillary/fork_test.rb +0 -28
  39. data/test/auxillary/pool_reuse_test.rb +0 -65
  40. data/test/auxillary/repl_set_auth_test.rb +0 -69
  41. data/test/auxillary/slave_connection_test.rb +0 -37
  42. data/test/auxillary/threaded_authentication_test.rb +0 -99
  43. data/test/bson/binary_test.rb +0 -13
  44. data/test/bson/bson_test.rb +0 -762
  45. data/test/bson/byte_buffer_test.rb +0 -215
  46. data/test/bson/hash_with_indifferent_access_test.rb +0 -48
  47. data/test/bson/json_test.rb +0 -16
  48. data/test/bson/object_id_test.rb +0 -153
  49. data/test/bson/ordered_hash_test.rb +0 -247
  50. data/test/bson/timestamp_test.rb +0 -51
  51. data/test/tools/auth_repl_set_manager.rb +0 -14
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- MThmZWQ1YmJmNDFkNDNhMjY3MTcxZTQxNjRjZjI2YjYzMWE4MDRiOQ==
5
- data.tar.gz: !binary |-
6
- Njk3M2NhNmI2MWM1ZDE1ZGQ0MTZiYjNiYTgyNzRjYmZmM2E5MWExMg==
7
- !binary "U0hBNTEy":
8
- metadata.gz: !binary |-
9
- NjYyM2MxZDQ3ZjRiMzliMjM3NDdhZmFmYTZmMTEwNjgwNzFiZmVmOTIwNzVh
10
- MDkxZWQ2ZmNiNDUxZjA1NWQzOGNmMDNkMjRkZThhM2RhMzZiNTRlOTA4ODQ0
11
- ZDAxMjg1ZmZlYWZhNzcyZTU0OWQ5M2RlZmMyMWNkMjgzMmU5NmM=
12
- data.tar.gz: !binary |-
13
- MDU0ZTI3MjA2MzVlYjc2MDFiZGM1MjUxZjRlZDFmNDE5ZTc0NzMyNzBhMDI2
14
- NjM5ZGE1NDYxYmY2MjM3NmQyMTg1ZmMxMjFlYWU1M2ExZDgyYTU2NjRkZjk4
15
- MjIxYTliNDRmNWIyODA5YmRmYTYxMWJmYzAwNTVkOTRkYTczMzg=
2
+ SHA1:
3
+ metadata.gz: b8b721f436d16c55388789c19bd0c03b99812702
4
+ data.tar.gz: b43de3ec9c986727abd9d4bf181e038ce3ddbe02
5
+ SHA512:
6
+ metadata.gz: d0c55e5a9968be883c92acb53676b6ae8d08a77578dbaaec4cca2d71bf1c535d981d63f4f1377712819bae39733f6bde8781f8af860f5469e172bf4c2a14acb6
7
+ data.tar.gz: 241ccee8c30eadb597252c4fea0a599b920551c4f77dea15fbf747eea2abf7e0270788f496d6df657f8d88cb98728fae20a956977a285086c7f25a161bc8c89b
Binary file
data.tar.gz.sig CHANGED
Binary file
data/README.md CHANGED
@@ -241,6 +241,8 @@ for the first time.
241
241
 
242
242
  ### Strict mode
243
243
 
244
+ _**NOTE:** Support for strict mode has been deprecated and will be removed in version 2.0 of the driver._
245
+
244
246
  Each database has an optional strict mode. If strict mode is on, then asking
245
247
  for a collection that does not exist will raise an error, as will asking to
246
248
  create a collection that already exists. Note that both these operations are
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.8.4
1
+ 1.8.5
@@ -6,17 +6,19 @@ module Mongo
6
6
  GEOHAYSTACK = 'geoHaystack'
7
7
  TEXT = 'text'
8
8
  HASHED = 'hashed'
9
- INDEX_TYPES = [ ASCENDING,
10
- DESCENDING,
11
- GEO2D,
12
- GEO2DSPHERE,
13
- GEOHAYSTACK,
14
- TEXT,
15
- HASHED
16
- ]
9
+
10
+ INDEX_TYPES = {
11
+ 'ASCENDING' => ASCENDING,
12
+ 'DESCENDING' => DESCENDING,
13
+ 'GEO2D' => GEO2D,
14
+ 'GEO2DSPHERE' => GEO2DSPHERE,
15
+ 'GEOHAYSTACK' => GEOHAYSTACK,
16
+ 'TEXT' => TEXT,
17
+ 'HASHED' => HASHED
18
+ }
17
19
 
18
20
  DEFAULT_MAX_BSON_SIZE = 4 * 1024 * 1024
19
- DEFAULT_MAX_MESSAGE_SIZE = DEFAULT_MAX_BSON_SIZE * 2
21
+ MESSAGE_SIZE_FACTOR = 2
20
22
 
21
23
  module Constants
22
24
  OP_REPLY = 1
@@ -505,12 +505,15 @@ module Mongo
505
505
  # @option opts [Integer] :min (nil) specify the minimum longitude and latitude for a geo index.
506
506
  # @option opts [Integer] :max (nil) specify the maximum longitude and latitude for a geo index.
507
507
  #
508
- # @example Creating a compound index using a hash: (Ruby 1.9 and above)
508
+ # @example Creating a compound index using a hash: (Ruby 1.9+ Syntax)
509
509
  # @posts.create_index({'subject' => Mongo::ASCENDING, 'created_at' => Mongo::DESCENDING})
510
510
  #
511
511
  # @example Creating a compound index:
512
512
  # @posts.create_index([['subject', Mongo::ASCENDING], ['created_at', Mongo::DESCENDING]])
513
513
  #
514
+ # @example Creating a geospatial index using a hash: (Ruby 1.9+ Syntax)
515
+ # @restaurants.create_index(:location => Mongo::GEO2D)
516
+ #
514
517
  # @example Creating a geospatial index:
515
518
  # @restaurants.create_index([['location', Mongo::GEO2D]])
516
519
  #
@@ -542,13 +545,13 @@ module Mongo
542
545
  #
543
546
  # The parameters and options for this methods are the same as those for Collection#create_index.
544
547
  #
545
- # @example Call sequence:
546
- # Time t: @posts.ensure_index([['subject', Mongo::ASCENDING]) -- calls create_index and
548
+ # @example Call sequence (Ruby 1.9+ Syntax):
549
+ # Time t: @posts.ensure_index(:subject => Mongo::ASCENDING) -- calls create_index and
547
550
  # sets the 5 minute cache
548
- # Time t+2min : @posts.ensure_index([['subject', Mongo::ASCENDING]) -- doesn't do anything
549
- # Time t+3min : @posts.ensure_index([['something_else', Mongo::ASCENDING]) -- calls create_index
551
+ # Time t+2min : @posts.ensure_index(:subject => Mongo::ASCENDING) -- doesn't do anything
552
+ # Time t+3min : @posts.ensure_index(:something_else => Mongo::ASCENDING) -- calls create_index
550
553
  # and sets 5 minute cache
551
- # Time t+10min : @posts.ensure_index([['subject', Mongo::ASCENDING]) -- calls create_index and
554
+ # Time t+10min : @posts.ensure_index(:subject => Mongo::ASCENDING) -- calls create_index and
552
555
  # resets the 5 minute counter
553
556
  #
554
557
  # @return [String] the name of the index.
@@ -1013,21 +1016,15 @@ module Mongo
1013
1016
  if spec.is_a?(String) || spec.is_a?(Symbol)
1014
1017
  field_spec[spec.to_s] = 1
1015
1018
  elsif spec.is_a?(Hash)
1016
- if RUBY_VERSION < '1.9' && !spec.is_a?(BSON::OrderedHash)
1017
- raise MongoArgumentError, "Must use OrderedHash in Ruby < 1.9.0"
1018
- else
1019
- field_spec = spec.is_a?(BSON::OrderedHash) ? spec : BSON::OrderedHash.try_convert(spec)
1020
- end
1019
+ if RUBY_VERSION < '1.9' && !spec.is_a?(BSON::OrderedHash)
1020
+ raise MongoArgumentError, "Must use OrderedHash in Ruby < 1.9.0"
1021
+ end
1022
+ validate_index_types(spec.values)
1023
+ field_spec = spec.is_a?(BSON::OrderedHash) ? spec : BSON::OrderedHash.try_convert(spec)
1021
1024
  elsif spec.is_a?(Array) && spec.all? {|field| field.is_a?(Array) }
1022
1025
  spec.each do |f|
1023
- if Mongo::INDEX_TYPES.include?(f[1])
1024
- field_spec[f[0].to_s] = f[1]
1025
- else
1026
- raise MongoArgumentError, "Invalid index field #{f[1].inspect}; " +
1027
- "should be one of Mongo::ASCENDING (#{Mongo::ASCENDING}), Mongo::DESCENDING (#{Mongo::DESCENDING}), " +
1028
- "Mongo::GEOHAYSTACK ('#{Mongo::GEOHAYSTACK}'), Mongo::GEO2DSPHERE ('#{Mongo::GEO2DSPHERE}'), " +
1029
- "Mongo::TEXT ('#{Mongo::TEXT}'), or Mongo::HASHED ('#{Mongo::HASHED}')"
1030
- end
1026
+ validate_index_types(f[1])
1027
+ field_spec[f[0].to_s] = f[1]
1031
1028
  end
1032
1029
  else
1033
1030
  raise MongoArgumentError, "Invalid index specification #{spec.inspect}; " +
@@ -1036,6 +1033,16 @@ module Mongo
1036
1033
  field_spec
1037
1034
  end
1038
1035
 
1036
+ def validate_index_types(*types)
1037
+ types.flatten!
1038
+ types.each do |t|
1039
+ unless Mongo::INDEX_TYPES.values.include?(t)
1040
+ raise MongoArgumentError, "Invalid index field #{t.inspect}; " +
1041
+ "should be one of " + Mongo::INDEX_TYPES.map {|k,v| "Mongo::#{k} (#{v})"}.join(', ')
1042
+ end
1043
+ end
1044
+ end
1045
+
1039
1046
  def generate_indexes(field_spec, name, opts)
1040
1047
  selector = {
1041
1048
  :name => name,
@@ -472,6 +472,7 @@ module Mongo
472
472
  nil, @options & OP_QUERY_EXHAUST != 0)
473
473
  rescue ConnectionFailure => ex
474
474
  socket.close if socket
475
+ @pool = nil
475
476
  @connection.unpin_pool
476
477
  @connection.refresh
477
478
  if tries < 3 && !@socket && (!@command || Mongo::Support::secondary_ok?(@selector))
@@ -584,16 +585,20 @@ module Mongo
584
585
  spec['$returnKey'] = true if @return_key
585
586
  spec['$showDiskLoc'] = true if @show_disk_loc
586
587
  spec['$comment'] = @comment if @comment
587
- if @connection.mongos? && @read != :primary
588
+ if needs_read_pref?
588
589
  read_pref = Mongo::ReadPreference::mongos(@read, @tag_sets)
589
590
  spec['$readPreference'] = read_pref if read_pref
590
591
  end
591
592
  spec
592
593
  end
593
594
 
595
+ def needs_read_pref?
596
+ @connection.mongos? && @read != :primary
597
+ end
598
+
594
599
  def query_contains_special_fields?
595
600
  @order || @explain || @hint || @snapshot || @show_disk_loc ||
596
- @max_scan || @return_key || @comment || @connection.mongos?
601
+ @max_scan || @return_key || @comment || needs_read_pref?
597
602
  end
598
603
 
599
604
  def close_cursor_if_query_complete
@@ -123,7 +123,7 @@ module Mongo
123
123
  end
124
124
 
125
125
  begin
126
- socket = @connection.checkout_reader(:primary_preferred)
126
+ socket = @connection.checkout_reader(:mode => :primary_preferred)
127
127
  issue_authentication(username, password, save_auth, :socket => socket)
128
128
  ensure
129
129
  socket.checkin if socket
@@ -520,7 +520,7 @@ module Mongo
520
520
  end
521
521
 
522
522
  def max_message_size
523
- @max_message_size || DEFAULT_MAX_MESSAGE_SIZE
523
+ @max_message_size || max_bson_size * MESSAGE_SIZE_FACTOR
524
524
  end
525
525
 
526
526
  # Checkout a socket for reading (i.e., a secondary node).
@@ -105,8 +105,7 @@ module Mongo
105
105
  warn "Please specify hosts as an array of 'host:port' strings; the old format will be removed in v2.0"
106
106
  node
107
107
  elsif node.is_a?(String)
108
- host, port = node.split(":")
109
- [ host, port.to_i ]
108
+ Support.normalize_seeds(node)
110
109
  else
111
110
  raise MongoArgumentError "Bad seed format!"
112
111
  end
@@ -432,7 +431,7 @@ module Mongo
432
431
 
433
432
  def max_message_size
434
433
  return local_manager.max_message_size if local_manager
435
- DEFAULT_MAX_MESSAGE_SIZE
434
+ max_bson_size * MESSAGE_SIZE_FACTOR
436
435
  end
437
436
 
438
437
  private
@@ -25,8 +25,7 @@ module Mongo
25
25
  end
26
26
 
27
27
  @seeds = nodes.map do |host_port|
28
- host, port = host_port.split(":")
29
- [ host, port.to_i ]
28
+ Support.normalize_seeds(host_port)
30
29
  end
31
30
 
32
31
  # TODO: add a method for replacing this list of node.
@@ -5,7 +5,8 @@ module Mongo
5
5
 
6
6
  def initialize(client, host_port)
7
7
  @client = client
8
- @host, @port = split_node(host_port)
8
+ @manager = @client.local_manager
9
+ @host, @port = Support.normalize_seeds(host_port)
9
10
  @address = "#{@host}:#{@port}"
10
11
  @config = nil
11
12
  @socket = nil
@@ -19,7 +20,7 @@ module Mongo
19
20
 
20
21
  def =~(other)
21
22
  if other.is_a?(String)
22
- h, p = split_node(other)
23
+ h, p = Support.normalize_seeds(other)
23
24
  h == @host && p == @port
24
25
  else
25
26
  false
@@ -105,6 +106,7 @@ module Mongo
105
106
  close
106
107
  end
107
108
  end
109
+ @manager.update_max_sizes
108
110
  end
109
111
 
110
112
  # Return a list of replica set nodes from the config.
@@ -119,9 +121,8 @@ module Mongo
119
121
 
120
122
  def arbiters
121
123
  return [] unless config['arbiters']
122
-
123
124
  config['arbiters'].map do |arbiter|
124
- split_node(arbiter)
125
+ Support.normalize_seeds(arbiter)
125
126
  end
126
127
  end
127
128
 
@@ -149,19 +150,16 @@ module Mongo
149
150
  connected? && config
150
151
  end
151
152
 
152
- protected
153
-
154
- def split_node(host_port)
155
- if host_port.is_a?(String)
156
- host_port = host_port.split(":")
157
- end
158
-
159
- host = host_port[0]
160
- port = host_port[1].nil? ? MongoClient::DEFAULT_PORT : host_port[1].to_i
153
+ def max_bson_size
154
+ max = config['maxBsonObjectSize'] || DEFAULT_MAX_BSON_SIZE
155
+ end
161
156
 
162
- [host, port]
157
+ def max_message_size
158
+ max = config['maxMessageSizeBytes'] || max_bson_size * MESSAGE_SIZE_FACTOR
163
159
  end
164
160
 
161
+ protected
162
+
165
163
  # Ensure that this node is a healthy member of a replica set.
166
164
  def check_set_membership(config)
167
165
  if !config.has_key?('hosts')
@@ -165,8 +165,8 @@ module Mongo
165
165
  socket.pool = self
166
166
  rescue => ex
167
167
  socket.close if socket
168
- raise ConnectionFailure, "Failed to connect to host #{@host} and port #{@port}: #{ex}"
169
168
  @node.close if @node
169
+ raise ConnectionFailure, "Failed to connect to host #{@host} and port #{@port}: #{ex}"
170
170
  end
171
171
 
172
172
  # If any saved authentications exist, we want to apply those
@@ -12,7 +12,9 @@ module Mongo
12
12
  :nodes,
13
13
  :members,
14
14
  :seeds,
15
- :pools
15
+ :pools,
16
+ :max_bson_size,
17
+ :max_message_size
16
18
 
17
19
  # Create a new set of connection pools.
18
20
  #
@@ -33,6 +35,8 @@ module Mongo
33
35
  @hosts = Set.new
34
36
  @members = Set.new
35
37
  @refresh_required = false
38
+ @max_bson_size = DEFAULT_MAX_BSON_SIZE
39
+ @max_message_size = @max_bson_size * MESSAGE_SIZE_FACTOR
36
40
  end
37
41
 
38
42
  def inspect
@@ -44,7 +48,7 @@ module Mongo
44
48
  disconnect_old_members
45
49
  connect_to_members
46
50
  initialize_pools(@members)
47
- cache_discovered_seeds
51
+ @seeds = discovered_seeds
48
52
  end
49
53
 
50
54
  def refresh!(additional_seeds)
@@ -113,12 +117,11 @@ module Mongo
113
117
  read_pool.host_port
114
118
  end
115
119
 
116
- def max_bson_size
117
- @max_bson_size ||= config_min('maxBsonObjectSize', DEFAULT_MAX_BSON_SIZE)
118
- end
119
-
120
- def max_message_size
121
- @max_message_size ||= config_min('maxMessageSizeBytes', DEFAULT_MAX_MESSAGE_SIZE)
120
+ def update_max_sizes
121
+ unless @members.size == 0
122
+ @max_bson_size = @members.map(&:max_bson_size).min
123
+ @max_message_size = @members.map(&:max_message_size).min
124
+ end
122
125
  end
123
126
 
124
127
  private
@@ -192,11 +195,6 @@ module Mongo
192
195
  @arbiters = members.first.arbiters
193
196
  end
194
197
 
195
- def config_min(attribute, default)
196
- @members.reject {|m| !m.config[attribute]}
197
- @members.map {|m| m.config[attribute]}.min || default
198
- end
199
-
200
198
  def assign_primary(member)
201
199
  member.last_state = :primary
202
200
  @primary = member.host_port
@@ -246,8 +244,8 @@ module Mongo
246
244
 
247
245
  private
248
246
 
249
- def cache_discovered_seeds
250
- @seeds = @members.map &:host_port
247
+ def discovered_seeds
248
+ @members.map(&:host_port)
251
249
  end
252
250
 
253
251
  end
@@ -16,6 +16,7 @@ module Mongo
16
16
  disconnect_old_members
17
17
  connect_to_members
18
18
  initialize_pools best(@members)
19
+ @seeds = discovered_seeds
19
20
  end
20
21
 
21
22
  # We want to refresh to the member with the fastest ping time
@@ -25,8 +26,10 @@ module Mongo
25
26
  # The config.mongos find can't be part of the connect call chain due to infinite recursion
26
27
  def check_connection_health
27
28
  begin
28
- seeds = @client['config']['mongos'].find.to_a.map{|doc| doc['_id']}
29
- if @seeds != seeds
29
+ seeds = @client['config']['mongos'].find.map do |mongos|
30
+ Support.normalize_seeds(mongos['_id'])
31
+ end
32
+ if discovered_seeds != seeds
30
33
  @seeds = seeds
31
34
  @refresh_required = true
32
35
  end
@@ -82,6 +82,20 @@ module Mongo
82
82
  end
83
83
  end
84
84
 
85
+ def normalize_seeds(seeds)
86
+ pairs = Array(seeds)
87
+ pairs = [ seeds ] if pairs.last.is_a?(Fixnum)
88
+ pairs = pairs.collect do |hostport|
89
+ if hostport.is_a?(String)
90
+ host, port = hostport.split(':')
91
+ [ host, port && port.to_i || MongoClient::DEFAULT_PORT ]
92
+ else
93
+ hostport
94
+ end
95
+ end
96
+ pairs.length > 1 ? pairs : pairs.first
97
+ end
98
+
85
99
  def is_i?(value)
86
100
  return !!(value =~ /^\d+$/)
87
101
  end
@@ -11,14 +11,18 @@ Gem::Specification.new do |s|
11
11
  s.rubyforge_project = 'mongo'
12
12
  s.license = 'Apache License Version 2.0'
13
13
 
14
- s.signing_key = 'gem-private_key.pem'
15
- s.cert_chain = ['gem-public_cert.pem']
14
+ if File.exists?('gem-private_key.pem')
15
+ s.signing_key = 'gem-private_key.pem'
16
+ s.cert_chain = ['gem-public_cert.pem']
17
+ else
18
+ warn 'Warning: No private key present, creating unsigned gem.'
19
+ end
16
20
 
17
21
  s.files = ['mongo.gemspec', 'LICENSE', 'VERSION']
18
22
  s.files += ['README.md', 'Rakefile', 'bin/mongo_console']
19
23
  s.files += ['lib/mongo.rb'] + Dir['lib/mongo/**/*.rb']
20
24
 
21
- s.test_files = Dir['test/**/*.rb']
25
+ s.test_files = Dir['test/**/*.rb'] - Dir['test/bson/*']
22
26
  s.executables = ['mongo_console']
23
27
  s.require_paths = ['lib']
24
28
  s.has_rdoc = 'yard'
@@ -0,0 +1,21 @@
1
+ require 'test_helper'
2
+ require 'shared/authentication'
3
+
4
+ class AuthenticationTest < Test::Unit::TestCase
5
+ include Mongo
6
+ include AuthenticationTests
7
+
8
+ def setup
9
+ @client = MongoClient.new
10
+ @db = @client[MONGO_TEST_DB]
11
+ end
12
+
13
+ def teardown
14
+ @db['system.users'].remove
15
+ end
16
+
17
+ def test_authenticate_with_connection_uri
18
+ @db.add_user('eunice', 'uritest')
19
+ assert MongoClient.from_uri("mongodb://eunice:uritest@#{host_port}/#{@db.name}")
20
+ end
21
+ end