class Mongo::URIParser

Constants

AUTH_REGEX
HOST_REGEX
MONGODB_URI_MATCHER
MONGODB_URI_SPEC
NODE_REGEX
OPT_ATTRS
OPT_CONV
OPT_ERR
OPT_VALID
PASS_REGEX
PATH_REGEX
PORT_REGEX
READ_PREFERENCES
SPEC_ATTRS
USER_REGEX

Attributes

auths[R]
connect[R]
connecttimeoutms[R]
fsync[R]
journal[R]
nodes[R]
pool_size[R]
readpreference[R]
replicaset[R]
safe[R]
slaveok[R]
sockettimeoutms[R]
ssl[R]
w[R]
wtimeout[R]
wtimeoutms[R]

Public Class Methods

new(uri) click to toggle source

Parse a MongoDB URI. This method is used by Mongo::MongoClient.from_uri. Returns an array of nodes and an array of db authorizations, if applicable.

@note Passwords can contain any character except for ','

@param [String] uri The MongoDB URI string. @param [Hash,nil] extra_opts Extra options. Will override anything already specified in the URI.

@core connections

# File lib/mongo/util/uri_parser.rb, line 140
def initialize(uri)
  if uri.start_with?('mongodb://')
    uri = uri[10..-1]
  else
    raise MongoArgumentError, "MongoDB URI must match this spec: #{MONGODB_URI_SPEC}"
  end

  hosts, opts = uri.split('?')
  parse_hosts(hosts)
  parse_options(opts)
  validate_connect
end

Public Instance Methods

connect?() click to toggle source

Whether to immediately connect to the MongoDB node. Defaults to true. @return [true, false]

# File lib/mongo/util/uri_parser.rb, line 185
def connect?
  connect != false
end
connection(extra_opts, legacy = false, sharded = false) click to toggle source

Create a Mongo::MongoClient or a Mongo::MongoReplicaSetClient based on the URI.

@note Don't confuse this with attribute getter method connect.

@return [MongoClient,MongoReplicaSetClient]

# File lib/mongo/util/uri_parser.rb, line 158
def connection(extra_opts, legacy = false, sharded = false)
  opts = connection_options.merge!(extra_opts)
  if(legacy)
    if replicaset?
      ReplSetConnection.new(node_strings, opts)
    else
      Connection.new(host, port, opts)
    end
  else
    if sharded
      MongoShardedClient.new(node_strings, opts)
    elsif replicaset?
      MongoReplicaSetClient.new(node_strings, opts)
    else
      MongoClient.new(host, port, opts)
    end
  end
end
connection_options() click to toggle source

Options that can be passed to Mongo::MongoClient.new or Mongo::MongoReplicaSetClient.new @return [Hash]

# File lib/mongo/util/uri_parser.rb, line 212
def connection_options
  opts = {}

  if @wtimeout
    warn "Using wtimeout in a URI is deprecated, please use wtimeoutMS. It will be removed in v2.0."
    opts[:wtimeout] = @wtimeout
  end
  opts[:wtimeout] = @wtimeoutms

  opts[:w] = 1 if @safe
  opts[:w] = @w if @w
  opts[:j] = @journal
  opts[:fsync] = @fsync

  if @connecttimeoutms
    opts[:connect_timeout] = @connecttimeoutms
  end

  if @sockettimeoutms
    opts[:op_timeout] = @sockettimeoutms
  end

  if @pool_size
    opts[:pool_size] = @pool_size
  end

  if @readpreference
    opts[:read] = @readpreference
  end

  if @slaveok && !@readpreference
    unless replicaset?
      opts[:slave_ok] = true
    else
      opts[:read] = :secondary_preferred
    end
  end

  opts[:ssl] = @ssl
  opts[:auths] = auths

  if replicaset.is_a?(String)
    opts[:name] = replicaset
  end

  opts[:default_db] = @db
  opts[:connect] = connect?

  opts
