Commit 0c7dd146 authored by Marc Gravell's avatar Marc Gravell

Merge pull request #196 from freakingawesome/connstring-defaultdatabase

Added a way to specify the default database in the connection string
parents 583cf5f4 4d94274f
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NUnit.Framework;
using StackExchange.Redis;
namespace StackExchange.Redis.Tests.Issues
{
[TestFixture]
public class DefaultDatabase : TestBase
{
[Test]
public void UnspecifiedDbId_ReturnsNull()
{
var config = ConfigurationOptions.Parse("localhost");
Assert.IsNull(config.DefaultDatabase);
}
[Test]
public void SpecifiedDbId_ReturnsExpected()
{
var config = ConfigurationOptions.Parse("localhost,defaultDatabase=3");
Assert.AreEqual(3, config.DefaultDatabase);
}
[Test]
public void ConfigurationOptions_UnspecifiedDefaultDb()
{
var log = new StringWriter();
try
{
using (var conn = ConnectionMultiplexer.Connect(string.Format("{0}:{1}", PrimaryServer, PrimaryPort), log)) {
var db = conn.GetDatabase();
Assert.AreEqual(0, db.Database);
}
}
finally
{
Console.WriteLine(log);
}
}
[Test]
public void ConfigurationOptions_SpecifiedDefaultDb()
{
var log = new StringWriter();
try
{
using (var conn = ConnectionMultiplexer.Connect(string.Format("{0}:{1},defaultDatabase=3", PrimaryServer, PrimaryPort), log)) {
var db = conn.GetDatabase();
Assert.AreEqual(3, db.Database);
}
}
finally
{
Console.WriteLine(log);
}
}
}
}
...@@ -71,6 +71,7 @@ ...@@ -71,6 +71,7 @@
<Compile Include="ConnectingFailDetection.cs" /> <Compile Include="ConnectingFailDetection.cs" />
<Compile Include="ConnectToUnexistingHost.cs" /> <Compile Include="ConnectToUnexistingHost.cs" />
<Compile Include="HyperLogLog.cs" /> <Compile Include="HyperLogLog.cs" />
<Compile Include="Issues\DefaultDatabase.cs" />
<Compile Include="Issues\Issue182.cs" /> <Compile Include="Issues\Issue182.cs" />
<Compile Include="WrapperBaseTests.cs" /> <Compile Include="WrapperBaseTests.cs" />
<Compile Include="TransactionWrapperTests.cs" /> <Compile Include="TransactionWrapperTests.cs" />
......
...@@ -74,7 +74,7 @@ internal static void Unknown(string key) ...@@ -74,7 +74,7 @@ internal static void Unknown(string key)
TieBreaker = "tiebreaker", WriteBuffer = "writeBuffer", Ssl = "ssl", SslHost = "sslHost", TieBreaker = "tiebreaker", WriteBuffer = "writeBuffer", Ssl = "ssl", SslHost = "sslHost",
ConfigChannel = "configChannel", AbortOnConnectFail = "abortConnect", ResolveDns = "resolveDns", ConfigChannel = "configChannel", AbortOnConnectFail = "abortConnect", ResolveDns = "resolveDns",
ChannelPrefix = "channelPrefix", Proxy = "proxy", ConnectRetry = "connectRetry", ChannelPrefix = "channelPrefix", Proxy = "proxy", ConnectRetry = "connectRetry",
ConfigCheckSeconds = "configCheckSeconds", ResponseTimeout = "responseTimeout"; ConfigCheckSeconds = "configCheckSeconds", ResponseTimeout = "responseTimeout", DefaultDatabase = "defaultDatabase";
private static readonly Dictionary<string, string> normalizedOptions = new[] private static readonly Dictionary<string, string> normalizedOptions = new[]
{ {
AllowAdmin, SyncTimeout, AllowAdmin, SyncTimeout,
...@@ -83,7 +83,7 @@ internal static void Unknown(string key) ...@@ -83,7 +83,7 @@ internal static void Unknown(string key)
TieBreaker, WriteBuffer, Ssl, SslHost, TieBreaker, WriteBuffer, Ssl, SslHost,
ConfigChannel, AbortOnConnectFail, ResolveDns, ConfigChannel, AbortOnConnectFail, ResolveDns,
ChannelPrefix, Proxy, ConnectRetry, ChannelPrefix, Proxy, ConnectRetry,
ConfigCheckSeconds ConfigCheckSeconds, DefaultDatabase,
}.ToDictionary(x => x, StringComparer.InvariantCultureIgnoreCase); }.ToDictionary(x => x, StringComparer.InvariantCultureIgnoreCase);
public static string TryNormalize(string value) public static string TryNormalize(string value)
...@@ -108,7 +108,7 @@ public static string TryNormalize(string value) ...@@ -108,7 +108,7 @@ public static string TryNormalize(string value)
private Version defaultVersion; private Version defaultVersion;
private int? keepAlive, syncTimeout, connectTimeout, responseTimeout, writeBuffer, connectRetry, configCheckSeconds; private int? keepAlive, syncTimeout, connectTimeout, responseTimeout, writeBuffer, connectRetry, configCheckSeconds, defaultDatabase;
private Proxy? proxy; private Proxy? proxy;
...@@ -265,6 +265,11 @@ public CommandMap CommandMap ...@@ -265,6 +265,11 @@ public CommandMap CommandMap
/// </summary> /// </summary>
public int WriteBuffer { get { return writeBuffer.GetValueOrDefault(4096); } set { writeBuffer = value; } } public int WriteBuffer { get { return writeBuffer.GetValueOrDefault(4096); } set { writeBuffer = value; } }
/// <summary>
/// Specifies the default database to be used when calling ConnectionMultiplexer.GetDatabase() without any parameters
/// </summary>
public int? DefaultDatabase { get { return defaultDatabase; } set { defaultDatabase = value; } }
internal LocalCertificateSelectionCallback CertificateSelectionCallback { get { return CertificateSelection; } private set { CertificateSelection = value; } } internal LocalCertificateSelectionCallback CertificateSelectionCallback { get { return CertificateSelection; } private set { CertificateSelection = value; } }
// these just rip out the underlying handlers, bypassing the event accessors - needed when creating the SSL stream // these just rip out the underlying handlers, bypassing the event accessors - needed when creating the SSL stream
...@@ -328,7 +333,8 @@ public ConfigurationOptions Clone() ...@@ -328,7 +333,8 @@ public ConfigurationOptions Clone()
SocketManager = SocketManager, SocketManager = SocketManager,
connectRetry = connectRetry, connectRetry = connectRetry,
configCheckSeconds = configCheckSeconds, configCheckSeconds = configCheckSeconds,
responseTimeout = responseTimeout responseTimeout = responseTimeout,
defaultDatabase = defaultDatabase,
}; };
foreach (var item in endpoints) foreach (var item in endpoints)
options.endpoints.Add(item); options.endpoints.Add(item);
...@@ -374,6 +380,7 @@ public override string ToString() ...@@ -374,6 +380,7 @@ public override string ToString()
Append(sb, OptionKeys.Proxy, proxy); Append(sb, OptionKeys.Proxy, proxy);
Append(sb, OptionKeys.ConfigCheckSeconds, configCheckSeconds); Append(sb, OptionKeys.ConfigCheckSeconds, configCheckSeconds);
Append(sb, OptionKeys.ResponseTimeout, responseTimeout); Append(sb, OptionKeys.ResponseTimeout, responseTimeout);
Append(sb, OptionKeys.DefaultDatabase, defaultDatabase);
if (commandMap != null) commandMap.AppendDeltas(sb); if (commandMap != null) commandMap.AppendDeltas(sb);
return sb.ToString(); return sb.ToString();
} }
...@@ -463,7 +470,7 @@ static bool IsOption(string option, string prefix) ...@@ -463,7 +470,7 @@ static bool IsOption(string option, string prefix)
void Clear() void Clear()
{ {
clientName = serviceName = password = tieBreaker = sslHost = configChannel = null; clientName = serviceName = password = tieBreaker = sslHost = configChannel = null;
keepAlive = syncTimeout = connectTimeout = writeBuffer = connectRetry = configCheckSeconds = null; keepAlive = syncTimeout = connectTimeout = writeBuffer = connectRetry = configCheckSeconds = defaultDatabase = null;
allowAdmin = abortOnConnectFail = resolveDns = ssl = null; allowAdmin = abortOnConnectFail = resolveDns = ssl = null;
defaultVersion = null; defaultVersion = null;
endpoints.Clear(); endpoints.Clear();
...@@ -569,6 +576,9 @@ private void DoParse(string configuration, bool ignoreUnknown) ...@@ -569,6 +576,9 @@ private void DoParse(string configuration, bool ignoreUnknown)
case OptionKeys.ResponseTimeout: case OptionKeys.ResponseTimeout:
ResponseTimeout = OptionKeys.ParseInt32(key, value, minValue: 1); ResponseTimeout = OptionKeys.ParseInt32(key, value, minValue: 1);
break; break;
case OptionKeys.DefaultDatabase:
defaultDatabase = OptionKeys.ParseInt32(key, value);
break;
default: default:
if (!string.IsNullOrEmpty(key) && key[0] == '$') if (!string.IsNullOrEmpty(key) && key[0] == '$')
{ {
......
...@@ -943,8 +943,11 @@ public ISubscriber GetSubscriber(object asyncState = null) ...@@ -943,8 +943,11 @@ public ISubscriber GetSubscriber(object asyncState = null)
/// <summary> /// <summary>
/// Obtain an interactive connection to a database inside redis /// Obtain an interactive connection to a database inside redis
/// </summary> /// </summary>
public IDatabase GetDatabase(int db = 0, object asyncState = null) public IDatabase GetDatabase(int db = -1, object asyncState = null)
{ {
if (db == -1)
db = configuration.DefaultDatabase ?? 0;
if (db < 0) throw new ArgumentOutOfRangeException("db"); if (db < 0) throw new ArgumentOutOfRangeException("db");
if (db != 0 && RawConfig.Proxy == Proxy.Twemproxy) throw new NotSupportedException("Twemproxy only supports database 0"); if (db != 0 && RawConfig.Proxy == Proxy.Twemproxy) throw new NotSupportedException("Twemproxy only supports database 0");
return new RedisDatabase(this, db, asyncState); return new RedisDatabase(this, db, asyncState);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment