mongo 2.0.2 → 2.0.3

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 (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