You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
586 lines
21 KiB
586 lines
21 KiB
/* Copyright 2010-2011 10gen Inc.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Data.Common;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Text.RegularExpressions;
|
|
using System.Xml;
|
|
|
|
using MongoDB.Bson;
|
|
using MongoDB.Driver.Internal;
|
|
|
|
namespace MongoDB.Driver {
|
|
/// <summary>
|
|
/// Represents .NET style connection strings. We recommend you use URL style connection strings
|
|
/// (see MongoUrl and MongoUrlBuilder).
|
|
/// </summary>
|
|
public class MongoConnectionStringBuilder : DbConnectionStringBuilder {
|
|
#region private static fields
|
|
private static Dictionary<string, string> canonicalKeywords = new Dictionary<string, string> {
|
|
{ "connect", "connect" },
|
|
{ "connecttimeout", "connectTimeout" },
|
|
{ "connecttimeoutms", "connectTimeoutMS" },
|
|
{ "database", "database" },
|
|
{ "fsync", "fsync" },
|
|
{ "guids", "guids" },
|
|
{ "j", "j" },
|
|
{ "maxidletime", "maxIdleTime" },
|
|
{ "maxlifetime", "maxLifeTime" },
|
|
{ "maxpoolsize", "maxPoolSize" },
|
|
{ "minpoolsize", "minPoolSize" },
|
|
{ "password", "password" },
|
|
{ "replicaset", "replicaSet" },
|
|
{ "safe", "safe" },
|
|
{ "server", "server" },
|
|
{ "servers", "server" },
|
|
{ "slaveok", "slaveOk" },
|
|
{ "sockettimeout", "socketTimeout" },
|
|
{ "sockettimeoutms", "socketTimeoutMS" },
|
|
{ "username", "username" },
|
|
{ "w", "w" },
|
|
{ "waitqueuemultiple", "waitQueueMultiple" },
|
|
{ "waitqueuesize", "waitQueueSize" },
|
|
{ "waitqueuetimeout", "waitQueueTimeout" },
|
|
{ "waitqueuetimeoutms", "waitQueueTimeoutMS" },
|
|
{ "wtimeout", "wtimeout" },
|
|
{ "wtimeoutms", "wtimeout" }
|
|
};
|
|
#endregion
|
|
|
|
#region private fields
|
|
// default values are set in ResetValues
|
|
private ConnectionMode connectionMode;
|
|
private TimeSpan connectTimeout;
|
|
private string databaseName;
|
|
private GuidRepresentation guidRepresentation;
|
|
private bool ipv6;
|
|
private TimeSpan maxConnectionIdleTime;
|
|
private TimeSpan maxConnectionLifeTime;
|
|
private int maxConnectionPoolSize;
|
|
private int minConnectionPoolSize;
|
|
private string password;
|
|
private string replicaSetName;
|
|
private SafeMode safeMode;
|
|
private IEnumerable<MongoServerAddress> servers;
|
|
private bool slaveOk;
|
|
private TimeSpan socketTimeout;
|
|
private string username;
|
|
private double waitQueueMultiple;
|
|
private int waitQueueSize;
|
|
private TimeSpan waitQueueTimeout;
|
|
#endregion
|
|
|
|
#region constructors
|
|
/// <summary>
|
|
/// Creates a new instance of MongoConnectionStringBuilder.
|
|
/// </summary>
|
|
public MongoConnectionStringBuilder()
|
|
: base() {
|
|
ResetValues();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates a new instance of MongoConnectionStringBuilder.
|
|
/// </summary>
|
|
/// <param name="connectionString">The initial settings.</param>
|
|
public MongoConnectionStringBuilder(
|
|
string connectionString
|
|
) {
|
|
ConnectionString = connectionString; // base class calls Clear which calls ResetValues
|
|
}
|
|
#endregion
|
|
|
|
#region public properties
|
|
/// <summary>
|
|
/// Gets the actual wait queue size (either WaitQueueSize or WaitQueueMultiple x MaxConnectionPoolSize).
|
|
/// </summary>
|
|
public int ComputedWaitQueueSize {
|
|
get {
|
|
if (waitQueueMultiple == 0.0) {
|
|
return waitQueueSize;
|
|
} else {
|
|
return (int) (waitQueueMultiple * maxConnectionPoolSize);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets the connection mode.
|
|
/// </summary>
|
|
public ConnectionMode ConnectionMode {
|
|
get { return connectionMode; }
|
|
set {
|
|
connectionMode = value;
|
|
base["connect"] = MongoUtils.ToCamelCase(value.ToString());
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets the connect timeout.
|
|
/// </summary>
|
|
public TimeSpan ConnectTimeout {
|
|
get { return connectTimeout; }
|
|
set {
|
|
connectTimeout = value;
|
|
base["connectTimeout"] = MongoUrlBuilder.FormatTimeSpan(value);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets the optional database name.
|
|
/// </summary>
|
|
public string DatabaseName {
|
|
get { return databaseName; }
|
|
set {
|
|
base["database"] = databaseName = value;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets the representation for Guids.
|
|
/// </summary>
|
|
public GuidRepresentation GuidRepresentation {
|
|
get { return guidRepresentation; }
|
|
set {
|
|
base["guids"] = guidRepresentation = value;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets whether to use IPv6.
|
|
/// </summary>
|
|
public bool IPv6 {
|
|
get { return ipv6; }
|
|
set {
|
|
ipv6 = value;
|
|
base["ipv6"] = XmlConvert.ToString(value);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets the max connection idle time.
|
|
/// </summary>
|
|
public TimeSpan MaxConnectionIdleTime {
|
|
get { return maxConnectionIdleTime; }
|
|
set {
|
|
maxConnectionIdleTime = value;
|
|
base["maxIdleTime"] = MongoUrlBuilder.FormatTimeSpan(value);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets the max connection life time.
|
|
/// </summary>
|
|
public TimeSpan MaxConnectionLifeTime {
|
|
get { return maxConnectionLifeTime; }
|
|
set {
|
|
maxConnectionLifeTime = value;
|
|
base["maxLifeTime"] = MongoUrlBuilder.FormatTimeSpan(value);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets the max connection pool size.
|
|
/// </summary>
|
|
public int MaxConnectionPoolSize {
|
|
get { return maxConnectionPoolSize; }
|
|
set {
|
|
maxConnectionPoolSize = value;
|
|
base["maxPoolSize"] = XmlConvert.ToString(value);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets the min connection pool size.
|
|
/// </summary>
|
|
public int MinConnectionPoolSize {
|
|
get { return minConnectionPoolSize; }
|
|
set {
|
|
minConnectionPoolSize = value;
|
|
base["minPoolSize"] = XmlConvert.ToString(value);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets the default password.
|
|
/// </summary>
|
|
public string Password {
|
|
get { return password; }
|
|
set {
|
|
base["password"] = password = value;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets the name of the replica set.
|
|
/// </summary>
|
|
public string ReplicaSetName {
|
|
get { return replicaSetName; }
|
|
set {
|
|
ConnectionMode = ConnectionMode.ReplicaSet;
|
|
base["replicaSet"] = replicaSetName = value;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets the SafeMode to use.
|
|
/// </summary>
|
|
public SafeMode SafeMode {
|
|
get { return safeMode; }
|
|
set {
|
|
safeMode = value;
|
|
if (value == null) {
|
|
base["safe"] = null;
|
|
base["w"] = null;
|
|
base["wtimeout"] = null;
|
|
base["fsync"] = null;
|
|
base["j"] = null;
|
|
} else {
|
|
if (value.Enabled) {
|
|
base["safe"] = "true";
|
|
base["w"] = (value.W != 0) ? value.W.ToString() : (value.WMode != null) ? value.WMode : null;
|
|
base["wtimeout"] = (value.W != 0 && value.WTimeout != TimeSpan.Zero) ? MongoUrlBuilder.FormatTimeSpan(value.WTimeout) : null;
|
|
base["fsync"] = (value.FSync) ? "true" : null;
|
|
base["j"] = (value.J) ? "true" : null;
|
|
} else {
|
|
base["safe"] = "false";
|
|
base["w"] = null;
|
|
base["wtimeout"] = null;
|
|
base["fsync"] = null;
|
|
base["j"] = null;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets the address of the server (see also Servers if using more than one address).
|
|
/// </summary>
|
|
public MongoServerAddress Server {
|
|
get { return (servers == null) ? null : servers.Single(); }
|
|
set {
|
|
Servers = new[] { value };
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets the list of server addresses (see also Server if using only one address).
|
|
/// </summary>
|
|
public IEnumerable<MongoServerAddress> Servers {
|
|
get { return servers; }
|
|
set {
|
|
servers = value;
|
|
base["server"] = GetServersString();
|
|
connectionMode = (value.Count() == 1) ? ConnectionMode.Direct : ConnectionMode.ReplicaSet; // assign to field not to property
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets whether queries should be sent to secondary servers.
|
|
/// </summary>
|
|
public bool SlaveOk {
|
|
get { return slaveOk; }
|
|
set {
|
|
slaveOk = value;
|
|
base["slaveOk"] = XmlConvert.ToString(value);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets the socket timeout.
|
|
/// </summary>
|
|
public TimeSpan SocketTimeout {
|
|
get { return socketTimeout; }
|
|
set {
|
|
socketTimeout = value;
|
|
base["socketTimeout"] = MongoUrlBuilder.FormatTimeSpan(value);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets the default username.
|
|
/// </summary>
|
|
public string Username {
|
|
get { return username; }
|
|
set {
|
|
base["username"] = username = value;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets the wait queue multiple (the actual wait queue size will be WaitQueueMultiple x MaxConnectionPoolSize).
|
|
/// </summary>
|
|
public double WaitQueueMultiple {
|
|
get { return waitQueueMultiple; }
|
|
set {
|
|
waitQueueMultiple = value;
|
|
base["waitQueueMultiple"] = (value != 0) ? XmlConvert.ToString(value) : null;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets the wait queue size.
|
|
/// </summary>
|
|
public int WaitQueueSize {
|
|
get { return waitQueueSize; }
|
|
set {
|
|
waitQueueSize = value;
|
|
base["waitQueueSize"] = (value != 0) ? XmlConvert.ToString(value) : null;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets the wait queue timeout.
|
|
/// </summary>
|
|
public TimeSpan WaitQueueTimeout {
|
|
get { return waitQueueTimeout; }
|
|
set {
|
|
waitQueueTimeout = value;
|
|
base["waitQueueTimeout"] = MongoUrlBuilder.FormatTimeSpan(value);
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region public indexers
|
|
/// <summary>
|
|
/// Gets or sets individual settings by keyword.
|
|
/// </summary>
|
|
/// <param name="keyword">The keyword.</param>
|
|
/// <returns>The value of the setting.</returns>
|
|
public override object this[
|
|
string keyword
|
|
] {
|
|
get {
|
|
if (keyword == null) { throw new ArgumentNullException("keyword"); }
|
|
return base[canonicalKeywords[keyword.ToLower()]];
|
|
}
|
|
set {
|
|
if (keyword == null) { throw new ArgumentNullException("keyword"); }
|
|
switch (keyword.ToLower()) {
|
|
case "connect":
|
|
if (value is string) {
|
|
ConnectionMode = (ConnectionMode) Enum.Parse(typeof(ConnectionMode), (string) value, true);
|
|
} else {
|
|
ConnectionMode = (ConnectionMode) value;
|
|
}
|
|
break;
|
|
case "connecttimeout":
|
|
case "connecttimeoutms":
|
|
ConnectTimeout = ToTimeSpan(keyword, value);
|
|
break;
|
|
case "database":
|
|
DatabaseName = (string) value;
|
|
break;
|
|
case "fsync":
|
|
if (safeMode == null) { safeMode = new SafeMode(false); }
|
|
safeMode.FSync = Convert.ToBoolean(value);
|
|
SafeMode = safeMode;
|
|
break;
|
|
case "guids":
|
|
GuidRepresentation = (GuidRepresentation) Enum.Parse(typeof(GuidRepresentation), (string) value, true); // ignoreCase
|
|
break;
|
|
case "ipv6":
|
|
IPv6 = Convert.ToBoolean(value);
|
|
break;
|
|
case "j":
|
|
if (safeMode == null) { safeMode = new SafeMode(false); }
|
|
safeMode.J = Convert.ToBoolean(value);
|
|
SafeMode = safeMode;
|
|
break;
|
|
case "maxidletime":
|
|
case "maxidletimems":
|
|
MaxConnectionIdleTime = ToTimeSpan(keyword, value);
|
|
break;
|
|
case "maxlifetime":
|
|
case "maxlifetimems":
|
|
MaxConnectionLifeTime = ToTimeSpan(keyword, value);
|
|
break;
|
|
case "maxpoolsize":
|
|
MaxConnectionPoolSize = Convert.ToInt32(value);
|
|
break;
|
|
case "minpoolsize":
|
|
MinConnectionPoolSize = Convert.ToInt32(value);
|
|
break;
|
|
case "password":
|
|
Password = (string) value;
|
|
break;
|
|
case "replicaset":
|
|
ReplicaSetName = (string) value;
|
|
ConnectionMode = ConnectionMode.ReplicaSet;
|
|
break;
|
|
case "safe":
|
|
if (safeMode == null) { safeMode = new SafeMode(false); }
|
|
safeMode.Enabled = Convert.ToBoolean(value);
|
|
SafeMode = safeMode;
|
|
break;
|
|
case "server":
|
|
case "servers":
|
|
Servers = ParseServersString((string) value);
|
|
break;
|
|
case "slaveok":
|
|
SlaveOk = Convert.ToBoolean(value);
|
|
break;
|
|
case "sockettimeout":
|
|
case "sockettimeoutms":
|
|
SocketTimeout = ToTimeSpan(keyword, value);
|
|
break;
|
|
case "username":
|
|
Username = (string) value;
|
|
break;
|
|
case "w":
|
|
if (safeMode == null) { safeMode = new SafeMode(false); }
|
|
try {
|
|
safeMode.W = Convert.ToInt32(value);
|
|
} catch (FormatException) {
|
|
safeMode.WMode = (string) value;
|
|
}
|
|
SafeMode = safeMode;
|
|
break;
|
|
case "waitqueuemultiple":
|
|
WaitQueueMultiple = Convert.ToDouble(value);
|
|
WaitQueueSize = 0;
|
|
break;
|
|
case "waitqueuesize":
|
|
WaitQueueSize = Convert.ToInt32(value);
|
|
WaitQueueMultiple = 0;
|
|
break;
|
|
case "waitqueuetimeout":
|
|
case "waitqueuetimeoutms":
|
|
WaitQueueTimeout = ToTimeSpan(keyword, value);
|
|
break;
|
|
case "wtimeout":
|
|
if (safeMode == null) { safeMode = new SafeMode(false); }
|
|
safeMode.WTimeout = ToTimeSpan(keyword, value);
|
|
SafeMode = safeMode;
|
|
break;
|
|
default:
|
|
var message = string.Format("Invalid keyword '{0}'.", keyword);
|
|
throw new ArgumentException(message);
|
|
}
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region public methods
|
|
/// <summary>
|
|
/// Clears all settings to their default values.
|
|
/// </summary>
|
|
public override void Clear() {
|
|
base.Clear();
|
|
ResetValues();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Tests whether a keyword is valid.
|
|
/// </summary>
|
|
/// <param name="keyword">The keyword.</param>
|
|
/// <returns>True if the keyword is valid.</returns>
|
|
public override bool ContainsKey(
|
|
string keyword
|
|
) {
|
|
return canonicalKeywords.ContainsKey(keyword.ToLower());
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates a new instance of MongoServerSettings based on the settings in this MongoConnectionStringBuilder.
|
|
/// </summary>
|
|
/// <returns>A new instance of MongoServerSettings.</returns>
|
|
public MongoServerSettings ToServerSettings() {
|
|
return new MongoServerSettings(
|
|
connectionMode,
|
|
connectTimeout,
|
|
MongoCredentials.Create(username, password), // defaultCredentials
|
|
guidRepresentation,
|
|
ipv6,
|
|
maxConnectionIdleTime,
|
|
maxConnectionLifeTime,
|
|
maxConnectionPoolSize,
|
|
minConnectionPoolSize,
|
|
replicaSetName,
|
|
safeMode ?? MongoDefaults.SafeMode,
|
|
servers,
|
|
slaveOk,
|
|
socketTimeout,
|
|
ComputedWaitQueueSize, // waitQueueSize
|
|
waitQueueTimeout
|
|
);
|
|
}
|
|
#endregion
|
|
|
|
#region private methods
|
|
private string GetServersString() {
|
|
var sb = new StringBuilder();
|
|
foreach (var server in servers) {
|
|
if (sb.Length > 0) { sb.Append(","); }
|
|
if (server.Port == 27017) {
|
|
sb.Append(server.Host);
|
|
} else {
|
|
sb.AppendFormat("{0}:{1}", server.Host, server.Port);
|
|
}
|
|
}
|
|
return sb.ToString();
|
|
}
|
|
|
|
private IEnumerable<MongoServerAddress> ParseServersString(
|
|
string value
|
|
) {
|
|
var servers = new List<MongoServerAddress>();
|
|
foreach (var server in value.Split(',')) {
|
|
servers.Add(MongoServerAddress.Parse(server));
|
|
}
|
|
return servers;
|
|
}
|
|
|
|
private void ResetValues() {
|
|
// set fields and not properties so base class items aren't set
|
|
connectionMode = ConnectionMode.Direct;
|
|
connectTimeout = MongoDefaults.ConnectTimeout;
|
|
databaseName = null;
|
|
guidRepresentation = MongoDefaults.GuidRepresentation;
|
|
ipv6 = false;
|
|
maxConnectionIdleTime = MongoDefaults.MaxConnectionIdleTime;
|
|
maxConnectionLifeTime = MongoDefaults.MaxConnectionLifeTime;
|
|
maxConnectionPoolSize = MongoDefaults.MaxConnectionPoolSize;
|
|
minConnectionPoolSize = MongoDefaults.MinConnectionPoolSize;
|
|
password = null;
|
|
replicaSetName = null;
|
|
safeMode = null;
|
|
servers = null;
|
|
slaveOk = false;
|
|
socketTimeout = MongoDefaults.SocketTimeout;
|
|
username = null;
|
|
waitQueueMultiple = MongoDefaults.WaitQueueMultiple;
|
|
waitQueueSize = MongoDefaults.WaitQueueSize;
|
|
waitQueueTimeout = MongoDefaults.WaitQueueTimeout;
|
|
}
|
|
|
|
private TimeSpan ToTimeSpan(
|
|
string keyword,
|
|
object value
|
|
) {
|
|
if (value is TimeSpan) {
|
|
return (TimeSpan) value;
|
|
} else if (value is string) {
|
|
return MongoUrlBuilder.ParseTimeSpan(keyword, (string) value);
|
|
} else {
|
|
return TimeSpan.FromSeconds(Convert.ToDouble(value));
|
|
}
|
|
}
|
|
#endregion
|
|
}
|
|
}
|