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