mongo 2.0.2 → 2.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/lib/mongo/address.rb +70 -11
- data/lib/mongo/address/ipv4.rb +23 -22
- data/lib/mongo/address/ipv6.rb +23 -22
- data/lib/mongo/address/unix.rb +18 -18
- data/lib/mongo/auth.rb +0 -1
- data/lib/mongo/auth/cr.rb +21 -2
- data/lib/mongo/auth/cr/conversation.rb +7 -4
- data/lib/mongo/auth/ldap.rb +14 -1
- data/lib/mongo/auth/scram.rb +15 -1
- data/lib/mongo/auth/scram/conversation.rb +3 -3
- data/lib/mongo/auth/user.rb +1 -1
- data/lib/mongo/auth/x509.rb +15 -1
- data/lib/mongo/cluster.rb +22 -8
- data/lib/mongo/cluster/topology.rb +7 -6
- data/lib/mongo/cluster/topology/replica_set.rb +5 -5
- data/lib/mongo/cluster/topology/sharded.rb +5 -5
- data/lib/mongo/cluster/topology/{standalone.rb → single.rb} +26 -22
- data/lib/mongo/cluster/topology/unknown.rb +6 -5
- data/lib/mongo/collection.rb +6 -1
- data/lib/mongo/collection/view.rb +1 -0
- data/lib/mongo/collection/view/readable.rb +5 -0
- data/lib/mongo/error.rb +4 -0
- data/lib/mongo/error/invalid_document.rb +1 -1
- data/lib/mongo/error/invalid_server_preference.rb +36 -0
- data/lib/mongo/error/invalid_uri.rb +37 -0
- data/lib/mongo/error/invalid_uri_option.rb +38 -0
- data/lib/mongo/error/no_server_available.rb +37 -0
- data/lib/mongo/operation/read_preferrable.rb +20 -4
- data/lib/mongo/protocol/query.rb +14 -1
- data/lib/mongo/server.rb +12 -0
- data/lib/mongo/server/connectable.rb +5 -1
- data/lib/mongo/server/connection.rb +1 -1
- data/lib/mongo/server/context.rb +2 -1
- data/lib/mongo/server_selector.rb +0 -19
- data/lib/mongo/server_selector/selectable.rb +4 -22
- data/lib/mongo/uri.rb +9 -55
- data/lib/mongo/version.rb +1 -1
- data/spec/mongo/address/ipv4_spec.rb +27 -6
- data/spec/mongo/address/ipv6_spec.rb +27 -6
- data/spec/mongo/address/unix_spec.rb +15 -4
- data/spec/mongo/auth/cr_spec.rb +2 -2
- data/spec/mongo/auth/ldap_spec.rb +2 -2
- data/spec/mongo/auth/scram_spec.rb +2 -2
- data/spec/mongo/auth/x509_spec.rb +2 -2
- data/spec/mongo/client_spec.rb +8 -0
- data/spec/mongo/cluster/topology/replica_set_spec.rb +6 -6
- data/spec/mongo/cluster/topology/sharded_spec.rb +5 -5
- data/spec/mongo/cluster/topology/{standalone_spec.rb → single_spec.rb} +7 -7
- data/spec/mongo/cluster/topology_spec.rb +31 -5
- data/spec/mongo/cluster_spec.rb +103 -21
- data/spec/mongo/collection/view/readable_spec.rb +18 -7
- data/spec/mongo/collection/view_spec.rb +13 -0
- data/spec/mongo/collection_spec.rb +7 -0
- data/spec/mongo/database_spec.rb +2 -2
- data/spec/mongo/protocol/query_spec.rb +29 -0
- data/spec/mongo/server/connection_pool_spec.rb +4 -4
- data/spec/mongo/server/connection_spec.rb +46 -10
- data/spec/mongo/server/monitor_spec.rb +2 -2
- data/spec/mongo/server_discovery_and_monitoring_spec.rb +23 -0
- data/spec/mongo/server_selection_rtt_spec.rb +2 -1
- data/spec/mongo/server_selection_spec.rb +6 -15
- data/spec/mongo/server_selector/nearest_spec.rb +1 -1
- data/spec/mongo/server_selector_spec.rb +53 -2
- data/spec/mongo/server_spec.rb +9 -9
- data/spec/mongo/socket/ssl_spec.rb +1 -1
- data/spec/mongo/uri_spec.rb +2 -2
- data/spec/spec_helper.rb +34 -5
- data/spec/support/authorization.rb +32 -46
- data/spec/support/server_discovery_and_monitoring.rb +1 -1
- data/spec/support/server_selection.rb +1 -25
- data/spec/support/shared/operation.rb +3 -0
- data/spec/support/shared/server_selector.rb +1 -1
- metadata +10 -7
- metadata.gz.sig +0 -0
- data/lib/mongo/auth/executable.rb +0 -52
@@ -111,7 +111,7 @@ module Mongo
|
|
111
111
|
def continue(reply)
|
112
112
|
validate_first_message!(reply)
|
113
113
|
Protocol::Query.new(
|
114
|
-
|
114
|
+
user.auth_source,
|
115
115
|
Database::COMMAND,
|
116
116
|
CLIENT_CONTINUE_MESSAGE.merge(payload: client_final_message, conversationId: id),
|
117
117
|
limit: -1
|
@@ -133,7 +133,7 @@ module Mongo
|
|
133
133
|
def finalize(reply)
|
134
134
|
validate_final_message!(reply)
|
135
135
|
Protocol::Query.new(
|
136
|
-
|
136
|
+
user.auth_source,
|
137
137
|
Database::COMMAND,
|
138
138
|
CLIENT_CONTINUE_MESSAGE.merge(payload: client_empty_message, conversationId: id),
|
139
139
|
limit: -1
|
@@ -151,7 +151,7 @@ module Mongo
|
|
151
151
|
# @since 2.0.0
|
152
152
|
def start
|
153
153
|
Protocol::Query.new(
|
154
|
-
|
154
|
+
user.auth_source,
|
155
155
|
Database::COMMAND,
|
156
156
|
CLIENT_FIRST_MESSAGE.merge(payload: client_first_message, mechanism: SCRAM::MECHANISM),
|
157
157
|
limit: -1
|
data/lib/mongo/auth/user.rb
CHANGED
@@ -134,8 +134,8 @@ module Mongo
|
|
134
134
|
#
|
135
135
|
# @since 2.0.0
|
136
136
|
def initialize(options)
|
137
|
-
@auth_source = options[:auth_source] || options[:database] || Database::ADMIN
|
138
137
|
@database = options[:database] || Database::ADMIN
|
138
|
+
@auth_source = options[:auth_source] || @database
|
139
139
|
@name = options[:user]
|
140
140
|
@password = options[:password] || options[:pwd]
|
141
141
|
@mechanism = options[:auth_mech] || :mongodb_cr
|
data/lib/mongo/auth/x509.rb
CHANGED
@@ -21,13 +21,27 @@ module Mongo
|
|
21
21
|
#
|
22
22
|
# @since 2.0.0
|
23
23
|
class X509
|
24
|
-
include Executable
|
25
24
|
|
26
25
|
# The authentication mechinism string.
|
27
26
|
#
|
28
27
|
# @since 2.0.0
|
29
28
|
MECHANISM = 'MONGODB-X509'.freeze
|
30
29
|
|
30
|
+
# @return [ Mongo::Auth::User ] The user to authenticate.
|
31
|
+
attr_reader :user
|
32
|
+
|
33
|
+
# Instantiate a new authenticator.
|
34
|
+
#
|
35
|
+
# @example Create the authenticator.
|
36
|
+
# Mongo::Auth::X509.new(user)
|
37
|
+
#
|
38
|
+
# @param [ Mongo::Auth::User ] user The user to authenticate.
|
39
|
+
#
|
40
|
+
# @since 2.0.0
|
41
|
+
def initialize(user)
|
42
|
+
@user = user
|
43
|
+
end
|
44
|
+
|
31
45
|
# Log the user in on the given connection.
|
32
46
|
#
|
33
47
|
# @example Log the user in.
|
data/lib/mongo/cluster.rb
CHANGED
@@ -34,7 +34,7 @@ module Mongo
|
|
34
34
|
# @return [ Object ] The cluster topology.
|
35
35
|
attr_reader :topology
|
36
36
|
|
37
|
-
def_delegators :topology, :replica_set?, :replica_set_name, :sharded?, :
|
37
|
+
def_delegators :topology, :replica_set?, :replica_set_name, :sharded?, :single?, :unknown?
|
38
38
|
|
39
39
|
# Determine if this cluster of servers is equal to another object. Checks the
|
40
40
|
# servers currently in the cluster, not what was configured.
|
@@ -66,12 +66,15 @@ module Mongo
|
|
66
66
|
# @since 2.0.0
|
67
67
|
def add(host)
|
68
68
|
address = Address.new(host)
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
69
|
+
if !addresses.include?(address)
|
70
|
+
if addition_allowed?(address)
|
71
|
+
log_debug([ "Adding #{address.to_s} to the cluster." ])
|
72
|
+
addresses.push(address)
|
73
|
+
server = Server.new(address, event_listeners,
|
74
|
+
options.merge(slave_ok: @slave_ok))
|
75
|
+
@servers.push(server)
|
76
|
+
server
|
77
|
+
end
|
75
78
|
end
|
76
79
|
end
|
77
80
|
|
@@ -90,6 +93,7 @@ module Mongo
|
|
90
93
|
@event_listeners = Event::Listeners.new
|
91
94
|
@options = options.freeze
|
92
95
|
@topology = Topology.initial(seeds, options)
|
96
|
+
@slave_ok = @topology.single? unless options[:read]
|
93
97
|
|
94
98
|
subscribe_to(Event::SERVER_ADDED, Event::ServerAdded.new(self))
|
95
99
|
subscribe_to(Event::SERVER_REMOVED, Event::ServerRemoved.new(self))
|
@@ -179,7 +183,7 @@ module Mongo
|
|
179
183
|
#
|
180
184
|
# @since 2.0.0
|
181
185
|
def servers
|
182
|
-
topology.servers(@servers)
|
186
|
+
topology.servers(@servers.compact).compact
|
183
187
|
end
|
184
188
|
|
185
189
|
# Create a cluster for the provided client, for use when we don't want the
|
@@ -199,5 +203,15 @@ module Mongo
|
|
199
203
|
cluster = Cluster.new(client.cluster.addresses.map(&:to_s), client.options)
|
200
204
|
client.instance_variable_set(:@cluster, cluster)
|
201
205
|
end
|
206
|
+
|
207
|
+
private
|
208
|
+
|
209
|
+
def direct_connection?(address)
|
210
|
+
address.seed == @topology.seed
|
211
|
+
end
|
212
|
+
|
213
|
+
def addition_allowed?(address)
|
214
|
+
!@topology.single? || direct_connection?(address)
|
215
|
+
end
|
202
216
|
end
|
203
217
|
end
|
@@ -14,7 +14,7 @@
|
|
14
14
|
|
15
15
|
require 'mongo/cluster/topology/replica_set'
|
16
16
|
require 'mongo/cluster/topology/sharded'
|
17
|
-
require 'mongo/cluster/topology/
|
17
|
+
require 'mongo/cluster/topology/single'
|
18
18
|
require 'mongo/cluster/topology/unknown'
|
19
19
|
|
20
20
|
module Mongo
|
@@ -32,7 +32,7 @@ module Mongo
|
|
32
32
|
OPTIONS = {
|
33
33
|
replica_set: ReplicaSet,
|
34
34
|
sharded: Sharded,
|
35
|
-
direct:
|
35
|
+
direct: Single
|
36
36
|
}
|
37
37
|
|
38
38
|
# Get the initial cluster topology for the provided options.
|
@@ -40,19 +40,20 @@ module Mongo
|
|
40
40
|
# @example Get the initial cluster topology.
|
41
41
|
# Topology.initial(topology: :replica_set)
|
42
42
|
#
|
43
|
+
# @param [ Array<String> ] seeds The addresses of the configured servers.
|
43
44
|
# @param [ Hash ] options The cluster options.
|
44
45
|
#
|
45
|
-
# @return [ ReplicaSet, Sharded,
|
46
|
+
# @return [ ReplicaSet, Sharded, Single ] The topology.
|
46
47
|
#
|
47
48
|
# @since 2.0.0
|
48
49
|
def initial(seeds, options)
|
49
50
|
if options.has_key?(:connect)
|
50
|
-
return OPTIONS.fetch(options[:connect]).new(options)
|
51
|
+
return OPTIONS.fetch(options[:connect]).new(options, seeds)
|
51
52
|
end
|
52
53
|
if options.has_key?(:replica_set)
|
53
|
-
ReplicaSet.new(options)
|
54
|
+
ReplicaSet.new(options, seeds)
|
54
55
|
else
|
55
|
-
seeds.size > 1 ? Unknown.new(options) :
|
56
|
+
seeds.size > 1 ? Unknown.new(options, seeds) : Single.new(options, seeds)
|
56
57
|
end
|
57
58
|
end
|
58
59
|
end
|
@@ -82,7 +82,7 @@ module Mongo
|
|
82
82
|
# @param [ Hash ] options The options.
|
83
83
|
#
|
84
84
|
# @since 2.0.0
|
85
|
-
def initialize(options)
|
85
|
+
def initialize(options, seeds = [])
|
86
86
|
@options = options
|
87
87
|
end
|
88
88
|
|
@@ -135,15 +135,15 @@ module Mongo
|
|
135
135
|
# @since 2.0.0
|
136
136
|
def sharded?; false; end
|
137
137
|
|
138
|
-
# A replica set topology is not
|
138
|
+
# A replica set topology is not single.
|
139
139
|
#
|
140
|
-
# @example Is the topology
|
141
|
-
# ReplicaSet.
|
140
|
+
# @example Is the topology single?
|
141
|
+
# ReplicaSet.single?
|
142
142
|
#
|
143
143
|
# @return [ false ] Always false.
|
144
144
|
#
|
145
145
|
# @since 2.0.0
|
146
|
-
def
|
146
|
+
def single?; false; end
|
147
147
|
|
148
148
|
# A replica set topology is not unknown.
|
149
149
|
#
|
@@ -59,7 +59,7 @@ module Mongo
|
|
59
59
|
# @param [ Hash ] options The options.
|
60
60
|
#
|
61
61
|
# @since 2.0.0
|
62
|
-
def initialize(options)
|
62
|
+
def initialize(options, seeds = [])
|
63
63
|
@options = options
|
64
64
|
end
|
65
65
|
|
@@ -107,15 +107,15 @@ module Mongo
|
|
107
107
|
# @since 2.0.0
|
108
108
|
def sharded?; true; end
|
109
109
|
|
110
|
-
# A sharded topology is not
|
110
|
+
# A sharded topology is not single.
|
111
111
|
#
|
112
|
-
# @example Is the topology
|
113
|
-
# Sharded.
|
112
|
+
# @example Is the topology single?
|
113
|
+
# Sharded.single?
|
114
114
|
#
|
115
115
|
# @return [ false ] Always false.
|
116
116
|
#
|
117
117
|
# @since 2.0.0
|
118
|
-
def
|
118
|
+
def single?; false; end
|
119
119
|
|
120
120
|
# A sharded topology is not unknown.
|
121
121
|
#
|
@@ -16,20 +16,23 @@ module Mongo
|
|
16
16
|
class Cluster
|
17
17
|
module Topology
|
18
18
|
|
19
|
-
# Defines behaviour for when a cluster is in
|
19
|
+
# Defines behaviour for when a cluster is in single topology.
|
20
20
|
#
|
21
21
|
# @since 2.0.0
|
22
|
-
class
|
22
|
+
class Single
|
23
|
+
|
24
|
+
# @return [ String ] seed The seed address.
|
25
|
+
attr_reader :seed
|
23
26
|
|
24
27
|
# The display name for the topology.
|
25
28
|
#
|
26
29
|
# @since 2.0.0
|
27
|
-
NAME = '
|
30
|
+
NAME = 'Single'.freeze
|
28
31
|
|
29
32
|
# Get the display name.
|
30
33
|
#
|
31
34
|
# @example Get the display name.
|
32
|
-
#
|
35
|
+
# Single.display_name
|
33
36
|
#
|
34
37
|
# @return [ String ] The display name.
|
35
38
|
#
|
@@ -48,35 +51,36 @@ module Mongo
|
|
48
51
|
# @param [ Array<Server> ] servers The list of known servers to the
|
49
52
|
# cluster.
|
50
53
|
#
|
51
|
-
# @return [
|
54
|
+
# @return [ Single ] The topology.
|
52
55
|
def elect_primary(description, servers); self; end
|
53
56
|
|
54
57
|
# Initialize the topology with the options.
|
55
58
|
#
|
56
59
|
# @example Initialize the topology.
|
57
|
-
#
|
60
|
+
# Single.new(options)
|
58
61
|
#
|
59
62
|
# @param [ Hash ] options The options.
|
60
63
|
#
|
61
64
|
# @since 2.0.0
|
62
|
-
def initialize(options)
|
65
|
+
def initialize(options, seeds = [])
|
63
66
|
@options = options
|
67
|
+
@seed = seeds.first
|
64
68
|
end
|
65
69
|
|
66
|
-
# A
|
70
|
+
# A single topology is not a replica set.
|
67
71
|
#
|
68
72
|
# @example Is the topology a replica set?
|
69
|
-
#
|
73
|
+
# Single.replica_set?
|
70
74
|
#
|
71
75
|
# @return [ false ] Always false.
|
72
76
|
#
|
73
77
|
# @since 2.0.0
|
74
78
|
def replica_set?; false; end
|
75
79
|
|
76
|
-
#
|
80
|
+
# Single topologies have no replica set name.
|
77
81
|
#
|
78
82
|
# @example Get the replica set name.
|
79
|
-
#
|
83
|
+
# single.replica_set_name
|
80
84
|
#
|
81
85
|
# @return [ nil ] Always nil.
|
82
86
|
#
|
@@ -86,41 +90,41 @@ module Mongo
|
|
86
90
|
# Select appropriate servers for this topology.
|
87
91
|
#
|
88
92
|
# @example Select the servers.
|
89
|
-
#
|
93
|
+
# Single.servers(servers, 'test')
|
90
94
|
#
|
91
95
|
# @param [ Array<Server> ] servers The known servers.
|
92
96
|
#
|
93
|
-
# @return [ Array<Server> ] The
|
97
|
+
# @return [ Array<Server> ] The single servers.
|
94
98
|
#
|
95
99
|
# @since 2.0.0
|
96
100
|
def servers(servers, name = nil)
|
97
|
-
[ servers.detect{ |server| server.
|
101
|
+
[ servers.detect { |server| !server.unknown? } ]
|
98
102
|
end
|
99
103
|
|
100
|
-
# A
|
104
|
+
# A single topology is not sharded.
|
101
105
|
#
|
102
106
|
# @example Is the topology sharded?
|
103
|
-
#
|
107
|
+
# Single.sharded?
|
104
108
|
#
|
105
109
|
# @return [ false ] Always false.
|
106
110
|
#
|
107
111
|
# @since 2.0.0
|
108
112
|
def sharded?; false; end
|
109
113
|
|
110
|
-
# A
|
114
|
+
# A single topology is single.
|
111
115
|
#
|
112
|
-
# @example Is the topology
|
113
|
-
#
|
116
|
+
# @example Is the topology single?
|
117
|
+
# Single.single?
|
114
118
|
#
|
115
119
|
# @return [ true ] Always true.
|
116
120
|
#
|
117
121
|
# @since 2.0.0
|
118
|
-
def
|
122
|
+
def single?; true; end
|
119
123
|
|
120
|
-
# An
|
124
|
+
# An single topology is not unknown.
|
121
125
|
#
|
122
126
|
# @example Is the topology unknown?
|
123
|
-
#
|
127
|
+
# Single.unknown?
|
124
128
|
#
|
125
129
|
# @return [ false ] Always false.
|
126
130
|
#
|
@@ -70,7 +70,7 @@ module Mongo
|
|
70
70
|
# @param [ Hash ] options The options.
|
71
71
|
#
|
72
72
|
# @since 2.0.0
|
73
|
-
def initialize(options)
|
73
|
+
def initialize(options, seeds = [])
|
74
74
|
@options = options
|
75
75
|
end
|
76
76
|
|
@@ -106,6 +106,7 @@ module Mongo
|
|
106
106
|
#
|
107
107
|
# @since 2.0.0
|
108
108
|
def servers(servers)
|
109
|
+
[]
|
109
110
|
end
|
110
111
|
|
111
112
|
# An unknown topology is not sharded.
|
@@ -118,15 +119,15 @@ module Mongo
|
|
118
119
|
# @since 2.0.0
|
119
120
|
def sharded?; false; end
|
120
121
|
|
121
|
-
# An unknown topology is not
|
122
|
+
# An unknown topology is not single.
|
122
123
|
#
|
123
|
-
# @example Is the topology
|
124
|
-
# Unknown.
|
124
|
+
# @example Is the topology single?
|
125
|
+
# Unknown.single?
|
125
126
|
#
|
126
127
|
# @return [ true ] Always false.
|
127
128
|
#
|
128
129
|
# @since 2.0.0
|
129
|
-
def
|
130
|
+
def single?; false; end
|
130
131
|
|
131
132
|
# An unknown topology is unknown.
|
132
133
|
#
|
data/lib/mongo/collection.rb
CHANGED
@@ -84,6 +84,8 @@ module Mongo
|
|
84
84
|
# Drop the collection. Will also drop all indexes associated with the
|
85
85
|
# collection.
|
86
86
|
#
|
87
|
+
# @note An error returned if the collection doesn't exist is suppressed.
|
88
|
+
#
|
87
89
|
# @example Drop the collection.
|
88
90
|
# collection.drop
|
89
91
|
#
|
@@ -92,6 +94,9 @@ module Mongo
|
|
92
94
|
# @since 2.0.0
|
93
95
|
def drop
|
94
96
|
database.command(:drop => name)
|
97
|
+
rescue Error::OperationFailure => ex
|
98
|
+
raise ex unless ex.message =~ /ns not found/
|
99
|
+
false
|
95
100
|
end
|
96
101
|
|
97
102
|
# Find documents in the collection.
|
@@ -215,7 +220,7 @@ module Mongo
|
|
215
220
|
#
|
216
221
|
# @since 2.0.0
|
217
222
|
def namespace
|
218
|
-
"#{name}.#{
|
223
|
+
"#{database.name}.#{name}"
|
219
224
|
end
|
220
225
|
end
|
221
226
|
end
|
@@ -232,6 +232,7 @@ module Mongo
|
|
232
232
|
#
|
233
233
|
# @since 2.0.0
|
234
234
|
def projection(document = nil)
|
235
|
+
validate_doc!(document) if document
|
235
236
|
configure(:projection, document)
|
236
237
|
end
|
237
238
|
|
@@ -357,6 +358,10 @@ module Mongo
|
|
357
358
|
def to_return
|
358
359
|
[ limit || batch_size, batch_size || limit ].min
|
359
360
|
end
|
361
|
+
|
362
|
+
def validate_doc!(doc)
|
363
|
+
raise Error::InvalidDocument.new unless doc.respond_to?(:keys)
|
364
|
+
end
|
360
365
|
end
|
361
366
|
end
|
362
367
|
end
|