Skip to content

Instantly share code, notes, and snippets.

@khalidsalomao
Created March 29, 2013 01:08
Show Gist options
  • Save khalidsalomao/5268080 to your computer and use it in GitHub Desktop.
Save khalidsalomao/5268080 to your computer and use it in GitHub Desktop.
A global MongoDb configuration helper
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MongoDB.Driver;
namespace SimpleMongoDb
{
public class MongoDbContext
{
/// <summary>
/// ** connection string **
/// format example:
///
/// mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]
///
/// ** OPTIONS **
/// * w
/// -1 : The driver will not acknowledge write operations and will suppress all network or socket errors.
/// 0 : The driver will not acknowledge write operations, but will pass or handle any network and socket errors that it receives to the client.
/// 1 : Provides basic acknowledgment of write operations, a standalone mongod instance, or the primary for replica sets, acknowledge all write operations
/// majority
/// n
/// tags
///
/// * ssl
/// true: Initiate the connection with SSL.
/// false: Initiate the connection without SSL.
/// The default value is false.
///
/// * connectTimeoutMS
/// The time in milliseconds to attempt a connection before timing out.
/// The default is never to timeout, though different drivers might vary. See the driver documentation.
///
/// * socketTimeoutMS
/// The time in milliseconds to attempt a send or receive on a socket before the attempt times out.
/// The default is never to timeout, though different drivers might vary. See the driver documentation.
///
/// * journal
/// true / false
///
/// * readPreference
/// primaryPreferred - will try to read from primary (but if primary is offline, will read from the secondary nodes)
/// secondaryPreferred - will try to read from a secondary node (but if offline, will read from the primary node)
/// (OBS.: All writes go to the Primary)
///
/// </summary>
static string m_baseConnectionString = String.Empty;
static string m_login = null;
static string m_password = null;
static MongoServer m_server = null;
/// <summary>
/// Configures the specified login.
/// </summary>
/// <param name="login">The login.</param>
/// <param name="password">The password.</param>
/// <param name="addresses">List of addresses. Format: host1[:port1][,host2[:port2],...[,hostN[:portN]]]</param>
/// <param name="safeMode">The safe mode. True to receive write confirmation from mongo.</param>
/// <param name="readOnSecondary">The read on secondary. True to direct read operations to cluster secondary nodes (secondaryPreferred), else try to read from primary (primaryPreferred).</param>
/// <param name="connectionTimeoutMilliseconds">The time to attempt a connection before timing out.</param>
/// <param name="socketTimeoutMilliseconds">The time to attempt a send or receive on a socket before the attempt times out.</param>
/// <param name="isReplicaSet">The is replica set hint.</param>
/// <param name="readPreferenceTags">The read preference tags. List of a comma-separated list of colon-separated key-value pairs. Ex.: { {dc:ny,rack:1}, { dc:ny } } </param>
public static void Configure (string login, string password, string addresses, bool safeMode = true, bool readOnSecondary = false, int connectionTimeoutMilliseconds = 1000, int socketTimeoutMilliseconds = 6000, /* bool isReplicaSet = true, */ IEnumerable<string> readPreferenceTags = null)
{
m_login = login;
m_password = password;
string connectionString = BuildConnectionString (login, password, safeMode, readOnSecondary, addresses, connectionTimeoutMilliseconds, socketTimeoutMilliseconds, /*isReplicaSet, */ readPreferenceTags);
if (m_baseConnectionString != connectionString)
{
m_server = null;
m_baseConnectionString = connectionString;
m_docStore = new Lazy<MongoClient> (OpenConnection);
}
}
/// <summary>
/// Builds the connection string.
/// </summary>
/// <param name="login">The login.</param>
/// <param name="password">The password.</param>
/// <param name="safeMode">The safe mode. True to receive write confirmation from mongo.</param>
/// <param name="readOnSecondary">The read on secondary. True to direct read operations to cluster secondary nodes (secondaryPreferred), else try to read from primary (primaryPreferred).</param>
/// <param name="addresses">List of addresses. Format: host1[:port1][,host2[:port2],...[,hostN[:portN]]]</param>
/// <param name="connectionTimeoutMilliseconds">The time to attempt a connection before timing out.</param>
/// <param name="socketTimeoutMilliseconds">The time to attempt a send or receive on a socket before the attempt times out.</param>
/// <param name="isReplicaSet">The is replica set hint.</param>
/// <param name="readPreferenceTags">The read preference tags. List of a comma-separated list of colon-separated key-value pairs. Ex.: { {dc:ny,rack:1}, { dc:ny } } </param>
public static string BuildConnectionString (string login, string password, bool safeMode, bool readOnSecondary, string addresses, int connectionTimeoutMilliseconds, int socketTimeoutMilliseconds, /* bool isReplicaSet = true, */ IEnumerable<string> readPreferenceTags = null)
{
StringBuilder sb = new StringBuilder ("mongodb://", 230);
// check credentials
if (!String.IsNullOrWhiteSpace (login) && !String.IsNullOrWhiteSpace (password))
{
sb.Append (login).Append (':').Append (password).Append ('@');
}
// address
sb.Append (addresses).Append ("/?");
// options
//if (isReplicaSet)
// sb.Append ("connect=replicaset&");
if (safeMode)
sb.Append ("w=1&");
else
sb.Append ("w=0&");
if (readOnSecondary)
{
sb.Append ("readPreference=secondaryPreferred&");
}
else
{
sb.Append ("readPreference=primaryPreferred&");
}
if (readPreferenceTags != null)
{
foreach (var tag in readPreferenceTags)
{
if (String.IsNullOrWhiteSpace (tag))
continue;
sb.Append ("readPreferenceTags=").Append (tag.Trim ().Replace (' ', '_')).Append ('&');
}
}
sb.Append ("connectTimeoutMS=").Append (connectionTimeoutMilliseconds).Append ("&socketTimeoutMS=").Append (socketTimeoutMilliseconds);
// generate final connection string
return sb.ToString ();
}
private static Lazy<MongoClient> m_docStore = new Lazy<MongoClient> (OpenConnection);
private static MongoClient OpenConnection ()
{
// set serialization options (a design decision to use UtcNow or Local)
var dateTimeSerializer = new MongoDB.Bson.Serialization.Serializers.DateTimeSerializer (MongoDB.Bson.Serialization.Options.DateTimeSerializationOptions.LocalInstance);
MongoDB.Bson.Serialization.BsonSerializer.RegisterSerializer (typeof (DateTime), dateTimeSerializer);
// create mongo client
MongoClient client = new MongoClient (m_baseConnectionString);
return client;
}
public static MongoClient Client
{
get { return m_docStore.Value; }
}
public static MongoServer Server
{
get
{
if (m_server == null)
m_server = Client.GetServer ();
return m_server;
}
}
public static MongoDatabase GetDatabase (string dbName)
{
return Server.GetDatabase (dbName);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment