public void Parse(string url)
{
const string serverPattern = @"((\[[^]]+?\]|[^:,/]+)(:\d+)?)";
const string pattern =
@"^mongodb://" +
@"((?<username>[^:]+):(?<password>[^@]+)@)?" +
@"(?<servers>" + serverPattern + "(," + serverPattern + ")*)?" +
@"(/(?<database>[^?]+)?(\?(?<query>.*))?)?$";
Match match = Regex.Match(url, pattern);
if (match.Success)
{
string username = Uri.UnescapeDataString(match.Groups["username"].Value);
string password = Uri.UnescapeDataString(match.Groups["password"].Value);
string servers = match.Groups["servers"].Value;
string databaseName = match.Groups["database"].Value;
string query = match.Groups["query"].Value;
if (username != "" && password != "")
{
_defaultCredentials = new MongoCredentials(username, password);
}
else
{
_defaultCredentials = null;
}
if (servers != "")
{
List<MongoServerAddress> addresses = new List<MongoServerAddress>();
foreach (string server in servers.Split(','))
{
var address = MongoServerAddress.Parse(server);
addresses.Add(address);
}
_servers = addresses;
}
_databaseName = (databaseName != "") ? databaseName : null;
if (!string.IsNullOrEmpty(query))
{
foreach (var pair in query.Split('&', ';'))
{
var parts = pair.Split('=');
if (parts.Length != 2)
{
throw new FormatException(string.Format("Invalid connection string '{0}'.", parts));
}
var name = parts[0];
var value = parts[1];
switch (name.ToLower())
{
case "connect":
ConnectionMode = ParseConnectionMode(name, value);
break;
case "connecttimeout":
case "connecttimeoutms":
ConnectTimeout = ParseTimeSpan(name, value);
break;
case "fsync":
FSync = ParseBoolean(name, value);
break;
case "guids":
case "uuidrepresentation":
GuidRepresentation = (GuidRepresentation)Enum.Parse(typeof(GuidRepresentation), value, true); // ignoreCase
break;
case "ipv6":
IPv6 = ParseBoolean(name, value);
break;
case "j":
case "journal":
Journal = ParseBoolean(name, value);
break;
case "maxidletime":
case "maxidletimems":
MaxConnectionIdleTime = ParseTimeSpan(name, value);
break;
case "maxlifetime":
case "maxlifetimems":
MaxConnectionLifeTime = ParseTimeSpan(name, value);
break;
case "maxpoolsize":
MaxConnectionPoolSize = ParseInt32(name, value);
break;
case "minpoolsize":
MinConnectionPoolSize = ParseInt32(name, value);
break;
case "readpreference":
if (_readPreference == null) { _readPreference = new ReadPreference(); }
ReadPreference.ReadPreferenceMode = ParseReadPreferenceMode(name, value);
break;
case "readpreferencetags":
if (_readPreference == null) { _readPreference = new ReadPreference { ReadPreferenceMode = ReadPreferenceMode.Primary }; }
ReadPreference.AddTagSet(ParseReplicaSetTagSet(name, value));
break;
case "replicaset":
ReplicaSetName = value;
break;
case "safe":
var safe = Convert.ToBoolean(value);
if (_w == null)
{
W = safe ? 1 : 0;
}
else
{
if (safe)
{
// don't overwrite existing W value unless it's 0
var wCount = _w as WriteConcern.WCount;
if (wCount != null && wCount.Value == 0)
{
W = 1;
}
}
else
{
W = 0;
}
}
break;
case "secondaryacceptablelatency":
case "secondaryacceptablelatencyms":
SecondaryAcceptableLatency = ParseTimeSpan(name, value);
break;
case "slaveok":
#pragma warning disable 618
SlaveOk = ParseBoolean(name, value);
#pragma warning restore
break;
case "sockettimeout":
case "sockettimeoutms":
SocketTimeout = ParseTimeSpan(name, value);
break;
case "ssl":
UseSsl = ParseBoolean(name, value);
break;
case "sslverifycertificate":
VerifySslCertificate = ParseBoolean(name, value);
break;
case "w":
W = WriteConcern.WValue.Parse(value);
break;
case "waitqueuemultiple":
WaitQueueMultiple = ParseDouble(name, value);
break;
case "waitqueuesize":
WaitQueueSize = ParseInt32(name, value);
break;
case "waitqueuetimeout":
case "waitqueuetimeoutms":
WaitQueueTimeout = ParseTimeSpan(name, value);
break;
case "wtimeout":
case "wtimeoutms":
WTimeout = ParseTimeSpan(name, value);
break;
default:
var message = string.Format("Invalid option '{0}'.", name);
throw new ArgumentException(message, "url");
}
}
}
}
else
{
throw new FormatException(string.Format("Invalid connection string '{0}'.", url));
}
}