[System.Data] move to corefx (#4893)
[mono-project.git] / mcs / class / System.Data / corefx / DbConnectionOptions.cs
blobcdd1d7397cbb41fc032342bbcbddb69822e3a3c9
1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
5 using System.Collections;
6 using System.Collections.Generic;
7 using System.Diagnostics;
8 using System.Globalization;
9 using System.Runtime.Versioning;
10 using System.Text;
12 namespace System.Data.Common
14 internal partial class DbConnectionOptions
16 // SxS notes:
17 // * this method queries "DataDirectory" value from the current AppDomain.
18 // This string is used for to replace "!DataDirectory!" values in the connection string, it is not considered as an "exposed resource".
19 // * This method uses GetFullPath to validate that root path is valid, the result is not exposed out.
20 [ResourceExposure(ResourceScope.None)]
21 [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
22 internal static string ExpandDataDirectory(string keyword, string value, ref string datadir)
24 string fullPath = null;
25 if ((null != value) && value.StartsWith(DataDirectory, StringComparison.OrdinalIgnoreCase))
27 string rootFolderPath = datadir;
28 if (null == rootFolderPath)
30 // find the replacement path
31 object rootFolderObject = AppDomain.CurrentDomain.GetData("DataDirectory");
32 rootFolderPath = (rootFolderObject as string);
33 if ((null != rootFolderObject) && (null == rootFolderPath))
35 throw ADP.InvalidDataDirectory();
37 else if (string.IsNullOrEmpty(rootFolderPath))
39 rootFolderPath = AppDomain.CurrentDomain.BaseDirectory;
41 if (null == rootFolderPath)
43 rootFolderPath = "";
45 // cache the |DataDir| for ExpandDataDirectories
46 datadir = rootFolderPath;
49 // We don't know if rootFolderpath ends with '\', and we don't know if the given name starts with onw
50 int fileNamePosition = DataDirectory.Length; // filename starts right after the '|datadirectory|' keyword
51 bool rootFolderEndsWith = (0 < rootFolderPath.Length) && rootFolderPath[rootFolderPath.Length - 1] == '\\';
52 bool fileNameStartsWith = (fileNamePosition < value.Length) && value[fileNamePosition] == '\\';
54 // replace |datadirectory| with root folder path
55 if (!rootFolderEndsWith && !fileNameStartsWith)
57 // need to insert '\'
58 fullPath = rootFolderPath + '\\' + value.Substring(fileNamePosition);
60 else if (rootFolderEndsWith && fileNameStartsWith)
62 // need to strip one out
63 fullPath = rootFolderPath + value.Substring(fileNamePosition + 1);
65 else
67 // simply concatenate the strings
68 fullPath = rootFolderPath + value.Substring(fileNamePosition);
71 // verify root folder path is a real path without unexpected "..\"
72 if (!ADP.GetFullPath(fullPath).StartsWith(rootFolderPath, StringComparison.Ordinal))
74 throw ADP.InvalidConnectionOptionValue(keyword);
77 return fullPath;
80 internal string ExpandDataDirectories(ref string filename, ref int position)
82 string value = null;
83 StringBuilder builder = new StringBuilder(_usersConnectionString.Length);
84 string datadir = null;
86 int copyPosition = 0;
87 bool expanded = false;
89 for (NameValuePair current = _keyChain; null != current; current = current.Next)
91 value = current.Value;
93 // remove duplicate keyswords from connectionstring
94 //if ((object)this[current.Name] != (object)value) {
95 // expanded = true;
96 // copyPosition += current.Length;
97 // continue;
98 //}
100 // There is a set of keywords we explictly do NOT want to expand |DataDirectory| on
101 if (_useOdbcRules)
103 switch (current.Name)
105 case DbConnectionOptionKeywords.Driver:
106 case DbConnectionOptionKeywords.Pwd:
107 case DbConnectionOptionKeywords.UID:
108 break;
109 default:
110 value = ExpandDataDirectory(current.Name, value, ref datadir);
111 break;
114 else
116 switch (current.Name)
118 case DbConnectionOptionKeywords.Provider:
119 case DbConnectionOptionKeywords.DataProvider:
120 case DbConnectionOptionKeywords.RemoteProvider:
121 case DbConnectionOptionKeywords.ExtendedProperties:
122 case DbConnectionOptionKeywords.UserID:
123 case DbConnectionOptionKeywords.Password:
124 case DbConnectionOptionKeywords.UID:
125 case DbConnectionOptionKeywords.Pwd:
126 break;
127 default:
128 value = ExpandDataDirectory(current.Name, value, ref datadir);
129 break;
132 if (null == value)
134 value = current.Value;
136 if (_useOdbcRules || (DbConnectionOptionKeywords.FileName != current.Name))
138 if (value != current.Value)
140 expanded = true;
141 AppendKeyValuePairBuilder(builder, current.Name, value, _useOdbcRules);
142 builder.Append(';');
144 else
146 builder.Append(_usersConnectionString, copyPosition, current.Length);
149 else
151 // strip out 'File Name=myconnection.udl' for OleDb
152 // remembering is value for which UDL file to open
153 // and where to insert the strnig
154 expanded = true;
155 filename = value;
156 position = builder.Length;
158 copyPosition += current.Length;
161 if (expanded)
163 value = builder.ToString();
165 else
167 value = null;
169 return value;
172 internal bool HasBlankPassword {
173 get {
174 if (!ConvertValueToIntegratedSecurity()) {
175 if (_parsetable.ContainsKey(KEY.Password)) {
176 return ADP.IsEmpty((string)_parsetable[KEY.Password]);
177 } else
178 if (_parsetable.ContainsKey(SYNONYM.Pwd)) {
179 return ADP.IsEmpty((string)_parsetable[SYNONYM.Pwd]); // MDAC 83097
180 } else {
181 return ((_parsetable.ContainsKey(KEY.User_ID) && !ADP.IsEmpty((string)_parsetable[KEY.User_ID])) || (_parsetable.ContainsKey(SYNONYM.UID) && !ADP.IsEmpty((string)_parsetable[SYNONYM.UID])));
184 return false;
190 internal static class DbConnectionOptionKeywords
192 // Odbc
193 internal const string Driver = "driver";
194 internal const string Pwd = "pwd";
195 internal const string UID = "uid";
197 // OleDb
198 internal const string DataProvider = "data provider";
199 internal const string ExtendedProperties = "extended properties";
200 internal const string FileName = "file name";
201 internal const string Provider = "provider";
202 internal const string RemoteProvider = "remote provider";
204 // common keywords (OleDb, OracleClient, SqlClient)
205 internal const string Password = "password";
206 internal const string UserID = "user id";