1 // created on 6/21/2004
3 // Npgsql.NpgsqlConnecionString.cs
6 // Glen Parker (glenebob@nwlink.com)
8 // Copyright (C) 2002 The Npgsql Development Team
9 // npgsql-general@gborg.postgresql.org
10 // http://gborg.postgresql.org/project/npgsql/projdisplay.php
12 // This library is free software; you can redistribute it and/or
13 // modify it under the terms of the GNU Lesser General Public
14 // License as published by the Free Software Foundation; either
15 // version 2.1 of the License, or (at your option) any later version.
17 // This library is distributed in the hope that it will be useful,
18 // but WITHOUT ANY WARRANTY; without even the implied warranty of
19 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 // Lesser General Public License for more details.
22 // You should have received a copy of the GNU Lesser General Public
23 // License along with this library; if not, write to the Free Software
24 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 using System
.Collections
;
29 using System
.Collections
.Specialized
;
31 using System
.Resources
;
36 /// Represents a connection string.
38 internal sealed class NpgsqlConnectionString
: IEnumerable
40 // Logging related values
41 private static readonly String CLASSNAME
= "NpgsqlConnectionString";
42 private static System
.Resources
.ResourceManager resman
;
44 private String connection_string
= null;
45 private ListDictionary connection_string_values
;
47 static NpgsqlConnectionString()
49 resman
= new System
.Resources
.ResourceManager(typeof(NpgsqlConnectionString
));
52 private NpgsqlConnectionString(NpgsqlConnectionString Other
)
54 connection_string
= Other
.connection_string
;
55 connection_string_values
= new ListDictionary(CaseInsensitiveComparer
.Default
);
56 foreach (DictionaryEntry DE
in Other
.connection_string_values
) {
57 connection_string_values
.Add(DE
.Key
, DE
.Value
);
61 private NpgsqlConnectionString(ListDictionary Values
)
63 connection_string_values
= Values
;
67 /// Return an exact copy of this NpgsqlConnectionString.
69 public NpgsqlConnectionString
Clone()
71 return new NpgsqlConnectionString(this);
74 IEnumerator IEnumerable
.GetEnumerator()
76 return connection_string_values
.GetEnumerator();
80 /// This method parses a connection string and returns a new NpgsqlConnectionString object.
82 public static NpgsqlConnectionString
ParseConnectionString(String CS
)
84 ListDictionary new_values
= new ListDictionary(CaseInsensitiveComparer
.Default
);
88 // Get the key-value pairs delimited by ;
89 pairs
= CS
.Split(';');
91 // Now, for each pair, get its key=value.
92 foreach(String sraw
in pairs
)
94 String s
= sraw
.Trim();
95 String Key
= "", Value
= "";
102 // Split this chunk on the first CONN_ASSIGN only.
103 keyvalue
= s
.Split(new Char
[] {'='}
, 2);
105 // Keys always get trimmed and uppercased.
106 Key
= keyvalue
[0].Trim().ToUpper();
108 // Make sure the key is even there...
109 if (Key
.Length
== 0) {
110 throw new ArgumentException(resman
.GetString("Exception_WrongKeyVal"), "<BLANK>");
113 // We don't expect keys this long, and it might be about to be put
114 // in an error message, so makes sure it is a sane length.
115 if (Key
.Length
> 20) {
116 Key
= Key
.Substring(0, 20);
119 // Check if there is a key-value pair.
120 if (keyvalue
.Length
!= 2) {
121 throw new ArgumentException(resman
.GetString("Exception_WrongKeyVal"), Key
);
124 // Values always get trimmed.
125 Value
= keyvalue
[1].Trim();
127 // Substitute the real key name if this is an alias key (ODBC stuff for example)...
128 String AliasKey
= (string)ConnectionStringKeys
.Aliases
[Key
];
130 if (AliasKey
!= null) {
134 // Add the pair to the dictionary..
135 new_values
.Add(Key
, Value
);
138 return new NpgsqlConnectionString(new_values
);
142 /// Case insensative accessor for indivual connection string values.
144 public String
this[String Key
]
148 return (String
)connection_string_values
[Key
];
152 connection_string_values
[Key
] = value;
153 connection_string
= null;
158 /// Report whether a value with the provided key name exists in this connection string.
160 public Boolean
Contains(String Key
)
162 return connection_string_values
.Contains(Key
);
166 /// Return a clean string representation of this connection string.
168 public override String
ToString()
170 if (connection_string
== null) {
171 StringBuilder S
= new StringBuilder();
173 foreach (DictionaryEntry DE
in this) {
174 S
.AppendFormat("{0}={1};", DE
.Key
, DE
.Value
);
177 connection_string
= S
.ToString();
180 return connection_string
;
184 /// Return a string value from the current connection string, even if the
185 /// given key is not in the string or if the value is null.
187 public String
ToString(String Key
)
189 return ToString(Key
, "");
193 /// Return a string value from the current connection string, even if the
194 /// given key is not in the string or if the value is null.
196 public String
ToString(String Key
, String Default
)
198 if (! connection_string_values
.Contains(Key
)) {
202 return Convert
.ToString(connection_string_values
[Key
]);
206 /// Return an integer value from the current connection string, even if the
207 /// given key is not in the string or if the value is null.
208 /// Throw an appropriate exception if the value cannot be coerced to an integer.
210 public Int32
ToInt32(String Key
)
212 return ToInt32(Key
, 0);
216 /// Return an integer value from the current connection string, even if the
217 /// given key is not in the string or if the value is null.
218 /// Throw an appropriate exception if the value cannot be coerced to an integer.
220 public Int32
ToInt32(String Key
, Int32 Min
, Int32 Max
)
222 return ToInt32(Key
, Min
, Max
, 0);
226 /// Return an integer value from the current connection string, even if the
227 /// given key is not in the string or if the value is null.
228 /// Throw an appropriate exception if the value cannot be coerced to an integer.
230 public Int32
ToInt32(String Key
, Int32 Default
)
232 if (! connection_string_values
.Contains(Key
)) {
237 return Convert
.ToInt32(connection_string_values
[Key
]);
238 } catch (Exception E
) {
239 throw new ArgumentException(String
.Format(resman
.GetString("Exception_InvalidIntegerKeyVal"), Key
), Key
, E
);
244 /// Return an integer value from the current connection string, even if the
245 /// given key is not in the string.
246 /// Throw an appropriate exception if the value cannot be coerced to an integer.
248 public Int32
ToInt32(String Key
, Int32 Min
, Int32 Max
, Int32 Default
)
252 V
= ToInt32(Key
, Default
);
255 throw new ArgumentException(String
.Format(resman
.GetString("Exception_IntegerKeyValMin"), Key
, Min
), Key
);
258 throw new ArgumentException(String
.Format(resman
.GetString("Exception_IntegerKeyValMax"), Key
, Max
), Key
);
265 /// Return a boolean value from the current connection string, even if the
266 /// given key is not in the string.
267 /// Throw an appropriate exception if the value is not recognized as a boolean.
269 public Boolean
ToBool(String Key
)
271 return ToBool(Key
, false);
275 /// Return a boolean value from the current connection string, even if the
276 /// given key is not in the string.
277 /// Throw an appropriate exception if the value is not recognized as a boolean.
279 public Boolean
ToBool(String Key
, Boolean Default
)
281 if (! connection_string_values
.Contains(Key
)) {
285 switch (connection_string_values
[Key
].ToString().ToLower()) {
299 throw new ArgumentException(String
.Format(resman
.GetString("Exception_InvalidBooleanKeyVal"), Key
), Key
);
305 /// Return a ProtocolVersion from the current connection string, even if the
306 /// given key is not in the string.
307 /// Throw an appropriate exception if the value is not recognized as
310 public ProtocolVersion
ToProtocolVersion(String Key
)
312 if (! connection_string_values
.Contains(Key
)) {
313 return ProtocolVersion
.Version3
;
316 switch (ToInt32(Key
)) {
318 return ProtocolVersion
.Version2
;
321 return ProtocolVersion
.Version3
;
324 throw new ArgumentException(String
.Format(resman
.GetString("Exception_InvalidProtocolVersionKeyVal"), Key
), Key
);
332 /// Know connection string keys.
334 internal abstract class ConnectionStringKeys
336 public static readonly String Host
= "SERVER";
337 public static readonly String Port
= "PORT";
338 public static readonly String Protocol
= "PROTOCOL";
339 public static readonly String Database
= "DATABASE";
340 public static readonly String UserName
= "USER ID";
341 public static readonly String Password
= "PASSWORD";
342 public static readonly String SSL
= "SSL";
343 public static readonly String Encoding
= "ENCODING";
344 public static readonly String Timeout
= "TIMEOUT";
346 // These are for the connection pool
347 public static readonly String Pooling
= "POOLING";
348 public static readonly String MinPoolSize
= "MINPOOLSIZE";
349 public static readonly String MaxPoolSize
= "MAXPOOLSIZE";
351 // A list of aliases for some of the above values. If one of these aliases is
352 // encountered when parsing a connection string, it's real key name will
353 // be used instead. These will be reflected if ToString() is used to inspect
355 private static ListDictionary _aliases
;
357 static ConnectionStringKeys()
359 _aliases
= new ListDictionary();
361 // Aliases to help catch common errors.
362 _aliases
.Add("DB", Database
);
363 _aliases
.Add("HOST", Host
);
364 _aliases
.Add("USER", UserName
);
365 _aliases
.Add("USERID", UserName
);
366 _aliases
.Add("USER NAME", UserName
);
367 _aliases
.Add("USERNAME", UserName
);
368 _aliases
.Add("PSW", Password
);
370 // Aliases to make migration from ODBC easier.
371 _aliases
.Add("UID", UserName
);
372 _aliases
.Add("PWD", Password
);
375 public static IDictionary Aliases
385 /// Connection string default values.
387 internal abstract class ConnectionStringDefaults
389 // Connection string defaults
390 public static readonly Int32 Port
= 5432;
391 public static readonly String Encoding
= "SQL_ASCII";
392 public static readonly Boolean Pooling
= true;
393 public static readonly Int32 MinPoolSize
= 1;
394 public static readonly Int32 MaxPoolSize
= 20;
395 public static readonly Int32 Timeout
= 15; // Seconds