mongo 2.0.2 → 2.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/lib/mongo/address.rb +70 -11
  5. data/lib/mongo/address/ipv4.rb +23 -22
  6. data/lib/mongo/address/ipv6.rb +23 -22
  7. data/lib/mongo/address/unix.rb +18 -18
  8. data/lib/mongo/auth.rb +0 -1
  9. data/lib/mongo/auth/cr.rb +21 -2
  10. data/lib/mongo/auth/cr/conversation.rb +7 -4
  11. data/lib/mongo/auth/ldap.rb +14 -1
  12. data/lib/mongo/auth/scram.rb +15 -1
  13. data/lib/mongo/auth/scram/conversation.rb +3 -3
  14. data/lib/mongo/auth/user.rb +1 -1
  15. data/lib/mongo/auth/x509.rb +15 -1
  16. data/lib/mongo/cluster.rb +22 -8
  17. data/lib/mongo/cluster/topology.rb +7 -6
  18. data/lib/mongo/cluster/topology/replica_set.rb +5 -5
  19. data/lib/mongo/cluster/topology/sharded.rb +5 -5
  20. data/lib/mongo/cluster/topology/{standalone.rb → single.rb} +26 -22
  21. data/lib/mongo/cluster/topology/unknown.rb +6 -5
  22. data/lib/mongo/collection.rb +6 -1
  23. data/lib/mongo/collection/view.rb +1 -0
  24. data/lib/mongo/collection/view/readable.rb +5 -0
  25. data/lib/mongo/error.rb +4 -0
  26. data/lib/mongo/error/invalid_document.rb +1 -1
  27. data/lib/mongo/error/invalid_server_preference.rb +36 -0
  28. data/lib/mongo/error/invalid_uri.rb +37 -0
  29. data/lib/mongo/error/invalid_uri_option.rb +38 -0
  30. data/lib/mongo/error/no_server_available.rb +37 -0
  31. data/lib/mongo/operation/read_preferrable.rb +20 -4
  32. data/lib/mongo/protocol/query.rb +14 -1
  33. data/lib/mongo/server.rb +12 -0
  34. data/lib/mongo/server/connectable.rb +5 -1
  35. data/lib/mongo/server/connection.rb +1 -1
  36. data/lib/mongo/server/context.rb +2 -1
  37. data/lib/mongo/server_selector.rb +0 -19
  38. data/lib/mongo/server_selector/selectable.rb +4 -22
  39. data/lib/mongo/uri.rb +9 -55
  40. data/lib/mongo/version.rb +1 -1
  41. data/spec/mongo/address/ipv4_spec.rb +27 -6
  42. data/spec/mongo/address/ipv6_spec.rb +27 -6
  43. data/spec/mongo/address/unix_spec.rb +15 -4
  44. data/spec/mongo/auth/cr_spec.rb +2 -2
  45. data/spec/mongo/auth/ldap_spec.rb +2 -2
  46. data/spec/mongo/auth/scram_spec.rb +2 -2
  47. data/spec/mongo/auth/x509_spec.rb +2 -2
  48. data/spec/mongo/client_spec.rb +8 -0
  49. data/spec/mongo/cluster/topology/replica_set_spec.rb +6 -6
  50. data/spec/mongo/cluster/topology/sharded_spec.rb +5 -5
  51. data/spec/mongo/cluster/topology/{standalone_spec.rb → single_spec.rb} +7 -7
  52. data/spec/mongo/cluster/topology_spec.rb +31 -5
  53. data/spec/mongo/cluster_spec.rb +103 -21
  54. data/spec/mongo/collection/view/readable_spec.rb +18 -7
  55. data/spec/mongo/collection/view_spec.rb +13 -0
  56. data/spec/mongo/collection_spec.rb +7 -0
  57. data/spec/mongo/database_spec.rb +2 -2
  58. data/spec/mongo/protocol/query_spec.rb +29 -0
  59. data/spec/mongo/server/connection_pool_spec.rb +4 -4
  60. data/spec/mongo/server/connection_spec.rb +46 -10
  61. data/spec/mongo/server/monitor_spec.rb +2 -2
  62. data/spec/mongo/server_discovery_and_monitoring_spec.rb +23 -0
  63. data/spec/mongo/server_selection_rtt_spec.rb +2 -1
  64. data/spec/mongo/server_selection_spec.rb +6 -15
  65. data/spec/mongo/server_selector/nearest_spec.rb +1 -1
  66. data/spec/mongo/server_selector_spec.rb +53 -2
  67. data/spec/mongo/server_spec.rb +9 -9
  68. data/spec/mongo/socket/ssl_spec.rb +1 -1
  69. data/spec/mongo/uri_spec.rb +2 -2
  70. data/spec/spec_helper.rb +34 -5
  71. data/spec/support/authorization.rb +32 -46
  72. data/spec/support/server_discovery_and_monitoring.rb +1 -1
  73. data/spec/support/server_selection.rb +1 -25
  74. data/spec/support/shared/operation.rb +3 -0
  75. data/spec/support/shared/server_selector.rb +1 -1
  76. metadata +10 -7
  77. metadata.gz.sig +0 -0
  78. data/lib/mongo/auth/executable.rb +0 -52
