mongo 1.8.6 → 1.12.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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/LICENSE +1 -1
- data/README.md +114 -282
- data/Rakefile +18 -4
- data/VERSION +1 -1
- data/bin/mongo_console +27 -5
- data/lib/mongo/bulk_write_collection_view.rb +387 -0
- data/lib/mongo/collection.rb +283 -222
- data/lib/mongo/collection_writer.rb +364 -0
- data/lib/mongo/{util → connection}/node.rb +58 -6
- data/lib/mongo/{util → connection}/pool.rb +61 -37
- data/lib/mongo/{util → connection}/pool_manager.rb +72 -22
- data/lib/mongo/{util → connection}/sharding_pool_manager.rb +13 -0
- data/lib/mongo/connection/socket/socket_util.rb +37 -0
- data/lib/mongo/connection/socket/ssl_socket.rb +95 -0
- data/lib/mongo/connection/socket/tcp_socket.rb +87 -0
- data/lib/mongo/connection/socket/unix_socket.rb +39 -0
- data/lib/mongo/connection/socket.rb +18 -0
- data/lib/mongo/connection.rb +19 -0
- data/lib/mongo/cursor.rb +183 -57
- data/lib/mongo/db.rb +302 -138
- data/lib/mongo/exception.rb +145 -0
- data/lib/mongo/functional/authentication.rb +455 -0
- data/lib/mongo/{util → functional}/logging.rb +23 -7
- data/lib/mongo/functional/read_preference.rb +183 -0
- data/lib/mongo/functional/scram.rb +556 -0
- data/lib/mongo/functional/uri_parser.rb +409 -0
- data/lib/mongo/{util → functional}/write_concern.rb +21 -9
- data/lib/mongo/functional.rb +20 -0
- data/lib/mongo/gridfs/grid.rb +19 -8
- data/lib/mongo/gridfs/grid_ext.rb +14 -0
- data/lib/mongo/gridfs/grid_file_system.rb +17 -4
- data/lib/mongo/gridfs/grid_io.rb +21 -9
- data/lib/mongo/gridfs.rb +18 -0
- data/lib/mongo/legacy.rb +76 -7
- data/lib/mongo/mongo_client.rb +246 -206
- data/lib/mongo/mongo_replica_set_client.rb +65 -15
- data/lib/mongo/mongo_sharded_client.rb +18 -3
- data/lib/mongo/networking.rb +47 -18
- data/lib/mongo/{util → utils}/conversions.rb +18 -3
- data/lib/mongo/{util → utils}/core_ext.rb +15 -32
- data/lib/mongo/{util → utils}/server_version.rb +15 -0
- data/lib/mongo/{util → utils}/support.rb +22 -55
- data/lib/mongo/utils/thread_local_variable_manager.rb +25 -0
- data/lib/mongo/utils.rb +19 -0
- data/lib/mongo.rb +44 -26
- data/mongo.gemspec +2 -2
- data/test/functional/authentication_test.rb +31 -10
- data/test/functional/bulk_api_stress_test.rb +133 -0
- data/test/functional/bulk_write_collection_view_test.rb +1198 -0
- data/test/functional/client_test.rb +627 -0
- data/test/functional/collection_test.rb +1419 -654
- data/test/functional/collection_writer_test.rb +83 -0
- data/test/functional/conversions_test.rb +46 -2
- data/test/functional/cursor_fail_test.rb +17 -9
- data/test/functional/cursor_message_test.rb +28 -15
- data/test/functional/cursor_test.rb +300 -165
- data/test/functional/db_api_test.rb +294 -264
- data/test/functional/db_connection_test.rb +15 -3
- data/test/functional/db_test.rb +165 -99
- data/test/functional/grid_file_system_test.rb +124 -112
- data/test/functional/grid_io_test.rb +17 -3
- data/test/functional/grid_test.rb +16 -2
- data/test/functional/pool_test.rb +99 -10
- data/test/functional/safe_test.rb +18 -4
- data/test/functional/ssl_test.rb +29 -0
- data/test/functional/support_test.rb +14 -0
- data/test/functional/timeout_test.rb +27 -27
- data/test/functional/uri_test.rb +268 -22
- data/test/functional/write_concern_test.rb +19 -5
- data/test/helpers/general.rb +50 -0
- data/test/helpers/test_unit.rb +476 -0
- data/test/replica_set/authentication_test.rb +28 -11
- data/test/replica_set/basic_test.rb +79 -23
- data/test/replica_set/client_test.rb +253 -124
- data/test/replica_set/connection_test.rb +59 -37
- data/test/replica_set/count_test.rb +18 -2
- data/test/replica_set/cursor_test.rb +30 -8
- data/test/replica_set/insert_test.rb +109 -2
- data/test/replica_set/max_values_test.rb +85 -10
- data/test/replica_set/pinning_test.rb +66 -2
- data/test/replica_set/query_test.rb +17 -3
- data/test/replica_set/read_preference_test.rb +115 -96
- data/test/replica_set/refresh_test.rb +59 -9
- data/test/replica_set/replication_ack_test.rb +32 -11
- data/test/replica_set/ssl_test.rb +32 -0
- data/test/sharded_cluster/basic_test.rb +73 -25
- data/test/shared/authentication/basic_auth_shared.rb +260 -0
- data/test/shared/authentication/bulk_api_auth_shared.rb +249 -0
- data/test/shared/authentication/gssapi_shared.rb +176 -0
- data/test/shared/authentication/sasl_plain_shared.rb +96 -0
- data/test/shared/authentication/scram_shared.rb +92 -0
- data/test/shared/ssl_shared.rb +235 -0
- data/test/test_helper.rb +47 -196
- data/test/threading/basic_test.rb +42 -2
- data/test/tools/mongo_config.rb +175 -35
- data/test/tools/mongo_config_test.rb +15 -1
- data/test/unit/client_test.rb +186 -57
- data/test/unit/collection_test.rb +44 -54
- data/test/unit/connection_test.rb +160 -71
- data/test/unit/cursor_test.rb +37 -3
- data/test/unit/db_test.rb +38 -14
- data/test/unit/grid_test.rb +15 -1
- data/test/unit/mongo_sharded_client_test.rb +30 -14
- data/test/unit/node_test.rb +16 -1
- data/test/unit/pool_manager_test.rb +21 -4
- data/test/unit/read_pref_test.rb +386 -1
- data/test/unit/read_test.rb +27 -13
- data/test/unit/safe_test.rb +22 -8
- data/test/unit/sharding_pool_manager_test.rb +25 -4
- data/test/unit/write_concern_test.rb +23 -9
- data.tar.gz.sig +0 -0
- metadata +80 -54
- metadata.gz.sig +0 -0
- data/lib/mongo/exceptions.rb +0 -65
- data/lib/mongo/util/read_preference.rb +0 -112
- data/lib/mongo/util/socket_util.rb +0 -20
- data/lib/mongo/util/ssl_socket.rb +0 -51
- data/lib/mongo/util/tcp_socket.rb +0 -62
- data/lib/mongo/util/thread_local_variable_manager.rb +0 -11
- data/lib/mongo/util/unix_socket.rb +0 -23
- data/lib/mongo/util/uri_parser.rb +0 -337
- data/test/functional/connection_test.rb +0 -449
- data/test/functional/threading_test.rb +0 -95
- data/test/replica_set/complex_connect_test.rb +0 -64
- data/test/shared/authentication.rb +0 -66
- data/test/unit/pool_test.rb +0 -9
- data/test/unit/util_test.rb +0 -55
data/lib/mongo/mongo_client.rb
CHANGED
|
@@ -1,6 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
# Copyright (C) 2009-2013 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.
|
|
4
14
|
|
|
5
15
|
module Mongo
|
|
6
16
|
|
|
@@ -9,6 +19,22 @@ module Mongo
|
|
|
9
19
|
include Mongo::Logging
|
|
10
20
|
include Mongo::Networking
|
|
11
21
|
include Mongo::WriteConcern
|
|
22
|
+
include Mongo::Authentication
|
|
23
|
+
|
|
24
|
+
# Wire version
|
|
25
|
+
RELEASE_2_4_AND_BEFORE = 0 # Everything before we started tracking.
|
|
26
|
+
AGG_RETURNS_CURSORS = 1 # The aggregation command may now be requested to return cursors.
|
|
27
|
+
BATCH_COMMANDS = 2 # insert, update, and delete batch command
|
|
28
|
+
MONGODB_3_0 = 3 # listCollections and listIndexes commands, SCRAM-SHA-1 auth mechanism
|
|
29
|
+
MAX_WIRE_VERSION = MONGODB_3_0 # supported by this client implementation
|
|
30
|
+
MIN_WIRE_VERSION = RELEASE_2_4_AND_BEFORE # supported by this client implementation
|
|
31
|
+
|
|
32
|
+
# Server command headroom
|
|
33
|
+
COMMAND_HEADROOM = 16_384
|
|
34
|
+
APPEND_HEADROOM = COMMAND_HEADROOM / 2
|
|
35
|
+
SERIALIZE_HEADROOM = APPEND_HEADROOM / 2
|
|
36
|
+
|
|
37
|
+
DEFAULT_MAX_WRITE_BATCH_SIZE = 1000
|
|
12
38
|
|
|
13
39
|
Mutex = ::Mutex
|
|
14
40
|
ConditionVariable = ::ConditionVariable
|
|
@@ -16,8 +42,10 @@ module Mongo
|
|
|
16
42
|
DEFAULT_HOST = 'localhost'
|
|
17
43
|
DEFAULT_PORT = 27017
|
|
18
44
|
DEFAULT_DB_NAME = 'test'
|
|
19
|
-
|
|
45
|
+
DEFAULT_OP_TIMEOUT = 20
|
|
46
|
+
GENERIC_OPTS = [:auths, :logger, :connect, :db_name]
|
|
20
47
|
TIMEOUT_OPTS = [:timeout, :op_timeout, :connect_timeout]
|
|
48
|
+
SSL_OPTS = [:ssl, :ssl_key, :ssl_cert, :ssl_verify, :ssl_ca_cert, :ssl_key_pass_phrase]
|
|
21
49
|
POOL_OPTS = [:pool_size, :pool_timeout]
|
|
22
50
|
READ_PREFERENCE_OPTS = [:read, :tag_sets, :secondary_acceptable_latency_ms]
|
|
23
51
|
WRITE_CONCERN_OPTS = [:w, :j, :fsync, :wtimeout]
|
|
@@ -36,10 +64,14 @@ module Mongo
|
|
|
36
64
|
:pool_timeout,
|
|
37
65
|
:primary_pool,
|
|
38
66
|
:socket_class,
|
|
67
|
+
:socket_opts,
|
|
39
68
|
:op_timeout,
|
|
40
69
|
:tag_sets,
|
|
41
70
|
:acceptable_latency,
|
|
42
|
-
:read
|
|
71
|
+
:read,
|
|
72
|
+
:max_wire_version,
|
|
73
|
+
:min_wire_version,
|
|
74
|
+
:max_write_batch_size
|
|
43
75
|
|
|
44
76
|
# Create a connection to single MongoDB instance.
|
|
45
77
|
#
|
|
@@ -55,33 +87,50 @@ module Mongo
|
|
|
55
87
|
# MongoClient#arbiters. This is useful if your application needs to connect manually to nodes other
|
|
56
88
|
# than the primary.
|
|
57
89
|
#
|
|
58
|
-
# @
|
|
59
|
-
#
|
|
60
|
-
#
|
|
61
|
-
#
|
|
62
|
-
#
|
|
63
|
-
#
|
|
64
|
-
#
|
|
65
|
-
#
|
|
66
|
-
#
|
|
67
|
-
#
|
|
68
|
-
#
|
|
69
|
-
#
|
|
70
|
-
#
|
|
71
|
-
#
|
|
72
|
-
#
|
|
73
|
-
#
|
|
74
|
-
#
|
|
75
|
-
#
|
|
76
|
-
#
|
|
77
|
-
#
|
|
78
|
-
#
|
|
79
|
-
#
|
|
80
|
-
#
|
|
81
|
-
#
|
|
82
|
-
#
|
|
83
|
-
#
|
|
84
|
-
#
|
|
90
|
+
# @overload initialize(host, port, opts={})
|
|
91
|
+
# @param [String] host hostname for the target MongoDB server.
|
|
92
|
+
# @param [Integer] port specify a port number here if only one host is being specified.
|
|
93
|
+
# @param [Hash] opts hash of optional settings and configuration values.
|
|
94
|
+
#
|
|
95
|
+
# @option opts [String, Integer, Symbol] :w (1) Set default number of nodes to which a write
|
|
96
|
+
# should be acknowledged.
|
|
97
|
+
# @option opts [Integer] :wtimeout (nil) Set replica set acknowledgement timeout.
|
|
98
|
+
# @option opts [Boolean] :j (false) If true, block until write operations have been committed
|
|
99
|
+
# to the journal. Cannot be used in combination with 'fsync'. Prior to MongoDB 2.6 this option was
|
|
100
|
+
# ignored if the server was running without journaling. Starting with MongoDB 2.6, write operations will
|
|
101
|
+
# fail with an exception if this option is used when the server is running without journaling.
|
|
102
|
+
# @option opts [Boolean] :fsync (false) If true, and the server is running without journaling, blocks until
|
|
103
|
+
# the server has synced all data files to disk. If the server is running with journaling, this acts the same as
|
|
104
|
+
# the 'j' option, blocking until write operations have been committed to the journal.
|
|
105
|
+
# Cannot be used in combination with 'j'.
|
|
106
|
+
#
|
|
107
|
+
# Notes about Write-Concern Options:
|
|
108
|
+
# Write concern options are propagated to objects instantiated from this MongoClient.
|
|
109
|
+
# These defaults can be overridden upon instantiation of any object by explicitly setting an options hash
|
|
110
|
+
# on initialization.
|
|
111
|
+
#
|
|
112
|
+
# @option opts [Boolean] :ssl (false) If true, create the connection to the server using SSL.
|
|
113
|
+
# @option opts [String] :ssl_cert (nil) The certificate file used to identify the local connection against MongoDB.
|
|
114
|
+
# @option opts [String] :ssl_key (nil) The private keyfile used to identify the local connection against MongoDB.
|
|
115
|
+
# Note that even if the key is stored in the same file as the certificate, both need to be explicitly specified.
|
|
116
|
+
# @option opts [String] :ssl_key_pass_phrase (nil) A passphrase for the private key.
|
|
117
|
+
# @option opts [Boolean] :ssl_verify (nil) Specifies whether or not peer certification validation should occur.
|
|
118
|
+
# @option opts [String] :ssl_ca_cert (nil) The ca_certs file contains a set of concatenated "certification authority"
|
|
119
|
+
# certificates, which are used to validate certificates passed from the other end of the connection.
|
|
120
|
+
# Required for :ssl_verify.
|
|
121
|
+
# @option opts [Boolean] :slave_ok (false) Must be set to +true+ when connecting
|
|
122
|
+
# to a single, slave node.
|
|
123
|
+
# @option opts [Logger, #debug] :logger (nil) A Logger instance for debugging driver ops. Note that
|
|
124
|
+
# logging negatively impacts performance; therefore, it should not be used for high-performance apps.
|
|
125
|
+
# @option opts [Integer] :pool_size (1) The maximum number of socket self.connections allowed per
|
|
126
|
+
# connection pool. Note: this setting is relevant only for multi-threaded applications.
|
|
127
|
+
# @option opts [Float] :pool_timeout (5.0) When all of the self.connections a pool are checked out,
|
|
128
|
+
# this is the number of seconds to wait for a new connection to be released before throwing an exception.
|
|
129
|
+
# Note: this setting is relevant only for multi-threaded applications.
|
|
130
|
+
# @option opts [Float] :op_timeout (DEFAULT_OP_TIMEOUT) The number of seconds to wait for a read operation to time out.
|
|
131
|
+
# Set to DEFAULT_OP_TIMEOUT (20) by default. A value of nil may be specified explicitly.
|
|
132
|
+
# @option opts [Float] :connect_timeout (nil) The number of seconds to wait before timing out a
|
|
133
|
+
# connection attempt.
|
|
85
134
|
#
|
|
86
135
|
# @example localhost, 27017 (or <code>ENV["MONGODB_URI"]</code> if available)
|
|
87
136
|
# MongoClient.new
|
|
@@ -90,7 +139,7 @@ module Mongo
|
|
|
90
139
|
# MongoClient.new("localhost")
|
|
91
140
|
#
|
|
92
141
|
# @example localhost, 3000, max 5 self.connections, with max 5 seconds of wait time.
|
|
93
|
-
# MongoClient.new("localhost", 3000, :pool_size => 5, :
|
|
142
|
+
# MongoClient.new("localhost", 3000, :pool_size => 5, :pool_timeout => 5)
|
|
94
143
|
#
|
|
95
144
|
# @example localhost, 3000, where this node may be a slave
|
|
96
145
|
# MongoClient.new("localhost", 3000, :slave_ok => true)
|
|
@@ -104,10 +153,8 @@ module Mongo
|
|
|
104
153
|
# driver fails to connect to a replica set with that name.
|
|
105
154
|
#
|
|
106
155
|
# @raise [MongoArgumentError] If called with no arguments and <code>ENV["MONGODB_URI"]</code> implies a replica set.
|
|
107
|
-
#
|
|
108
|
-
# @core self.connections
|
|
109
156
|
def initialize(*args)
|
|
110
|
-
opts
|
|
157
|
+
opts = args.last.is_a?(Hash) ? args.pop : {}
|
|
111
158
|
@host, @port = parse_init(args[0], args[1], opts)
|
|
112
159
|
|
|
113
160
|
# Lock for request ids.
|
|
@@ -119,9 +166,15 @@ module Mongo
|
|
|
119
166
|
@mongos = false
|
|
120
167
|
|
|
121
168
|
# Not set for direct connection
|
|
122
|
-
@tag_sets
|
|
169
|
+
@tag_sets = []
|
|
123
170
|
@acceptable_latency = 15
|
|
124
171
|
|
|
172
|
+
@max_bson_size = nil
|
|
173
|
+
@max_message_size = nil
|
|
174
|
+
@max_wire_version = nil
|
|
175
|
+
@min_wire_version = nil
|
|
176
|
+
@max_write_batch_size = nil
|
|
177
|
+
|
|
125
178
|
check_opts(opts)
|
|
126
179
|
setup(opts.dup)
|
|
127
180
|
end
|
|
@@ -153,8 +206,7 @@ module Mongo
|
|
|
153
206
|
#
|
|
154
207
|
# @deprecated
|
|
155
208
|
def self.multi(nodes, opts={})
|
|
156
|
-
warn
|
|
157
|
-
|
|
209
|
+
warn 'MongoClient.multi is now deprecated and will be removed in v2.0. Please use MongoReplicaSetClient.new instead.'
|
|
158
210
|
MongoReplicaSetClient.new(nodes, opts)
|
|
159
211
|
end
|
|
160
212
|
|
|
@@ -166,28 +218,14 @@ module Mongo
|
|
|
166
218
|
# @param uri [String]
|
|
167
219
|
# A string of the format mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/database]
|
|
168
220
|
#
|
|
169
|
-
# @param
|
|
221
|
+
# @param [Hash] extra_opts Any of the options available for MongoClient.new
|
|
170
222
|
#
|
|
171
223
|
# @return [Mongo::MongoClient, Mongo::MongoReplicaSetClient]
|
|
172
224
|
def self.from_uri(uri = ENV['MONGODB_URI'], extra_opts={})
|
|
173
|
-
parser = URIParser.new
|
|
225
|
+
parser = URIParser.new(uri)
|
|
174
226
|
parser.connection(extra_opts)
|
|
175
227
|
end
|
|
176
228
|
|
|
177
|
-
def parse_init(host, port, opts)
|
|
178
|
-
if host.nil? && port.nil? && ENV.has_key?('MONGODB_URI')
|
|
179
|
-
parser = URIParser.new(ENV['MONGODB_URI'])
|
|
180
|
-
if parser.replicaset?
|
|
181
|
-
raise MongoArgumentError,
|
|
182
|
-
"ENV['MONGODB_URI'] implies a replica set."
|
|
183
|
-
end
|
|
184
|
-
opts.merge! parser.connection_options
|
|
185
|
-
[parser.host, parser.port]
|
|
186
|
-
else
|
|
187
|
-
[host || DEFAULT_HOST, port || DEFAULT_PORT]
|
|
188
|
-
end
|
|
189
|
-
end
|
|
190
|
-
|
|
191
229
|
# The host name used for this connection.
|
|
192
230
|
#
|
|
193
231
|
# @return [String]
|
|
@@ -206,8 +244,7 @@ module Mongo
|
|
|
206
244
|
[@host, @port]
|
|
207
245
|
end
|
|
208
246
|
|
|
209
|
-
#
|
|
210
|
-
# the datafiles in a state safe for snapshotting, backing up, etc.
|
|
247
|
+
# Flush all pending writes to datafiles.
|
|
211
248
|
#
|
|
212
249
|
# @return [BSON::OrderedHash] the command response
|
|
213
250
|
def lock!
|
|
@@ -231,83 +268,15 @@ module Mongo
|
|
|
231
268
|
self['admin']['$cmd.sys.unlock'].find_one
|
|
232
269
|
end
|
|
233
270
|
|
|
234
|
-
# Apply each of the saved database authentications.
|
|
235
|
-
#
|
|
236
|
-
# @return [Boolean] returns true if authentications exist and succeeds, false
|
|
237
|
-
# if none exists.
|
|
238
|
-
#
|
|
239
|
-
# @raise [AuthenticationError] raises an exception if any one
|
|
240
|
-
# authentication fails.
|
|
241
|
-
def apply_saved_authentication(opts={})
|
|
242
|
-
return false if @auths.empty?
|
|
243
|
-
@auths.each do |auth|
|
|
244
|
-
self[auth[:db_name]].issue_authentication(auth[:username], auth[:password], false,
|
|
245
|
-
:socket => opts[:socket])
|
|
246
|
-
end
|
|
247
|
-
true
|
|
248
|
-
end
|
|
249
|
-
|
|
250
|
-
# Save an authentication to this connection. When connecting,
|
|
251
|
-
# the connection will attempt to re-authenticate on every db
|
|
252
|
-
# specified in the list of auths. This method is called automatically
|
|
253
|
-
# by DB#authenticate.
|
|
254
|
-
#
|
|
255
|
-
# Note: this method will not actually issue an authentication command. To do that,
|
|
256
|
-
# either run MongoClient#apply_saved_authentication or DB#authenticate.
|
|
257
|
-
#
|
|
258
|
-
# @param [String] db_name
|
|
259
|
-
# @param [String] username
|
|
260
|
-
# @param [String] password
|
|
261
|
-
#
|
|
262
|
-
# @return [Hash] a hash representing the authentication just added.
|
|
263
|
-
def add_auth(db_name, username, password)
|
|
264
|
-
if @auths.any? {|a| a[:db_name] == db_name}
|
|
265
|
-
raise MongoArgumentError, "Cannot apply multiple authentications to database '#{db_name}'"
|
|
266
|
-
end
|
|
267
|
-
|
|
268
|
-
auth = {
|
|
269
|
-
:db_name => db_name,
|
|
270
|
-
:username => username,
|
|
271
|
-
:password => password
|
|
272
|
-
}
|
|
273
|
-
@auths << auth
|
|
274
|
-
auth
|
|
275
|
-
end
|
|
276
|
-
|
|
277
|
-
# Remove a saved authentication for this connection.
|
|
278
|
-
#
|
|
279
|
-
# @param [String] db_name
|
|
280
|
-
#
|
|
281
|
-
# @return [Boolean]
|
|
282
|
-
def remove_auth(db_name)
|
|
283
|
-
return unless @auths
|
|
284
|
-
@auths.reject! { |a| a[:db_name] == db_name } ? true : false
|
|
285
|
-
end
|
|
286
|
-
|
|
287
|
-
# Remove all authentication information stored in this connection.
|
|
288
|
-
#
|
|
289
|
-
# @return [true] this operation return true because it always succeeds.
|
|
290
|
-
def clear_auths
|
|
291
|
-
@auths = []
|
|
292
|
-
true
|
|
293
|
-
end
|
|
294
|
-
|
|
295
|
-
def authenticate_pools
|
|
296
|
-
@primary_pool.authenticate_existing
|
|
297
|
-
end
|
|
298
|
-
|
|
299
|
-
def logout_pools(db)
|
|
300
|
-
@primary_pool.logout_existing(db)
|
|
301
|
-
end
|
|
302
|
-
|
|
303
271
|
# Return a hash with all database names
|
|
304
272
|
# and their respective sizes on disk.
|
|
305
273
|
#
|
|
306
274
|
# @return [Hash]
|
|
307
275
|
def database_info
|
|
308
276
|
doc = self['admin'].command({:listDatabases => 1})
|
|
309
|
-
doc['databases'].
|
|
277
|
+
doc['databases'].inject({}) do |info, db|
|
|
310
278
|
info[db['name']] = db['sizeOnDisk'].to_i
|
|
279
|
+
info
|
|
311
280
|
end
|
|
312
281
|
end
|
|
313
282
|
|
|
@@ -321,80 +290,63 @@ module Mongo
|
|
|
321
290
|
# Return a database with the given name.
|
|
322
291
|
# See DB#new for valid options hash parameters.
|
|
323
292
|
#
|
|
324
|
-
# @param [String]
|
|
325
|
-
# @param [Hash]
|
|
326
|
-
#
|
|
327
|
-
# @return [Mongo::DB]
|
|
293
|
+
# @param name [String] The name of the database.
|
|
294
|
+
# @param opts [Hash] A hash of options to be passed to the DB constructor.
|
|
328
295
|
#
|
|
329
|
-
# @
|
|
330
|
-
def db(
|
|
331
|
-
|
|
332
|
-
db_name = uri[%r{/([^/\?]+)(\?|$)}, 1]
|
|
333
|
-
end
|
|
334
|
-
|
|
335
|
-
db_name ||= DEFAULT_DB_NAME
|
|
336
|
-
|
|
337
|
-
DB.new(db_name, self, opts)
|
|
296
|
+
# @return [DB] The DB instance.
|
|
297
|
+
def db(name = nil, opts = {})
|
|
298
|
+
DB.new(name || @db_name || DEFAULT_DB_NAME, self, opts)
|
|
338
299
|
end
|
|
339
300
|
|
|
340
|
-
# Shortcut for returning a database. Use
|
|
301
|
+
# Shortcut for returning a database. Use MongoClient#db to accept options.
|
|
341
302
|
#
|
|
342
|
-
# @param [String]
|
|
303
|
+
# @param name [String] The name of the database.
|
|
343
304
|
#
|
|
344
|
-
# @return [
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
def [](db_name)
|
|
348
|
-
DB.new(db_name, self)
|
|
305
|
+
# @return [DB] The DB instance.
|
|
306
|
+
def [](name)
|
|
307
|
+
DB.new(name, self)
|
|
349
308
|
end
|
|
350
309
|
|
|
351
|
-
def refresh
|
|
352
|
-
end
|
|
310
|
+
def refresh; end
|
|
353
311
|
|
|
354
312
|
def pinned_pool
|
|
355
313
|
@primary_pool
|
|
356
314
|
end
|
|
357
315
|
|
|
358
|
-
def pin_pool(pool, read_prefs)
|
|
359
|
-
end
|
|
316
|
+
def pin_pool(pool, read_prefs); end
|
|
360
317
|
|
|
361
|
-
def unpin_pool
|
|
362
|
-
end
|
|
318
|
+
def unpin_pool; end
|
|
363
319
|
|
|
364
320
|
# Drop a database.
|
|
365
321
|
#
|
|
366
|
-
# @param [String] name
|
|
367
|
-
def drop_database(
|
|
368
|
-
self[
|
|
322
|
+
# @param database [String] name of an existing database.
|
|
323
|
+
def drop_database(database)
|
|
324
|
+
self[database].command(:dropDatabase => 1)
|
|
369
325
|
end
|
|
370
326
|
|
|
371
327
|
# Copy the database +from+ to +to+ on localhost. The +from+ database is
|
|
372
328
|
# assumed to be on localhost, but an alternate host can be specified.
|
|
373
329
|
#
|
|
374
|
-
# @param [String]
|
|
375
|
-
# @param [String]
|
|
376
|
-
# @param [String]
|
|
377
|
-
# @param [String] username
|
|
378
|
-
# @param [String] password
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
oh[:nonce] = result["nonce"]
|
|
394
|
-
oh[:username] = username
|
|
395
|
-
oh[:key] = Mongo::Support.auth_key(username, password, oh[:nonce])
|
|
330
|
+
# @param from [String] name of the database to copy from.
|
|
331
|
+
# @param to [String] name of the database to copy to.
|
|
332
|
+
# @param from_host [String] host of the 'from' database.
|
|
333
|
+
# @param username [String] username (applies to 'from' db)
|
|
334
|
+
# @param password [String] password (applies to 'from' db)
|
|
335
|
+
#
|
|
336
|
+
# @note This command only supports the MONGODB-CR authentication mechanism.
|
|
337
|
+
def copy_database(
|
|
338
|
+
from,
|
|
339
|
+
to,
|
|
340
|
+
from_host = DEFAULT_HOST,
|
|
341
|
+
username = nil,
|
|
342
|
+
password = nil,
|
|
343
|
+
mechanism = 'SCRAM-SHA-1'
|
|
344
|
+
)
|
|
345
|
+
if wire_version_feature?(MONGODB_3_0) && mechanism == 'SCRAM-SHA-1'
|
|
346
|
+
copy_db_scram(username, password, from_host, from, to)
|
|
347
|
+
else
|
|
348
|
+
copy_db_mongodb_cr(username, password, from_host, from, to)
|
|
396
349
|
end
|
|
397
|
-
self["admin"].command(oh)
|
|
398
350
|
end
|
|
399
351
|
|
|
400
352
|
# Checks if a server is alive. This command will return immediately
|
|
@@ -402,14 +354,14 @@ module Mongo
|
|
|
402
354
|
#
|
|
403
355
|
# @return [Hash]
|
|
404
356
|
def ping
|
|
405
|
-
self[
|
|
357
|
+
self['admin'].command({:ping => 1})
|
|
406
358
|
end
|
|
407
359
|
|
|
408
360
|
# Get the build information for the current connection.
|
|
409
361
|
#
|
|
410
362
|
# @return [Hash]
|
|
411
363
|
def server_info
|
|
412
|
-
self[
|
|
364
|
+
self['admin'].command({:buildinfo => 1})
|
|
413
365
|
end
|
|
414
366
|
|
|
415
367
|
# Get the build version of the current server.
|
|
@@ -417,7 +369,7 @@ module Mongo
|
|
|
417
369
|
# @return [Mongo::ServerVersion]
|
|
418
370
|
# object allowing easy comparability of version.
|
|
419
371
|
def server_version
|
|
420
|
-
ServerVersion.new(server_info[
|
|
372
|
+
ServerVersion.new(server_info['version'])
|
|
421
373
|
end
|
|
422
374
|
|
|
423
375
|
# Is it okay to connect to a slave?
|
|
@@ -440,9 +392,7 @@ module Mongo
|
|
|
440
392
|
# @raise [ConnectionFailure] if unable to connect to any host or port.
|
|
441
393
|
def connect
|
|
442
394
|
close
|
|
443
|
-
|
|
444
395
|
config = check_is_master(host_port)
|
|
445
|
-
|
|
446
396
|
if config
|
|
447
397
|
if config['ismaster'] == 1 || config['ismaster'] == true
|
|
448
398
|
@read_primary = true
|
|
@@ -454,14 +404,21 @@ module Mongo
|
|
|
454
404
|
@mongos = true
|
|
455
405
|
end
|
|
456
406
|
|
|
457
|
-
@max_bson_size
|
|
407
|
+
@max_bson_size = config['maxBsonObjectSize']
|
|
458
408
|
@max_message_size = config['maxMessageSizeBytes']
|
|
409
|
+
@max_wire_version = config['maxWireVersion']
|
|
410
|
+
@min_wire_version = config['minWireVersion']
|
|
411
|
+
@max_write_batch_size = config['maxWriteBatchSize']
|
|
412
|
+
check_wire_version_in_range
|
|
459
413
|
set_primary(host_port)
|
|
460
414
|
end
|
|
461
415
|
|
|
462
|
-
|
|
463
|
-
raise ConnectionFailure,
|
|
416
|
+
unless connected?
|
|
417
|
+
raise ConnectionFailure,
|
|
418
|
+
"Failed to connect to a master node at #{host_port.join(":")}"
|
|
464
419
|
end
|
|
420
|
+
|
|
421
|
+
true
|
|
465
422
|
end
|
|
466
423
|
alias :reconnect :connect
|
|
467
424
|
|
|
@@ -484,7 +441,7 @@ module Mongo
|
|
|
484
441
|
ping
|
|
485
442
|
true
|
|
486
443
|
|
|
487
|
-
rescue ConnectionFailure
|
|
444
|
+
rescue ConnectionFailure, OperationTimeout
|
|
488
445
|
false
|
|
489
446
|
end
|
|
490
447
|
|
|
@@ -508,7 +465,7 @@ module Mongo
|
|
|
508
465
|
def close
|
|
509
466
|
@primary_pool.close if @primary_pool
|
|
510
467
|
@primary_pool = nil
|
|
511
|
-
@primary
|
|
468
|
+
@primary = nil
|
|
512
469
|
end
|
|
513
470
|
|
|
514
471
|
# Returns the maximum BSON object size as returned by the core server.
|
|
@@ -523,6 +480,30 @@ module Mongo
|
|
|
523
480
|
@max_message_size || max_bson_size * MESSAGE_SIZE_FACTOR
|
|
524
481
|
end
|
|
525
482
|
|
|
483
|
+
def max_wire_version
|
|
484
|
+
@max_wire_version || 0
|
|
485
|
+
end
|
|
486
|
+
|
|
487
|
+
def min_wire_version
|
|
488
|
+
@min_wire_version || 0
|
|
489
|
+
end
|
|
490
|
+
|
|
491
|
+
def max_write_batch_size
|
|
492
|
+
@max_write_batch_size || DEFAULT_MAX_WRITE_BATCH_SIZE
|
|
493
|
+
end
|
|
494
|
+
|
|
495
|
+
def wire_version_feature?(feature)
|
|
496
|
+
min_wire_version <= feature && feature <= max_wire_version
|
|
497
|
+
end
|
|
498
|
+
|
|
499
|
+
def primary_wire_version_feature?(feature)
|
|
500
|
+
min_wire_version <= feature && feature <= max_wire_version
|
|
501
|
+
end
|
|
502
|
+
|
|
503
|
+
def use_write_command?(write_concern)
|
|
504
|
+
write_concern[:w] != 0 && primary_wire_version_feature?(Mongo::MongoClient::BATCH_COMMANDS)
|
|
505
|
+
end
|
|
506
|
+
|
|
526
507
|
# Checkout a socket for reading (i.e., a secondary node).
|
|
527
508
|
# Note: this is overridden in MongoReplicaSetClient.
|
|
528
509
|
def checkout_reader(read_preference)
|
|
@@ -555,13 +536,13 @@ module Mongo
|
|
|
555
536
|
begin
|
|
556
537
|
host, port = *node
|
|
557
538
|
config = nil
|
|
558
|
-
socket = @socket_class.new(host, port, @op_timeout, @connect_timeout)
|
|
539
|
+
socket = @socket_class.new(host, port, @op_timeout, @connect_timeout, @socket_opts)
|
|
559
540
|
if @connect_timeout
|
|
560
541
|
Timeout::timeout(@connect_timeout, OperationTimeout) do
|
|
561
|
-
config = self['admin'].command({:
|
|
542
|
+
config = self['admin'].command({:isMaster => 1}, :socket => socket)
|
|
562
543
|
end
|
|
563
544
|
else
|
|
564
|
-
config = self['admin'].command({:
|
|
545
|
+
config = self['admin'].command({:isMaster => 1}, :socket => socket)
|
|
565
546
|
end
|
|
566
547
|
rescue OperationFailure, SocketError, SystemCallError, IOError
|
|
567
548
|
close
|
|
@@ -579,7 +560,8 @@ module Mongo
|
|
|
579
560
|
POOL_OPTS +
|
|
580
561
|
READ_PREFERENCE_OPTS +
|
|
581
562
|
WRITE_CONCERN_OPTS +
|
|
582
|
-
TIMEOUT_OPTS
|
|
563
|
+
TIMEOUT_OPTS +
|
|
564
|
+
SSL_OPTS
|
|
583
565
|
end
|
|
584
566
|
|
|
585
567
|
def check_opts(opts)
|
|
@@ -593,11 +575,40 @@ module Mongo
|
|
|
593
575
|
# Parse option hash
|
|
594
576
|
def setup(opts)
|
|
595
577
|
@slave_ok = opts.delete(:slave_ok)
|
|
578
|
+
@ssl = opts.delete(:ssl)
|
|
579
|
+
@unix = @host ? @host.end_with?('.sock') : false
|
|
580
|
+
|
|
581
|
+
# if ssl options are present, but ssl is nil/false raise for misconfig
|
|
582
|
+
ssl_opts = opts.keys.select { |k| k.to_s.start_with?('ssl') }
|
|
583
|
+
if ssl_opts.size > 0 && !@ssl
|
|
584
|
+
raise MongoArgumentError, "SSL has not been enabled (:ssl=false) " +
|
|
585
|
+
"but the following SSL related options were " +
|
|
586
|
+
"specified: #{ssl_opts.join(', ')}"
|
|
587
|
+
end
|
|
596
588
|
|
|
597
|
-
@
|
|
598
|
-
@unix = @host ? @host.end_with?('.sock') : false
|
|
599
|
-
|
|
589
|
+
@socket_opts = {}
|
|
600
590
|
if @ssl
|
|
591
|
+
# construct ssl socket opts
|
|
592
|
+
@socket_opts[:key] = opts.delete(:ssl_key)
|
|
593
|
+
@socket_opts[:cert] = opts.delete(:ssl_cert)
|
|
594
|
+
@socket_opts[:verify] = opts.delete(:ssl_verify)
|
|
595
|
+
@socket_opts[:ca_cert] = opts.delete(:ssl_ca_cert)
|
|
596
|
+
@socket_opts[:key_pass_phrase] = opts.delete(:ssl_key_pass_phrase)
|
|
597
|
+
|
|
598
|
+
# verify peer requires ca_cert, raise if only one is present
|
|
599
|
+
if @socket_opts[:verify] && !@socket_opts[:ca_cert]
|
|
600
|
+
raise MongoArgumentError,
|
|
601
|
+
'If :ssl_verify_mode has been specified, then you must include ' +
|
|
602
|
+
':ssl_ca_cert in order to perform server validation.'
|
|
603
|
+
end
|
|
604
|
+
|
|
605
|
+
# if we have a keyfile passphrase but no key file, raise
|
|
606
|
+
if @socket_opts[:key_pass_phrase] && !@socket_opts[:key]
|
|
607
|
+
raise MongoArgumentError,
|
|
608
|
+
'If :ssl_key_pass_phrase has been specified, then you must include ' +
|
|
609
|
+
':ssl_key, the passphrase-protected keyfile.'
|
|
610
|
+
end
|
|
611
|
+
|
|
601
612
|
@socket_class = Mongo::SSLSocket
|
|
602
613
|
elsif @unix
|
|
603
614
|
@socket_class = Mongo::UNIXSocket
|
|
@@ -605,25 +616,25 @@ module Mongo
|
|
|
605
616
|
@socket_class = Mongo::TCPSocket
|
|
606
617
|
end
|
|
607
618
|
|
|
608
|
-
|
|
609
|
-
@auths
|
|
619
|
+
@db_name = opts.delete(:db_name)
|
|
620
|
+
@auths = opts.delete(:auths) || Set.new
|
|
610
621
|
|
|
611
622
|
# Pool size and timeout.
|
|
612
623
|
@pool_size = opts.delete(:pool_size) || 1
|
|
613
624
|
if opts[:timeout]
|
|
614
|
-
warn
|
|
615
|
-
|
|
625
|
+
warn 'The :timeout option has been deprecated ' +
|
|
626
|
+
'and will be removed in the 2.0 release. ' +
|
|
627
|
+
'Use :pool_timeout instead.'
|
|
616
628
|
end
|
|
617
629
|
@pool_timeout = opts.delete(:pool_timeout) || opts.delete(:timeout) || 5.0
|
|
618
630
|
|
|
619
631
|
# Timeout on socket read operation.
|
|
620
|
-
@op_timeout = opts.delete(:op_timeout)
|
|
632
|
+
@op_timeout = opts.key?(:op_timeout) ? opts.delete(:op_timeout) : DEFAULT_OP_TIMEOUT
|
|
621
633
|
|
|
622
634
|
# Timeout on socket connect.
|
|
623
635
|
@connect_timeout = opts.delete(:connect_timeout) || 30
|
|
624
636
|
|
|
625
|
-
@logger = opts.delete(:logger)
|
|
626
|
-
|
|
637
|
+
@logger = opts.delete(:logger)
|
|
627
638
|
if @logger
|
|
628
639
|
write_logging_startup_message
|
|
629
640
|
end
|
|
@@ -647,11 +658,40 @@ module Mongo
|
|
|
647
658
|
|
|
648
659
|
private
|
|
649
660
|
|
|
650
|
-
#
|
|
661
|
+
# Parses client initialization info from MONGODB_URI env variable
|
|
662
|
+
def parse_init(host, port, opts)
|
|
663
|
+
if host.nil? && port.nil? && ENV.has_key?('MONGODB_URI')
|
|
664
|
+
parser = URIParser.new(ENV['MONGODB_URI'])
|
|
665
|
+
if parser.replicaset?
|
|
666
|
+
raise MongoArgumentError,
|
|
667
|
+
'ENV[\'MONGODB_URI\'] implies a replica set.'
|
|
668
|
+
end
|
|
669
|
+
opts.merge!(parser.connection_options)
|
|
670
|
+
[parser.host, parser.port]
|
|
671
|
+
else
|
|
672
|
+
host = host[1...-1] if host && host[0,1] == '[' # ipv6 support
|
|
673
|
+
[host || DEFAULT_HOST, port || DEFAULT_PORT]
|
|
674
|
+
end
|
|
675
|
+
end
|
|
676
|
+
|
|
677
|
+
# Set the specified node as primary
|
|
651
678
|
def set_primary(node)
|
|
652
|
-
host, port
|
|
653
|
-
@primary
|
|
679
|
+
host, port = *node
|
|
680
|
+
@primary = [host, port]
|
|
654
681
|
@primary_pool = Pool.new(self, host, port, :size => @pool_size, :timeout => @pool_timeout)
|
|
655
682
|
end
|
|
683
|
+
|
|
684
|
+
# calculate wire version in range
|
|
685
|
+
def check_wire_version_in_range
|
|
686
|
+
unless MIN_WIRE_VERSION <= max_wire_version &&
|
|
687
|
+
MAX_WIRE_VERSION >= min_wire_version
|
|
688
|
+
close
|
|
689
|
+
raise ConnectionFailure,
|
|
690
|
+
"Client wire-version range #{MIN_WIRE_VERSION} to " +
|
|
691
|
+
"#{MAX_WIRE_VERSION} does not support server range " +
|
|
692
|
+
"#{min_wire_version} to #{max_wire_version}, please update " +
|
|
693
|
+
"clients or servers"
|
|
694
|
+
end
|
|
695
|
+
end
|
|
656
696
|
end
|
|
657
697
|
end
|