-
-
Notifications
You must be signed in to change notification settings - Fork 121
Expand file tree
/
Copy pathConnectionStringParser.cs
More file actions
103 lines (92 loc) · 4.55 KB
/
Copy pathConnectionStringParser.cs
File metadata and controls
103 lines (92 loc) · 4.55 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
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
namespace SQLite.CodeFirst.Utility
{
internal static class ConnectionStringParser
{
private const string DataDirectoryToken = "|datadirectory|";
private const string DataSourceToken = "data source";
private const char KeyValuePairSeperator = ';';
private const char KeyValueSeperator = '=';
private const int KeyPosition = 0;
private const int ValuePosition = 1;
public static string GetDataSource(string connectionString)
{
// If the datasource token does not exists this is a FullUri connection string.
IDictionary<string, string> strings = ParseConnectionString(connectionString);
if (strings.ContainsKey(DataSourceToken))
{
var path = ExpandDataDirectory(ParseConnectionString(connectionString)[DataSourceToken]);
return path.Trim('"');
}
// TODO: Implement FullUri parsing.
if (connectionString.Contains(":memory:"))
{
return ":memory:";
}
throw new NotSupportedException("FullUri format is currently only supported for :memory:.");
}
[SuppressMessage("Microsoft.Globalization", "CA1308:NormalizeStringsToUppercase", Justification = "ToUppercase makes no sense.")]
private static IDictionary<string, string> ParseConnectionString(string connectionString)
{
connectionString = connectionString.Trim();
string[] keyValuePairs = connectionString.Split(KeyValuePairSeperator);
IDictionary<string, string> keyValuePairDictionary = new Dictionary<string, string>();
foreach (var keyValuePair in keyValuePairs)
{
// Split on the first '=' only so a value that itself contains '=' is preserved.
// Input: "data source=C:\a=b.sqlite" -> key="data source", value="C:\a=b.sqlite"
string[] keyValue = keyValuePair.Split(new[] { KeyValueSeperator }, 2, StringSplitOptions.None);
if (keyValue.Length >= 2)
{
// Indexer assignment (last value wins) so a repeated key does not throw.
keyValuePairDictionary[keyValue[KeyPosition].Trim().ToLower(CultureInfo.InvariantCulture)] = keyValue[ValuePosition];
}
}
return keyValuePairDictionary;
}
private static string ExpandDataDirectory(string path)
{
if (path == null || !path.StartsWith(DataDirectoryToken, StringComparison.OrdinalIgnoreCase))
{
return path;
}
string fullPath;
// find the replacement path
object rootFolderObject = AppDomain.CurrentDomain.GetData("DataDirectory");
string rootFolderPath = rootFolderObject as string;
if (rootFolderObject != null && rootFolderPath == null)
{
throw new InvalidOperationException("The value stored in the AppDomains 'DataDirectory' variable has to be a string!");
}
if (string.IsNullOrEmpty(rootFolderPath))
{
rootFolderPath = AppDomain.CurrentDomain.BaseDirectory;
}
// We don't know if rootFolderpath ends with '\', and we don't know if the given name starts with onw
int fileNamePosition = DataDirectoryToken.Length; // filename starts right after the '|datadirectory|' keyword
bool rootFolderEndsWith = (0 < rootFolderPath.Length) && rootFolderPath[rootFolderPath.Length - 1] == Path.DirectorySeparatorChar;
bool fileNameStartsWith = (fileNamePosition < path.Length) && path[fileNamePosition] == Path.DirectorySeparatorChar;
// replace |datadirectory| with root folder path
if (!rootFolderEndsWith && !fileNameStartsWith)
{
// need to insert '\'
fullPath = rootFolderPath + Path.DirectorySeparatorChar + path.Substring(fileNamePosition);
}
else if (rootFolderEndsWith && fileNameStartsWith)
{
// need to strip one out
fullPath = rootFolderPath + path.Substring(fileNamePosition + 1);
}
else
{
// simply concatenate the strings
fullPath = rootFolderPath + path.Substring(fileNamePosition);
}
return fullPath;
}
}
}