data/lib/mongo/error.rb CHANGED
@@ -71,12 +71,16 @@ require 'mongo/error/invalid_document'
71
71
  require 'mongo/error/invalid_file'
72
72
  require 'mongo/error/invalid_nonce'
73
73
  require 'mongo/error/invalid_replacement_document'
74
+ require 'mongo/error/invalid_server_preference'
74
75
  require 'mongo/error/invalid_signature'
75
76
  require 'mongo/error/invalid_update_document'
77
+ require 'mongo/error/invalid_uri'
78
+ require 'mongo/error/invalid_uri_option'
76
79
  require 'mongo/error/max_bson_size'
77
80
  require 'mongo/error/max_message_size'
78
81
  require 'mongo/error/multi_index_drop'
79
82
  require 'mongo/error/need_primary_server'
83
+ require 'mongo/error/no_server_available'
80
84
  require 'mongo/error/socket_error'
81
85
  require 'mongo/error/socket_timeout_error'
82
86
  require 'mongo/error/unsupported_features'
@@ -23,7 +23,7 @@ module Mongo
23
23
  # The error message.
24
24
  #
25
25
  # @since 2.0.0
26
- MESSAGE = 'Invalid document provided'.freeze
26
+ MESSAGE = 'Invalid document provided.'.freeze
27
27
 
28
28
  # Instantiate the new exception.
29
29
  #
@@ -0,0 +1,36 @@
1
+ # Copyright (C) 2014-2015 MongoDB, Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ module Mongo
16
+ class Error
17
+
18
+ # Raised when an invalid server preference is provided.
19
+ #
20
+ # @since 2.0.0
21
+ class InvalidServerPreference < Error
22
+
23
+ # Instantiate the new exception.
24
+ #
25
+ # @example Instantiate the exception.
26
+ # Mongo::ServerSelector::InvalidServerPreference.new
27
+ #
28
+ # @param [ String ] name The preference name.
29
+ #
30
+ # @since 2.0.0
31
+ def initialize(name)
32
+ super("This server preference #{name} cannot be combined with tags.")
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,37 @@
1
+ # Copyright (C) 2014-2015 MongoDB, Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ module Mongo
16
+ class Error
17
+
18
+ # Exception that is raised when trying to parse a URI that does not match
19
+ # the specification.
20
+ #
21
+ # @since 2.0.0
22
+ class InvalidURI < Error
23
+
24
+ # Instantiate the new exception.
25
+ #
26
+ # @example Instantiate the exception.
27
+ # Mongo::Error::InvalidURI.new(uri)
28
+ #
29
+ # @since 2.0.0
30
+ def initialize(uri)
31
+ super("MongoDB URI must be in the following format: #{Mongo::URI::FORMAT}\n" +
32
+ "Please see the following URL for more information: #{Mongo::URI::HELP}\n" +
33
+ "Bad URI: #{uri}")
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,38 @@
1
+ # Copyright (C) 2014-2015 MongoDB, Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ module Mongo
16
+ class Error
17
+
18
+ # Raised if the URI is in the correct format but an option is provided that
19
+ # is not recognized.
20
+ #
21
+ # @since 2.0.0
22
+ class InvalidURIOption < Error
23
+
24
+ # Create the error.
25
+ #
26
+ # @example Create the error with the invalid option name.
27
+ # InvalidURIOption.new('nothing')
28
+ #
29
+ # @param [ String ] name The invalid option name.
30
+ #
31
+ # @since 2.0.0
32
+ def initialize(name)
33
+ super("Invalid option in URI: '#{name}'.\n" +
34
+ "Please see the following URL for more information: #{Mongo::URI::HELP}\n")
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,37 @@
1
+ # Copyright (C) 2014-2015 MongoDB, Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ module Mongo
16
+ class Error
17
+
18
+ # Raised if there are no servers available matching the preference.
19
+ #
20
+ # @since 2.0.0
21
+ class NoServerAvailable < Error
22
+
23
+ # Instantiate the new exception.
24
+ #
25
+ # @example Instantiate the exception.
26
+ # Mongo::Error::NoServerAvailable.new(server_selector)
27
+ #
28
+ # @param [ Hash ] server_selector The server preference that could not be
29
+ # satisfied.
30
+ #
31
+ # @since 2.0.0
32
+ def initialize(server_selector)
33
+ super("No server is available matching preference: #{server_selector.inspect}")
34
+ end
35
+ end
36
+ end
37
+ end
@@ -22,11 +22,27 @@ module Mongo
22
22
 
