Merge pull request #350 from robwilkens/bug1089
[mono.git] / mcs / class / System.Data / System.Data.Common / DbConnectionOptions.cs
1 //
2 // System.Data.Common.DbConnectionOptions
3 //      adapted from older (pre beta1) DbConnectionString
4 //
5 // Authors:
6 //      Tim Coleman (tim@timcoleman.com)
7 //      Sebastien Pouliot  <sebastien@ximian.com>
8 //
9 // Copyright (C) Tim Coleman, 2003
10 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
11 //
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
19 // 
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
22 // 
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 //
31
32 #if NET_2_0
33
34 using System.Collections;
35 using System.Collections.Specialized;
36 using System.Security;
37 using System.Text;
38
39 namespace System.Data.Common {
40
41         internal class DbConnectionOptions {
42
43                 #region Fields
44
45                 internal NameValueCollection options;
46                 internal string normalizedConnectionString;
47
48                 #endregion // Fields
49
50                 #region Constructors
51
52                 internal DbConnectionOptions ()
53                 {
54                 }
55
56                 protected internal DbConnectionOptions (DbConnectionOptions connectionOptions)
57                 {
58                         options = connectionOptions.options;
59                 }
60
61                 public DbConnectionOptions (string connectionString)
62                 {
63                         options = new NameValueCollection ();
64                         ParseConnectionString (connectionString);
65                 }
66                 
67                 [MonoTODO]
68                 public DbConnectionOptions (string connectionString, Hashtable synonyms, bool useFirstKeyValuePair)
69                         : this (connectionString)
70                 {
71                 }
72
73                 #endregion // Constructors
74
75                 #region Properties
76
77                 [MonoTODO]
78                 public bool IsEmpty {
79                         get { throw new NotImplementedException (); }
80                 }
81
82                 public string this [string keyword] {
83                         get { return options [keyword]; }
84                 }
85
86                 public ICollection Keys {
87                         get { return options.Keys; }
88                 }
89
90                 #endregion // Properties
91
92                 #region Methods
93
94                 [MonoTODO]
95                 protected void BuildConnectionString (StringBuilder builder, string[] withoutOptions, string insertValue)
96                 {
97                         throw new NotImplementedException ();
98                 }
99
100                 public bool ContainsKey (string keyword)
101                 {
102                         return (options.Get (keyword) != null);
103                 }
104
105                 public bool ConvertValueToBoolean (string keyname, bool defaultvalue)
106                 {
107                         if (ContainsKey (keyname))
108                                 return Boolean.Parse (this [keyname].Trim ());
109                         return defaultvalue;
110                 }
111
112                 public int ConvertValueToInt32 (string keyname, int defaultvalue)
113                 {
114                         if (ContainsKey (keyname))
115                                 return Int32.Parse (this [keyname].Trim ());
116                         return defaultvalue;
117                 }
118
119                 [MonoTODO]
120                 public bool ConvertValueToIntegratedSecurity ()
121                 {
122                         throw new NotImplementedException ();
123                 }
124
125                 public string ConvertValueToString (string keyname, string defaultValue)
126                 {
127                         if (ContainsKey (keyname))
128                                 return this [keyname];
129                         return defaultValue;
130                 }
131
132                 [MonoTODO]
133                 protected internal virtual PermissionSet CreatePermissionSet ()
134                 {
135                         throw new NotImplementedException ();
136                 }
137
138                 [MonoTODO]
139                 protected internal virtual string Expand ()
140                 {
141                         throw new NotImplementedException ();
142                 }
143
144                 [MonoTODO]
145                 public static string RemoveKeyValuePairs (string connectionString, string[] keynames)
146                 {
147                         throw new NotImplementedException ();
148                 }
149
150                 [MonoTODO]
151                 public string UsersConnectionString (bool hisPasswordPwd)
152                 {
153                         throw new NotImplementedException ();
154                 }
155
156                 internal void ParseConnectionString (string connectionString)
157                 {
158                         if (connectionString.Length == 0)
159                                 return;
160
161                         connectionString += ";";
162
163                         bool inQuote = false;
164                         bool inDQuote = false;
165                         bool inName = true;
166
167                         string name = String.Empty;
168                         string value = String.Empty;
169                         StringBuilder sb = new StringBuilder ();
170
171                         for (int i = 0; i < connectionString.Length; i += 1) {
172                                 char c = connectionString [i];
173                                 char peek;
174                                 if (i == connectionString.Length - 1)
175                                         peek = '\0';
176                                 else 
177                                         peek = connectionString [i + 1];
178
179                                 switch (c) {
180                                 case '\'':
181                                         if (inDQuote) 
182                                                 sb.Append (c);
183                                         else if (peek.Equals (c)) {
184                                                 sb.Append (c);
185                                                 i += 1;
186                                         }
187                                         else 
188                                                 inQuote = !inQuote;
189                                         break;
190                                 case '"':
191                                         if (inQuote) 
192                                                 sb.Append (c);
193                                         else if (peek.Equals (c)) {
194                                                 sb.Append (c);
195                                                 i += 1;
196                                         }
197                                         else 
198                                                 inDQuote = !inDQuote;
199                                         break;
200                                 case ';':
201                                         if (inDQuote || inQuote)
202                                                 sb.Append (c);
203                                         else {
204                                                 if (name != String.Empty && name != null) {
205                                                         value = sb.ToString ();
206                                                         // FIXME - KeywordLookup is an NOP
207                                                         // options [KeywordLookup (name.Trim ())] = value;
208                                                         options [name.Trim ()] = value;
209                                                 }
210                                                 inName = true;
211                                                 name = String.Empty;
212                                                 value = String.Empty;
213                                                 sb = new StringBuilder ();
214                                         }
215                                         break;
216                                 case '=':
217                                         if (inDQuote || inQuote || !inName)
218                                                 sb.Append (c);
219                                         else if (peek.Equals (c)) {
220                                                 sb.Append (c);
221                                                 i += 1;
222                                         } 
223                                         else {
224                                                 name = sb.ToString ();
225                                                 sb = new StringBuilder ();
226                                                 inName = false;
227                                         }
228                                         break;
229                                 case ' ':
230                                         if (inQuote || inDQuote)
231                                                 sb.Append (c);
232                                         else if (sb.Length > 0 && !peek.Equals (';'))
233                                                 sb.Append (c);
234                                         break;
235                                 default:
236                                         sb.Append (c);
237                                         break;
238                                 }
239                         }       
240                         
241                         StringBuilder normalized = new StringBuilder ();
242                         ArrayList keys = new ArrayList ();
243                         keys.AddRange (Keys);
244                         keys.Sort ();
245                         foreach (string key in keys)
246                         {
247                                 string entry = String.Format ("{0}=\"{1}\";", key, this [key].Replace ("\"", "\"\""));
248                                 normalized.Append (entry);
249                         }
250                         normalizedConnectionString = normalized.ToString ();
251                 }
252
253                 #endregion // Methods
254         }
255 }
256
257 #endif