lib/mongo/uri.rb in mongo-2.5.0.beta vs lib/mongo/uri.rb in mongo-2.5.0
- old
+ new
@@ -20,12 +20,12 @@
# defined in the connection string format spec.
#
# http://docs.mongodb.org/manual/reference/connection-string/
#
# @example Use the uri string to make a client connection.
- # uri = URI.new('mongodb://localhost:27017')
- # client = Client.new(uri.server, uri.options)
+ # uri = Mongo::URI.new('mongodb://localhost:27017')
+ # client = Mongo::Client.new(uri.servers, uri.options)
# client.login(uri.credentials)
# client[uri.database]
#
# @since 2.0.0
class URI
@@ -44,25 +44,53 @@
# The servers specified in the uri.
#
# @since 2.0.0
attr_reader :servers
+ # The mongodb connection string scheme.
+ #
+ # @deprecated Will be removed in 3.0.
+ #
+ # @since 2.0.0
+ SCHEME = 'mongodb://'.freeze
+
+ # The mongodb connection string scheme root.
+ #
+ # @since 2.5.0
+ MONGODB_SCHEME = 'mongodb'.freeze
+
+ # The mongodb srv protocol connection string scheme root.
+ #
+ # @since 2.5.0
+ MONGODB_SRV_SCHEME = 'mongodb+srv'.freeze
+
+ # Error details for an invalid scheme.
+ #
+ # @since 2.1.0
+ INVALID_SCHEME = "Invalid scheme. Scheme must be '#{MONGODB_SCHEME}' or '#{MONGODB_SRV_SCHEME}'".freeze
+
+ # MongoDB URI format specification.
+ #
+ # @since 2.0.0
+ FORMAT = 'mongodb://[username:password@]host1[:port1][,host2[:port2]' +
+ ',...[,hostN[:portN]]][/[database][?options]]'.freeze
+
+ # MongoDB URI (connection string) documentation url
+ #
+ # @since 2.0.0
+ HELP = 'http://docs.mongodb.org/manual/reference/connection-string/'.freeze
+
# Unsafe characters that must be urlencoded.
#
# @since 2.1.0
UNSAFE = /[\:\/\+\@]/
# Unix socket suffix.
#
# @since 2.1.0
UNIX_SOCKET = /.sock/
- # The mongodb connection string scheme.
- #
- # @since 2.0.0
- SCHEME = 'mongodb://'.freeze
-
# The character delimiting hosts.
#
# @since 2.1.0
HOST_DELIM = ','.freeze
@@ -99,14 +127,14 @@
# The character delimiting auth credentials.
#
# @since 2.1.0
AUTH_DELIM = '@'.freeze
- # Error details for an invalid scheme.
+ # Scheme delimiter.
#
- # @since 2.1.0
- INVALID_SCHEME = "Invalid scheme. Scheme must be '#{SCHEME}'".freeze
+ # @since 2.5.0
+ SCHEME_DELIM = '://'.freeze
# Error details for an invalid options format.
#
# @since 2.1.0
INVALID_OPTS_VALUE_DELIM = "Options and their values must be delimited" +
@@ -140,21 +168,10 @@
# Error details for an invalid port.
#
# @since 2.1.0
INVALID_PORT = "Invalid port. Port must be an integer greater than 0 and less than 65536".freeze
- # MongoDB URI format specification.
- #
- # @since 2.0.0
- FORMAT = 'mongodb://[username:password@]host1[:port1][,host2[:port2]' +
- ',...[,hostN[:portN]]][/[database][?options]]'.freeze
-
- # MongoDB URI (connection string) documentation url
- #
- # @since 2.0.0
- HELP = 'http://docs.mongodb.org/manual/reference/connection-string/'.freeze
-
# Map of URI read preference modes to ruby driver read preference modes
#
# @since 2.0.0
READ_MODE_MAP = {
'primary' => :primary,
@@ -178,27 +195,28 @@
# Options that are allowed to appear more than once in the uri.
#
# @since 2.1.0
REPEATABLE_OPTIONS = [ :tag_sets ]
- # Create the new uri from the provided string.
+ # Get either a URI object or a SRVProtocol URI object.
#
- # @example Create the new URI.
- # URI.new('mongodb://localhost:27017')
+ # @example Get the uri object.
+ # URI.get(string)
#
- # @param [ String ] string The uri string.
- # @param [ Hash ] options The options.
+ # @return [URI, URI::SRVProtocol] The uri object.
#
- # @raise [ Error::InvalidURI ] If the uri does not match the spec.
- #
- # @since 2.0.0
- def initialize(string, options = {})
- @string = string
- @options = options
- _, scheme, remaining = @string.partition(SCHEME)
- raise_invalid_error!(INVALID_SCHEME) unless scheme == SCHEME
- setup!(remaining)
+ # @since 2.5.0
+ def self.get(string, opts = {})
+ scheme, _, remaining = string.partition(SCHEME_DELIM)
+ case scheme
+ when MONGODB_SCHEME
+ URI.new(string, opts)
+ when MONGODB_SRV_SCHEME
+ SRVProtocol.new(string, opts)
+ else
+ raise Error::InvalidURI.new(string, INVALID_SCHEME)
+ end
end
# Gets the options hash that needs to be passed to a Mongo::Client on
# instantiation, so we don't have to merge the credentials and database in
# at that point - we only have a single point here.
@@ -212,10 +230,29 @@
def client_options
opts = uri_options.merge(:database => database)
@user ? opts.merge(credentials) : opts
end
+ # Create the new uri from the provided string.
+ #
+ # @example Create the new URI.
+ # URI.new('mongodb://localhost:27017')
+ #
+ # @param [ String ] string The uri string.
+ # @param [ Hash ] options The options.
+ #
+ # @raise [ Error::InvalidURI ] If the uri does not match the spec.
+ #
+ # @since 2.0.0
+ def initialize(string, options = {})
+ @string = string
+ @options = options
+ parsed_scheme, _, remaining = string.partition(SCHEME_DELIM)
+ raise_invalid_error!(INVALID_SCHEME) unless parsed_scheme == scheme
+ parse!(remaining)
+ end
+
# Get the credentials provided in the URI.
#
# @example Get the credentials.
# uri.credentials
#
@@ -240,11 +277,22 @@
@database ? @database : Database::ADMIN
end
private
- def setup!(remaining)
+ def scheme
+ MONGODB_SCHEME
+ end
+
+ def parse_creds_hosts!(string)
+ hosts, creds = split_creds_hosts(string)
+ @servers = parse_servers!(hosts)
+ @user = parse_user!(creds)
+ @password = parse_password!(creds)
+ end
+
+ def parse!(remaining)
creds_hosts, db_opts = extract_db_opts!(remaining)
parse_creds_hosts!(creds_hosts)
parse_db_opts!(db_opts)
end
@@ -255,17 +303,10 @@
raise_invalid_error!(INVALID_OPTS_DELIM)
end
[ creds_hosts, db_opts ].map { |s| s.reverse }
end
- def parse_creds_hosts!(string)
- hosts, creds = split_creds_hosts(string)
- @servers = parse_servers!(hosts)
- @user = parse_user!(creds)
- @password = parse_password!(creds)
- end
-
def split_creds_hosts(string)
hosts, _, creds = string.reverse.partition(AUTH_DELIM)
hosts, creds = creds, hosts if hosts.empty?
[ hosts, creds ].map { |s| s.reverse }
end
@@ -328,17 +369,18 @@
h, _, p = host.partition(HOST_PORT_DELIM)
raise_invalid_error!(INVALID_HOST) unless h.size > 0
validate_port_string!(p)
elsif host =~ UNIX_SOCKET
raise_invalid_error!(UNESCAPED_UNIX_SOCKET) if host =~ UNSAFE
+ host = decode(host)
end
servers << host
end
end
def raise_invalid_error!(details)
- raise Error::InvalidURI.new(@string, details)
+ raise Error::InvalidURI.new(@string, details, FORMAT)
end
def decode(value)
::URI::DEFAULT_PARSER.unescape(value)
end
@@ -583,5 +625,7 @@
def array(value)
value.split(',')
end
end
end
+
+require 'mongo/uri/srv_protocol'