2006-02-29 Carlos Alberto Cortez <calberto.cortez@gmail.com>
[mono.git] / mcs / class / ByteFX.Data / Common / ConnectionString.cs
1 // ByteFX.Data data access components for .Net\r
2 // Copyright (C) 2002-2003  ByteFX, Inc.\r
3 //\r
4 // This library is free software; you can redistribute it and/or\r
5 // modify it under the terms of the GNU Lesser General Public\r
6 // License as published by the Free Software Foundation; either\r
7 // version 2.1 of the License, or (at your option) any later version.\r
8 // \r
9 // This library is distributed in the hope that it will be useful,\r
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of\r
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
12 // Lesser General Public License for more details.\r
13 // \r
14 // You should have received a copy of the GNU Lesser General Public\r
15 // License along with this library; if not, write to the Free Software\r
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
17 \r
18 using System;\r
19 using System.Collections.Specialized;\r
20 \r
21 namespace ByteFX.Data.Common\r
22 {\r
23         /// <summary>\r
24         /// Summary description for Utility.\r
25         /// </summary>\r
26         internal class ConnectionString\r
27         {\r
28                 private StringDictionary        elements;\r
29                 private string                          connString;\r
30 \r
31                 public ConnectionString(string connString)\r
32                 {\r
33                         this.connString = connString;\r
34                         elements = new StringDictionary();\r
35                         Parse( connString );\r
36                 }\r
37 \r
38                 public string Value\r
39                 {\r
40                         get { return connString; }\r
41                 }\r
42 \r
43                 public string this[string key] \r
44                 {\r
45                         get \r
46                         { \r
47                                 string val = elements[key];\r
48                                 return val;\r
49                         }\r
50                 }\r
51 \r
52                 public int  GetIntOption( string key, int defaultvalue ) \r
53                 {\r
54                         string val = this[ key ];\r
55                         if (null == val) return defaultvalue;\r
56                         return Convert.ToInt32( val );\r
57                 }\r
58 \r
59                 public bool  GetBoolOption( string key, bool defaultvalue ) \r
60                 {\r
61                         string val = this[ key ];\r
62                         if (null == val) return defaultvalue;\r
63                         val = val.ToLower();\r
64                         if (val == "true" || val == "yes") return true;\r
65                         return false;\r
66                 }\r
67 \r
68                 public bool Contains( string key ) \r
69                 {\r
70                         return elements.ContainsKey(key);\r
71                 }\r
72 \r
73                 public bool Equals( ConnectionString obj ) \r
74                 {\r
75                         foreach (string key in elements.Keys) \r
76                         {\r
77                                 if (! obj.Contains(key)) return false;\r
78                                 if ( ! this[key].Equals( obj[key] )) return false;\r
79                         }\r
80                         return true;\r
81                 }\r
82 \r
83                 /// <summary>\r
84                 /// \r
85                 /// </summary>\r
86                 /// <param name="obj"></param>\r
87                 /// <returns></returns>\r
88                 public bool PoolingEquals( ConnectionString obj ) \r
89                 {\r
90                         foreach (string key in elements.Keys) \r
91                         {\r
92                                 // these connection string elements only affect pooling\r
93                                 // so we don't check them when making sure connection strings\r
94                                 // are alike\r
95                                 if (key.Equals("connection lifetime")) continue;\r
96                                 if (key.Equals("connection reset")) continue;\r
97                                 if (key.Equals("enlist")) continue;\r
98                                 if (key.Equals("max pool size")) continue;\r
99                                 if (key.Equals("min pool size")) continue;\r
100                                 if (key.Equals("pooling")) continue;\r
101 \r
102                                 if (! obj.Contains(key)) return false;\r
103                                 if ( ! this[key].Equals( obj[key] )) return false;\r
104                         }\r
105                         return true;\r
106                 }\r
107 \r
108                 /// <summary>\r
109                 /// \r
110                 /// </summary>\r
111                 /// <param name="s"></param>\r
112                 public void Parse( String s ) \r
113                 {\r
114                         String[] keyvalues = s.Split( ';' );\r
115                         String[] newkeyvalues = new String[keyvalues.Length];\r
116                         int              x = 0;\r
117 \r
118                         elements.Clear();\r
119 \r
120                         // first run through the array and check for any keys that\r
121                         // have ; in their value\r
122                         foreach (String keyvalue in keyvalues) \r
123                         {\r
124                                 // check for trailing ; at the end of the connection string\r
125                                 if (keyvalue.Length == 0) continue;\r
126 \r
127                                 // this value has an '=' sign so we are ok\r
128                                 if (keyvalue.IndexOf('=') >= 0) \r
129                                 {\r
130                                         newkeyvalues[x++] = keyvalue;\r
131                                 }\r
132                                 else \r
133                                 {\r
134                                         newkeyvalues[x-1] += ";";\r
135                                         newkeyvalues[x-1] += keyvalue;\r
136                                 }\r
137                         }\r
138 \r
139                         // now we run through our normalized key-values, splitting on equals\r
140                         for (int y=0; y < x; y++) \r
141                         {\r
142                                 String[] parts = newkeyvalues[y].Split( '=' );\r
143 \r
144                                 // first trim off any space and lowercase the key\r
145                                 parts[0] = parts[0].Trim().ToLower();\r
146                                 parts[1] = parts[1].Trim();\r
147 \r
148                                 // normalize the keys going in.  We want to support the same synonyms that\r
149                                 // SqlClient supports\r
150                                 switch (parts[0]) \r
151                                 {\r
152                                         case "uid": parts[0] = "user id"; break;\r
153                                         case "pwd": parts[0] = "password"; break;\r
154                                         case "user": parts[0] = "user id"; break;\r
155                                         case "initial catalog": parts[0] = "database"; break;\r
156                                         case "server": parts[0] = "data source"; break;\r
157                                 }\r
158 \r
159                                 // we also want to clear off any quotes\r
160                                 String newvalue = parts[1].Trim( '\'' );\r
161                                 if (newvalue.Length == parts[1].Length) \r
162                                 {\r
163                                         newvalue = parts[1].Trim('"');\r
164                                 }\r
165                                 parts[1] = newvalue;\r
166 \r
167                                 // make sure we don't get dupliate keys\r
168                                 if (elements.ContainsKey(parts[0])) \r
169                                 {\r
170                                         throw new ArgumentException("Duplicate key in connection string", parts[0]);\r
171                                 }\r
172 \r
173                                 elements.Add( parts[0], parts[1] );\r
174 \r
175                                 // now put the correct parsed string into the connection string !! (AG 4/8/2003)\r
176                                 connString="";\r
177                                 foreach(string key in elements.Keys)\r
178                                 {\r
179                                         connString=connString+key+"="+elements[key]+"; ";\r
180                                 }\r
181                                 connString=connString.Substring(0,connString.Length-2);\r
182                         }\r
183                 }\r
184         }\r
185 }\r