Skip to content

Commit 1454210

Browse files
seamusabshereTylerBrock
authored andcommitted
Use ENV["MONGODB_URI"] if available.
1 parent 351eeb6 commit 1454210

File tree

8 files changed

+296
-84
lines changed

8 files changed

+296
-84
lines changed

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,14 @@ Certain Ruby application servers work by forking, and it has long been necessary
173173
re-establish the child process's connection to the database after fork. But with the release
174174
of v1.3.0, the Ruby driver detects forking and reconnects automatically.
175175

176+
## Environment variable `MONGODB_URI`
177+
178+
`Mongo::Connection.new` and `Mongo::ReplSetConnection.new` will use <code>ENV["MONGODB_URI"]</code> if no other args are provided.
179+
180+
The URI must fit this specification:
181+
182+
mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]
183+
176184
## String Encoding
177185

178186
The BSON ("Binary JSON") format used to communicate with Mongo requires that

lib/mongo/connection.rb

Lines changed: 25 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ class Connection
3232

3333
Thread.abort_on_exception = true
3434

35+
DEFAULT_HOST = 'localhost'
3536
DEFAULT_PORT = 27017
3637
GENERIC_OPTS = [:ssl, :auths, :pool_size, :pool_timeout, :timeout, :op_timeout, :connect_timeout, :safe, :logger, :connect]
3738
CONNECTION_OPTS = [:slave_ok]
@@ -44,6 +45,8 @@ class Connection
4445

4546
# Create a connection to single MongoDB instance.
4647
#
48+
# If no args are provided, it will check <code>ENV["MONGODB_URI"]</code>.
49+
#
4750
# You may specify whether connection to slave is permitted.
4851
# In all cases, the default host is "localhost" and the default port is 27017.
4952
#
@@ -76,7 +79,7 @@ class Connection
7679
# connection attempt.
7780
# @option opts [Boolean] :ssl (false) If true, create the connection to the server using SSL.
7881
#
79-
# @example localhost, 27017
82+
# @example localhost, 27017 (or <code>ENV["MONGODB_URI"]</code> if available)
8083
# Mongo::Connection.new
8184
#
8285
# @example localhost, 27017
@@ -93,9 +96,22 @@ class Connection
9396
# @raise [ReplicaSetConnectionError] This is raised if a replica set name is specified and the
9497
# driver fails to connect to a replica set with that name.
9598
#
99+
# @raise [MongoArgumentError] If called with no arguments and <code>ENV["MONGODB_URI"]</code> implies a replica set.
100+
#
96101
# @core self.connections
97102
def initialize(host=nil, port=nil, opts={})
98-
@host_to_try = format_pair(host, port)
103+
if host.nil? and ENV.has_key?('MONGODB_URI')
104+
parser = URIParser.new ENV['MONGODB_URI'], opts
105+
if parser.replicaset?
106+
raise MongoArgumentError, "Mongo::Connection.new called with no arguments, but ENV['MONGODB_URI'] implies a replica set."
107+
end
108+
opts = parser.connection_options
109+
@host_to_try = [parser.host, parser.port]
110+
elsif host.is_a?(String)
111+
@host_to_try = [host, (port || DEFAULT_PORT).to_i]
112+
else
113+
@host_to_try = [DEFAULT_HOST, DEFAULT_PORT]
114+
end
99115

100116
# Host and port of current master.
101117
@host = @port = nil
@@ -143,8 +159,7 @@ def initialize(host=nil, port=nil, opts={})
143159
def self.multi(nodes, opts={})
144160
warn "Connection.multi is now deprecated and will be removed in v2.0. Please use ReplSetConnection.new instead."
145161

146-
nodes << opts
147-
ReplSetConnection.new(*nodes)
162+
ReplSetConnection.new(*(nodes+[opts]))
148163
end
149164

150165
# Initialize a connection to MongoDB using the MongoDB URI spec:
@@ -155,21 +170,9 @@ def self.multi(nodes, opts={})
155170
# @param opts Any of the options available for Connection.new
156171
#
157172
# @return [Mongo::Connection, Mongo::ReplSetConnection]
158-
def self.from_uri(string, extra_opts={})
159-
uri = URIParser.new(string)
160-
opts = uri.connection_options
161-
opts.merge!(extra_opts)
162-
163-
if uri.nodes.length == 1
164-
opts.merge!({:auths => uri.auths})
165-
Connection.new(uri.nodes[0][0], uri.nodes[0][1], opts)
166-
elsif uri.nodes.length > 1
167-
nodes = uri.nodes.clone
168-
nodes_with_opts = nodes << opts
169-
ReplSetConnection.new(*nodes_with_opts)
170-
else
171-
raise MongoArgumentError, "No nodes specified. Please ensure that you've provided at least one node."
172-
end
173+
def self.from_uri(uri, extra_opts={})
174+
parser = URIParser.new uri, extra_opts
175+
parser.connection
173176
end
174177

