Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use ENV['MONGODB_URI'] if available #99

Merged
merged 1 commit into from Jun 2, 2012
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 8 additions & 0 deletions README.md
Expand Up @@ -173,6 +173,14 @@ Certain Ruby application servers work by forking, and it has long been necessary
re-establish the child process's connection to the database after fork. But with the release
of v1.3.0, the Ruby driver detects forking and reconnects automatically.

## Environment variable `MONGODB_URI`

`Mongo::Connection.new` and `Mongo::ReplSetConnection.new` will use <code>ENV["MONGODB_URI"]</code> if no other args are provided.

The URI must fit this specification:

mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]

## String Encoding

The BSON ("Binary JSON") format used to communicate with Mongo requires that
Expand Down
62 changes: 25 additions & 37 deletions lib/mongo/connection.rb
Expand Up @@ -32,6 +32,7 @@ class Connection

Thread.abort_on_exception = true

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

# Create a connection to single MongoDB instance.
#
# If no args are provided, it will check <code>ENV["MONGODB_URI"]</code>.
#
# You may specify whether connection to slave is permitted.
# In all cases, the default host is "localhost" and the default port is 27017.
#
Expand Down Expand Up @@ -76,7 +79,7 @@ class Connection
# connection attempt.
# @option opts [Boolean] :ssl (false) If true, create the connection to the server using SSL.
#
# @example localhost, 27017
# @example localhost, 27017 (or <code>ENV["MONGODB_URI"]</code> if available)
# Mongo::Connection.new
#
# @example localhost, 27017
Expand All @@ -93,9 +96,22 @@ class Connection
# @raise [ReplicaSetConnectionError] This is raised if a replica set name is specified and the
# driver fails to connect to a replica set with that name.
#
# @raise [MongoArgumentError] If called with no arguments and <code>ENV["MONGODB_URI"]</code> implies a replica set.
#
# @core self.connections
def initialize(host=nil, port=nil, opts={})
@host_to_try = format_pair(host, port)
if host.nil? and ENV.has_key?('MONGODB_URI')
parser = URIParser.new ENV['MONGODB_URI'], opts
if parser.replicaset?
raise MongoArgumentError, "Mongo::Connection.new called with no arguments, but ENV['MONGODB_URI'] implies a replica set."
end
opts = parser.connection_options
@host_to_try = [parser.host, parser.port]
elsif host.is_a?(String)
@host_to_try = [host, (port || DEFAULT_PORT).to_i]
else
@host_to_try = [DEFAULT_HOST, DEFAULT_PORT]
end

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

nodes << opts
ReplSetConnection.new(*nodes)
ReplSetConnection.new(*(nodes+[opts]))
end

# Initialize a connection to MongoDB using the MongoDB URI spec:
Expand All @@ -155,21 +170,9 @@ def self.multi(nodes, opts={})
# @param opts Any of the options available for Connection.new
#
# @return [Mongo::Connection, Mongo::ReplSetConnection]
def self.from_uri(string, extra_opts={})
uri = URIParser.new(string)
opts = uri.connection_options
opts.merge!(extra_opts)

if uri.nodes.length == 1
opts.merge!({:auths => uri.auths})
Connection.new(uri.nodes[0][0], uri.nodes[0][1], opts)
elsif uri.nodes.length > 1
nodes = uri.nodes.clone
nodes_with_opts = nodes << opts
ReplSetConnection.new(*nodes_with_opts)
else
raise MongoArgumentError, "No nodes specified. Please ensure that you've provided at least one node."
end
def self.from_uri(uri, extra_opts={})
parser = URIParser.new uri, extra_opts
parser.connection
end

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

should_connect = opts.fetch(:connect, true)
connect if should_connect
end

## Configuration helper methods

# Returns a host-port pair.
#
# @return [Array]
#
# @private
def format_pair(host, port)
case host
when String
[host, port ? port.to_i : DEFAULT_PORT]
when nil
['localhost', DEFAULT_PORT]
if opts.fetch(:connect, true)
connect
end
end

Expand Down
29 changes: 21 additions & 8 deletions lib/mongo/repl_set_connection.rb
Expand Up @@ -29,6 +29,8 @@ class ReplSetConnection < Connection

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

unless args.length > 0
nodes = args

if nodes.empty? and ENV.has_key?('MONGODB_URI')
parser = URIParser.new ENV['MONGODB_URI'], opts
if parser.direct?
raise MongoArgumentError, "Mongo::ReplSetConnection.new called with no arguments, but ENV['MONGODB_URI'] implies a direct connection."
end
opts = parser.connection_options
nodes = parser.nodes
end

unless nodes.length > 0
raise MongoArgumentError, "A ReplSetConnection requires at least one seed node."
end

# This is temporary until support for the old format is dropped
@seeds = []
if args.first.last.is_a?(Integer)
if nodes.first.last.is_a?(Integer)
warn "Initiating a ReplSetConnection with seeds passed as individual [host, port] array arguments is deprecated."
warn "Please specify hosts as an array of 'host:port' strings; the old format will be removed in v2.0"
@seeds = args
@seeds = nodes
else
args.first.map do |host_port|
seed = host_port.split(":")
seed[1] = seed[1].to_i
seeds << seed
@seeds = nodes.first.map do |host_port|
host, port = host_port.split(":")
[ host, port.to_i ]
end
end

Expand Down