This repository was archived by the owner on Feb 16, 2019. It is now read-only.
Repository navigation
Expand file tree
/
Copy pathConnectionString.cs
More file actions
134 lines (121 loc) · 5.67 KB
/
Copy pathConnectionString.cs
File metadata and controls
134 lines (121 loc) · 5.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Text;
using EventStore.ClientAPI.SystemData;
namespace EventStore.ClientAPI
{
/// <summary>
/// Methods for dealing with connection strings.
/// </summary>
public class ConnectionString
{
private static readonly Dictionary<Type, Func<string, object>> translators;
static ConnectionString()
{
translators = new Dictionary<Type, Func<string, object>>()
{
{typeof(int), x => int.Parse(x, CultureInfo.InvariantCulture)},
{typeof(decimal), x=>decimal.Parse(x, CultureInfo.InvariantCulture)},
{typeof(string), x => x},
{typeof(bool), x=>bool.Parse(x)},
{typeof(long), x=>long.Parse(x, CultureInfo.InvariantCulture)},
{typeof(byte), x=>byte.Parse(x, CultureInfo.InvariantCulture)},
{typeof(double), x=>double.Parse(x, CultureInfo.InvariantCulture)},
{typeof(float), x=>float.Parse(x, CultureInfo.InvariantCulture)},
{typeof(TimeSpan), x => TimeSpan.FromMilliseconds(int.Parse(x, CultureInfo.InvariantCulture))},
{typeof(GossipSeed[]), x => x.Split(',').Select(q =>
{
try
{
var pieces = q.Trim().Split(':');
if (pieces.Length != 2) throw new Exception("Could not split IP address from port.");
return new GossipSeed(new IPEndPoint(IPAddress.Parse(pieces[0]), int.Parse(pieces[1])));
}
catch (Exception ex)
{
throw new Exception(string.Format("Gossip seed {0} is not in correct format", q), ex);
}
}).ToArray()
},
{typeof(UserCredentials), x =>
{
try
{
var pieces = x.Trim().Split(':');
if (pieces.Length != 2) throw new Exception("Could not split into username and password.");
return new UserCredentials(pieces[0], pieces[1]);
}
catch (Exception ex)
{
throw new Exception(string.Format("User credentials {0} is not in correct format. Expected format is username:password.", x), ex);
}
}
}
};
}
/// <summary>
/// Parses a connection string into its pieces represented as kv pairs
/// </summary>
/// <param name="connectionString">the connection string to parse</param>
/// <returns></returns>
internal static IEnumerable<KeyValuePair<string, string>> GetConnectionStringInfo(string connectionString)
{
var builder = new DbConnectionStringBuilder() { ConnectionString = connectionString };
//can someome mutate this builder before the enumerable is closed sure but thats the fun!
return from object key in builder.Keys
select new KeyValuePair<string, string>(key.ToString(), builder[key.ToString()].ToString());
}
/// <summary>
/// Returns a <see cref="ConnectionSettings"></see> for a given connection string.
/// </summary>
/// <param name="connectionString">The connection string to parse</param>
/// <param name="builder">Pre-populated settings builder, optional. If not specified, a new builder will be created.</param>
/// <returns>a <see cref="ConnectionSettings"/> from the connection string</returns>
public static ConnectionSettings GetConnectionSettings(string connectionString, ConnectionSettingsBuilder builder = null)
{
var settings = (builder ?? ConnectionSettings.Create()).Build();
var items = GetConnectionStringInfo(connectionString).ToArray();
return Apply(items, settings);
}
private static string WithSpaces(string name)
{
StringBuilder nameWithSpaces = new StringBuilder(32);
nameWithSpaces.Append(name[0]);
for (int i = 1; i < name.Length; i++)
{
char c = name[i];
if (char.IsUpper(c))
{
nameWithSpaces.Append(' ');
}
nameWithSpaces.Append(c);
}
return nameWithSpaces.ToString();
}
private static T Apply<T>(IEnumerable<KeyValuePair<string, string>> items, T obj)
{
var typeFields = typeof(T).GetFields(BindingFlags.Instance | BindingFlags.Public);
var fields = typeFields.Select(x => new Tuple<string, FieldInfo>(x.Name, x))
.Concat(typeFields.Select(x => new Tuple<string, FieldInfo>(WithSpaces(x.Name), x)))
.GroupBy(x => x.Item1)
.ToDictionary(x => x.First().Item1, x => x.First().Item2, StringComparer.OrdinalIgnoreCase);
foreach (var item in items)
{
FieldInfo fi = null;
if (!fields.TryGetValue(item.Key, out fi)) continue;
Func<string, object> func = null;
if (!translators.TryGetValue(fi.FieldType, out func))
{
throw new Exception(string.Format("Can not map field named {0} as type {1} has no translator", item, fi.FieldType.Name));
}
fi.SetValue(obj, func(item.Value));
}
return obj;
}
}
}