175178
# The host name used for this connection.
@@ -337,7 +340,7 @@ def drop_database(name)
337340
# @param [String] from_host host of the 'from' database.
338341
# @param [String] username username for authentication against from_db (>=1.3.x).
339342
# @param [String] password password for authentication against from_db (>=1.3.x).
340-
def copy_database(from, to, from_host="localhost", username=nil, password=nil)
343+
def copy_database(from, to, from_host=DEFAULT_HOST, username=nil, password=nil)
341344
oh = BSON::OrderedHash.new
342345
oh[:copydb] = 1
343346
oh[:fromhost] = from_host
@@ -585,23 +588,8 @@ def setup(opts)
585588
write_logging_startup_message
586589
end
587590

588-
should_connect = opts.fetch(:connect, true)
589-
connect if should_connect
590-
end
591-
592-
## Configuration helper methods
593-
594-
# Returns a host-port pair.
595-
#
596-
# @return [Array]
597-
#
598-
# @private
599-
def format_pair(host, port)
600-
case host
601-
when String
602-
[host, port ? port.to_i : DEFAULT_PORT]
603-
when nil
604-
['localhost', DEFAULT_PORT]
591+
if opts.fetch(:connect, true)
592+
connect
605593
end
606594
end
607595

lib/mongo/repl_set_connection.rb

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ class ReplSetConnection < Connection
2929

3030
# Create a connection to a MongoDB replica set.
3131
#
32+
# If no args are provided, it will check <code>ENV["MONGODB_URI"]</code>.
33+
#
3234
# Once connected to a replica set, you can find out which nodes are primary, secondary, and
3335
# arbiters with the corresponding accessors: Connection#primary, Connection#secondaries, and
3436
# Connection#arbiters. This is useful if your application needs to connect manually to nodes other
@@ -78,6 +80,8 @@ class ReplSetConnection < Connection
7880
#
7981
# @see http://api.mongodb.org/ruby/current/file.REPLICA_SETS.html Replica sets in Ruby
8082
#
83+
# @raise [MongoArgumentError] If called with no arguments and <code>ENV["MONGODB_URI"]</code> implies a direct connection.
84+
#
8185
# @raise [ReplicaSetConnectionError] This is raised if a replica set name is specified and the
8286
# driver fails to connect to a replica set with that name.
8387
def initialize(*args)
@@ -87,21 +91,30 @@ def initialize(*args)
8791
opts = {}
8892
end
8993

90-
unless args.length > 0
94+
nodes = args
95+
96+
if nodes.empty? and ENV.has_key?('MONGODB_URI')
97+
parser = URIParser.new ENV['MONGODB_URI'], opts
98+
if parser.direct?
99+
raise MongoArgumentError, "Mongo::ReplSetConnection.new called with no arguments, but ENV['MONGODB_URI'] implies a direct connection."
100+
end
101+
opts = parser.connection_options
102+
nodes = parser.nodes
103+
end
104+
105+
unless nodes.length > 0
91106
raise MongoArgumentError, "A ReplSetConnection requires at least one seed node."
92107
end
93108

94109
# This is temporary until support for the old format is dropped
95-
@seeds = []
96-
if args.first.last.is_a?(Integer)
110+
if nodes.first.last.is_a?(Integer)
97111
warn "Initiating a ReplSetConnection with seeds passed as individual [host, port] array arguments is deprecated."
98112
warn "Please specify hosts as an array of 'host:port' strings; the old format will be removed in v2.0"
99-
@seeds = args
113+
@seeds = nodes
100114
else
101-
args.first.map do |host_port|
102-
seed = host_port.split(":")
103-
seed[1] = seed[1].to_i
104-
seeds << seed
115+
@seeds = nodes.first.map do |host_port|
116+
host, port = host_port.split(":")
117+
[ host, port.to_i ]
105118
end
106119
end
107120

0 commit comments

Comments
 (0)