23
23
  private
24
24
 
25
+ def update_selector(context)
26
+ if context.mongos? && read_pref = read.to_mongos
27
+ selector.merge(:$readPreference => read_pref)
28
+ else
29
+ selector
30
+ end
31
+ end
32
+
33
+ def update_options(context)
34
+ if context.slave_ok?
35
+ options.merge(flags: [:slave_ok])
36
+ elsif !context.mongos? && read.slave_ok?
37
+ options.merge(flags: [:slave_ok])
38
+ else
39
+ options
40
+ end
41
+ end
42
+
25
43
  def message(context)
26
- sel = (context.mongos? && read_pref = read.to_mongos) ?
27
- selector.merge(:$readPreference => read_pref) : selector
28
- opts = context.standalone? || read.slave_ok? ?
29
- options.merge(flags: [:slave_ok]) : options
44
+ sel = update_selector(context)
45
+ opts = update_options(context)
30
46
  Protocol::Query.new(db_name, query_coll, sel, opts)
31
47
  end
32
48
  end
@@ -30,6 +30,12 @@ module Mongo
30
30
  # @api semipublic
31
31
  class Query < Message
32
32
 
33
+ # Constant for the max number of characters to print when inspecting
34
+ # a query field.
35
+ #
36
+ # @since 2.0.3
37
+ LOG_STRING_LIMIT = 250
38
+
33
39
  # Creates a new Query message
34
40
  #
35
41
  # @example Find all users named Tyler.
@@ -78,7 +84,7 @@ module Mongo
78
84
  fields = []
79
85
  fields << ["%s |", query_type]
80
86
  fields << ["namespace=%s", namespace]
81
- fields << ["selector=%s", selector.inspect]
87
+ fields << ["selector=%s", formatted_selector]
82
88
  fields << ["flags=%s", flags.inspect]
83
89
  fields << ["limit=%s", limit.inspect]
84
90
  fields << ["skip=%s", skip.inspect]
@@ -111,6 +117,13 @@ module Mongo
111
117
  namespace.include?(Database::COMMAND) ? 'COMMAND' : 'QUERY'
112
118
  end
113
119
 
120
+ def formatted_selector
121
+ ( (str = selector.inspect).length > LOG_STRING_LIMIT ) ?
122
+ "#{str[0..LOG_STRING_LIMIT]}..." : str
123
+ rescue ArgumentError
124
+ '<Unable to inspect selector>'
125
+ end
126
+
114
127
  # Available flags for a Query message.
115
128
  FLAGS = [
116
129
  :reserved,
data/lib/mongo/server.rb CHANGED
@@ -159,5 +159,17 @@ module Mongo
159
159
  tags[k] && tags[k] == tag_set[k]
160
160
  end
161
161
  end
162
+
163
+ # Whether the slaveOk bit must be set for all queries sent to the server.
164
+ #
165
+ # @example Does the slaveOk bit need to be set for all queries sent to the server.
166
+ # server.slave_ok?
167
+ #
168
+ # @return [ true, false ] If the slaveOk bit needs to be set for all queries.
169
+ #
170
+ # @since 2.0.0
171
+ def slave_ok?
172
+ options[:slave_ok]
173
+ end
162
174
  end
163
175
  end
@@ -82,7 +82,11 @@ module Mongo
82
82
 
83
83
  private
84
84
 
85
- attr_reader :socket, :ssl_options
85
+ attr_reader :socket
86
+
87
+ def ssl_options
88
+ @ssl_options[:ssl] == true ? @ssl_options : {}
89
+ end
86
90
 
87
91
  def ensure_connected
88
92
  ensure_same_process!
@@ -22,7 +22,7 @@ module Mongo
22
22
  include Connectable
23
23
  extend Forwardable
24
24
 
25
- # @return [ Mongo::Auth::CR, Mongo::Auth::X509, Mongo::Auth:LDAP ]
25
+ # @return [ Mongo::Auth::CR, Mongo::Auth::X509, Mongo::Auth:LDAP, Mongo::Auth::SCRAM ]
26
26
  # authenticator The authentication strategy.
27
27
  attr_reader :authenticator
28
28
 
@@ -33,7 +33,8 @@ module Mongo
33
33
  :mongos?,
34
34
  :primary?,
35
35
  :secondary?,
36
- :standalone?
36
+ :standalone?,
37
+ :slave_ok?
37
38
 
38
39
  # Instantiate a server context.
39
40
  #
@@ -58,24 +58,5 @@ module Mongo
58
58
  options
59
59
  )
60
60
  end
61
-
62
- # Exception raised if there are no servers available matching the preference.
63
- #
64
- # @since 2.0.0
65
- class NoServerAvailable < Error
66
-
67
- # Instantiate the new exception.
68
- #
69
- # @example Instantiate the exception.
70
- # Mongo::ServerSelector::NoServerAvailable.new(server_selector)
71
- #
72
- # @param [ Hash ] server_selector The server preference that could not be
73
- # satisfied.
74
- #
75
- # @since 2.0.0
76
- def initialize(server_selector)
77
- super("No server is available matching preference: #{server_selector.inspect}")
78
- end
79
- end
80
61
  end
81
62
  end
@@ -67,7 +67,7 @@ module Mongo
67
67
  # @since 2.0.0
68
68
  def initialize(tag_sets = [], options = {})
69
69
  if !tag_sets.all? { |set| set.empty? } && !tags_allowed?
70
- raise ServerSelector::InvalidServerPreference.new(name)
70
+ raise Error::InvalidServerPreference.new(name)
71
71
  end
72
72
  @tag_sets = tag_sets
73
73
  @options = options
@@ -86,7 +86,7 @@ module Mongo
86
86
  def select_server(cluster)
87
87
  deadline = Time.now + server_selection_timeout
88
88
  while (deadline - Time.now) > 0
89
- if cluster.standalone?
89
+ if cluster.single?
90
90
  servers = cluster.servers
91
91
  elsif cluster.sharded?
92
92
  servers = near_servers(cluster.servers)
@@ -96,7 +96,7 @@ module Mongo
96
96
  return servers.first if servers && !servers.compact.empty?
97
97
  cluster.scan!
98
98
  end
99
- raise NoServerAvailable.new(self)
99
+ raise Error::NoServerAvailable.new(self)
100
100
  end
101
101
 
102
102
  # Get the timeout for server selection.
@@ -136,7 +136,7 @@ module Mongo
136
136
  # @since 2.0.0
137
137
  def primary(candidates)
138
138
  candidates.select do |server|
139
- server.primary? || server.standalone?
139
+ server.primary?
140
140
  end