end
direct?() click to toggle source

Whether this represents a direct connection.

@note Specifying :connect => 'direct' has no effect… other than to raise an exception if other variables suggest a replicaset.

@return [true,false]

# File lib/mongo/util/uri_parser.rb, line 194
def direct?
  !replicaset?
end
host() click to toggle source

For direct connections, the host of the (only) node. @return [String]

# File lib/mongo/util/uri_parser.rb, line 200
def host
  nodes[0][0]
end
node_strings() click to toggle source
# File lib/mongo/util/uri_parser.rb, line 263
def node_strings
  nodes.map { |node| node.join(':') }
end
port() click to toggle source

For direct connections, the port of the (only) node. @return [Integer]

# File lib/mongo/util/uri_parser.rb, line 206
def port
  nodes[0][1].to_i
end
replicaset?() click to toggle source

Whether this represents a replica set. @return [true,false]

# File lib/mongo/util/uri_parser.rb, line 179
def replicaset?
  replicaset.is_a?(String) || nodes.length > 1
end

Private Instance Methods

parse_hosts(uri_without_proto) click to toggle source
# File lib/mongo/util/uri_parser.rb, line 269
def parse_hosts(uri_without_proto)
  @nodes = []
  @auths = []

  matches = MONGODB_URI_MATCHER.match(uri_without_proto)

  if !matches
    raise MongoArgumentError, "MongoDB URI must match this spec: #{MONGODB_URI_SPEC}"
  end

  uname    = matches[2]
  pwd      = matches[3]
  hosturis = matches[4].split(',')
  @db      = matches[8]

  hosturis.each do |hosturi|
    # If port is present, use it, otherwise use default port
    host, port = hosturi.split(':') + [MongoClient::DEFAULT_PORT]

    if !(port.to_s =~ /^\d+$/)
      raise MongoArgumentError, "Invalid port #{port}; port must be specified as digits."
    end

    port = port.to_i
    @nodes << [host, port]
  end

  if @nodes.empty?
    raise MongoArgumentError, "No nodes specified. Please ensure that you've provided at least one node."
  end

  if uname && pwd && @db
    auths << {
      :db_name  => @db,
      :username => URI.unescape(uname),
      :password => URI.unescape(pwd)
    }
  elsif uname || pwd
    raise MongoArgumentError, 'MongoDB URI must include username, ' +
                              'password, and db if username and ' +
                              'password are specified.'
  end
end
parse_options(string_opts) click to toggle source

This method uses the lambdas defined in OPT_VALID and OPT_CONV to validate and convert the given options.

# File lib/mongo/util/uri_parser.rb, line 315
def parse_options(string_opts)
  # initialize instance variables for available options
  OPT_VALID.keys.each { |k| instance_variable_set("@#{k}", nil) }

  string_opts ||= ''

  return if string_opts.empty?

  if string_opts.include?(';') and string_opts.include?('&')
    raise MongoArgumentError, "must not mix URL separators ; and &"
  end

  opts = CGI.parse(string_opts).inject({}) do |memo, (key, value)|
    value = value.first
    memo[key.downcase.to_sym] = value.strip.downcase
    memo
  end

  opts.each do |key, value|
    if !OPT_ATTRS.include?(key)
      raise MongoArgumentError, "Invalid Mongo URI option #{key}"
    end
    if OPT_VALID[key].call(value)
      instance_variable_set("@#{key}", OPT_CONV[key].call(value))
    else
      raise MongoArgumentError, "Invalid value #{value.inspect} for #{key}: #{OPT_ERR[key]}"
    end
  end
end
validate_connect() click to toggle source
# File lib/mongo/util/uri_parser.rb, line 345
def validate_connect
  if replicaset? and @connect == 'direct'
    # Make sure the user doesn't specify something contradictory
    raise MongoArgumentError, "connect=direct conflicts with setting a replicaset name"
  end
end