141
141
  end
142
142
 
@@ -187,23 +187,5 @@ module Mongo
187
187
  matches || []
188
188
  end
189
189
  end
190
-
191
- # Raised when an invalid server preference is provided.
192
- #
193
- # @since 2.0.0
194
- class InvalidServerPreference < Error
195
-
196
- # Instantiate the new exception.
197
- #
198
- # @example Instantiate the exception.
199
- # Mongo::ServerSelector::InvalidServerPreference.new
200
- #
201
- # @param [ String ] name The preference name.
202
- #
203
- # @since 2.0.0
204
- def initialize(name)
205
- super("This server preference #{name} cannot be combined with tags.")
206
- end
207
- end
208
190
  end
209
191
  end
data/lib/mongo/uri.rb CHANGED
@@ -80,6 +80,13 @@ module Mongo
80
80
  # @since 2.0.0
81
81
  URI = /#{SCHEME}#{CREDENTIALS}#{SERVERS}#{DATABASE}#{OPTIONS}/.freeze
82
82
 
83
+
84
+ # MongoDB URI format specification.
85
+ #
86
+ # @since 2.0.0
87
+ FORMAT = 'mongodb://[username:password@]host1[:port1][,host2[:port2]' +
88
+ ',...[,hostN[:portN]]][/[database][?options]]'.freeze
89
+
83
90
  # MongoDB URI (connection string) documentation url
84
91
  #
85
92
  # @since 2.0.0
@@ -117,7 +124,7 @@ module Mongo
117
124
  # @since 2.0.0
118
125
  def initialize(string)
119
126
  @match = string.match(URI)
120
- raise Invalid.new(string) unless @match
127
+ raise Error::InvalidURI.new(string) unless @match
121
128
  end
122
129
 
123
130
  # Get the servers provided in the URI.
@@ -203,65 +210,12 @@ module Mongo
203
210
  parsed_options.split('&').reduce({}) do |options, option|
204
211
  key, value = option.split('=')
205
212
  strategy = OPTION_MAP[key]
206
- raise InvalidOption.new(key) if strategy.nil?
213
+ raise Error::InvalidURIOption.new(key) if strategy.nil?
207
214
  add_option(strategy, value, options)
208
215
  options
209
216
  end
210
217
  end
211
218
 
212
- # Exception that is raised when trying to parse a URI that does not match
213
- # the specification.
214
- #
215
- # @since 2.0.0
216
- class Invalid < RuntimeError
217
-
218
- # MongoDB URI format specification.
219
- #
220
- # @since 2.0.0
221
- FORMAT = 'mongodb://[username:password@]host1[:port1][,host2[:port2]' +
222
- ',...[,hostN[:portN]]][/[database][?options]]'.freeze
223
-
224
- # Creates a new instance of the BadURI error.
225
- #
226
- # @example Initialize the error.
227
- # BadURI.new(uri)
228
- #
229
- # @param [ String ] uri The bad URI.
230
- #
231
- # @since 2.0.0
232
- def initialize(uri)
233
- super(message(uri))
234
- end
235
-
236
- private
237
-
238
- def message(uri)
239
- "MongoDB URI must be in the following format: #{FORMAT}\n" +
240
- "Please see the following URL for more information: #{HELP}\n" +
241
- "Bad URI: #{uri}"
242
- end
243
- end
244
-
245
- # Raised if the URI is in the correct format but an option is provided that
246
- # is not recognized.
247
- #
248
- # @since 2.0.0
249
- class InvalidOption < RuntimeError
250
-
251
- # Create the error.
252
- #
253
- # @example Create the error with the invalid option name.
254
- # InvalidOption.new('nothing')
255
- #
256
- # @param [ String ] name The invalid option name.
257
- #
258
- # @since 2.0.0
259
- def initialize(name)
260
- super("Invalid option in URI: '#{name}'.\n" +
261
- "Please see the following URL for more information: #{HELP}\n")
262
- end
263
- end
264
-
265
219
  private
266
220
 
267
221
  # Hash for storing map of URI option parameters to conversion strategies