| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802 |
- //
- // System.Data.Common.DbConnectionStringBuilder.cs
- //
- // Author:
- // Sureshkumar T ([email protected])
- // Gert Driesen ([email protected]
- //
- // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
- //
- // Permission is hereby granted, free of charge, to any person obtaining
- // a copy of this software and associated documentation files (the
- // "Software"), to deal in the Software without restriction, including
- // without limitation the rights to use, copy, modify, merge, publish,
- // distribute, sublicense, and/or sell copies of the Software, and to
- // permit persons to whom the Software is furnished to do so, subject to
- // the following conditions:
- //
- // The above copyright notice and this permission notice shall be
- // included in all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- //
- #if NET_2_0
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.Collections.ObjectModel;
- using System.ComponentModel;
- using System.Data;
- using System.Data.Common;
- using System.Reflection;
- using System.Text;
- namespace System.Data.Common
- {
- public class DbConnectionStringBuilder : IDictionary, ICollection, IEnumerable, ICustomTypeDescriptor
- {
- #region Fields
- readonly Dictionary<string, object> _dictionary;
- readonly bool useOdbcRules;
- #endregion Fields
- #region Constructors
- public DbConnectionStringBuilder () : this (false)
- {
- }
- public DbConnectionStringBuilder (bool useOdbcRules)
- {
- this.useOdbcRules = useOdbcRules;
- _dictionary = new Dictionary <string, object> (StringComparer.InvariantCultureIgnoreCase);
- }
- #endregion // Constructors
- #region Properties
- [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
- [EditorBrowsable (EditorBrowsableState.Never)]
- [Browsable (false)]
- [DesignOnly (true)]
- public bool BrowsableConnectionString {
- get { throw new NotImplementedException (); }
- set { throw new NotImplementedException (); }
- }
- [RefreshProperties (RefreshProperties.All)]
- public string ConnectionString {
- get {
- IDictionary<string, object> dictionary = (IDictionary <string, object>) _dictionary;
- StringBuilder sb = new StringBuilder ();
- foreach (string key in Keys) {
- object value = null;
- if (!dictionary.TryGetValue (key, out value))
- continue;
- string val = value.ToString ();
- AppendKeyValuePair (sb, key, val, useOdbcRules);
- }
- return sb.ToString ();
- }
- set {
- Clear ();
- if (value == null)
- return;
- if (value.Trim ().Length == 0)
- return;
- ParseConnectionString (value);
- }
- }
- [Browsable (false)]
- public virtual int Count
- {
- get { return _dictionary.Count; }
- }
- [Browsable (false)]
- public virtual bool IsFixedSize
- {
- get { return false; }
- }
- [Browsable (false)]
- public bool IsReadOnly
- {
- get { throw new NotImplementedException (); }
- }
- [Browsable (false)]
- public virtual object this [string keyword] {
- get {
- if (ContainsKey (keyword))
- return _dictionary [keyword];
- else
- throw new ArgumentException (string.Format (
- "Keyword '{0}' does not exist",
- keyword));
- }
- set {
- if (value == null) {
- Remove (keyword);
- return;
- }
- if (keyword == null)
- throw new ArgumentNullException ("keyword");
- if (keyword.Length == 0)
- throw CreateInvalidKeywordException (keyword);
- for (int i = 0; i < keyword.Length; i++) {
- char c = keyword [i];
- if (i == 0 && (Char.IsWhiteSpace (c) || c == ';'))
- throw CreateInvalidKeywordException (keyword);
- if (i == (keyword.Length - 1) && Char.IsWhiteSpace (c))
- throw CreateInvalidKeywordException (keyword);
- if (Char.IsControl (c))
- throw CreateInvalidKeywordException (keyword);
- }
- if (ContainsKey (keyword))
- _dictionary [keyword] = value;
- else
- _dictionary.Add (keyword, value);
- }
- }
- [Browsable (false)]
- public virtual ICollection Keys
- {
- get {
- string [] keys = new string [_dictionary.Keys.Count];
- ((ICollection<string>) _dictionary.Keys).CopyTo (keys, 0);
- ReadOnlyCollection<string> keyColl = new ReadOnlyCollection<string> (keys);
- return keyColl;
- }
- }
- bool ICollection.IsSynchronized
- {
- get { throw new NotImplementedException (); }
- }
- object ICollection.SyncRoot
- {
- get { throw new NotImplementedException (); }
- }
- object IDictionary.this [object keyword]
- {
- get { return this [(string) keyword]; }
- set { this [(string) keyword] = value; }
- }
- [Browsable (false)]
- public virtual ICollection Values {
- get {
- object [] values = new object [_dictionary.Values.Count];
- ((ICollection<object>) _dictionary.Values).CopyTo (values, 0);
- ReadOnlyCollection<object> valuesColl = new ReadOnlyCollection<object> (values);
- return valuesColl;
- }
- }
- #endregion // Properties
- #region Methods
- public void Add (string keyword, object value)
- {
- this [keyword] = value;
- }
- public static void AppendKeyValuePair (StringBuilder builder, string keyword, string value,
- bool useOdbcRules)
- {
- if (builder == null)
- throw new ArgumentNullException ("builder");
- if (keyword == null)
- throw new ArgumentNullException ("keyName");
- if (keyword.Length == 0)
- throw new ArgumentException ("Empty keyword is not valid.");
- if (builder.Length > 0)
- builder.Append (';');
- if (!useOdbcRules)
- builder.Append (keyword.Replace ("=", "=="));
- else
- builder.Append (keyword);
- builder.Append ('=');
- if (value == null || value.Length == 0)
- return;
- if (!useOdbcRules) {
- bool dquoteFound = (value.IndexOf ('\"') > -1);
- bool squoteFound = (value.IndexOf ('\'') > -1);
-
- if (dquoteFound && squoteFound) {
- builder.Append ('\"');
- builder.Append (value.Replace ("\"", "\"\""));
- builder.Append ('\"');
- } else if (dquoteFound) {
- builder.Append ('\'');
- builder.Append (value);
- builder.Append ('\'');
- } else if (squoteFound || value.IndexOf ('=') > -1 || value.IndexOf (';') > -1) {
- builder.Append ('\"');
- builder.Append (value);
- builder.Append ('\"');
- } else if (ValueNeedsQuoting (value)) {
- builder.Append ('\"');
- builder.Append (value);
- builder.Append ('\"');
- } else
- builder.Append (value);
- } else {
- int braces = 0;
- bool semicolonFound = false;
- int len = value.Length;
- bool needBraces = false;
- int lastChar = -1;
- for (int i = 0; i < len; i++) {
- int peek = 0;
- if (i == (len - 1))
- peek = -1;
- else
- peek = value [i + 1];
- char c = value [i];
- switch (c) {
- case '{':
- braces++;
- break;
- case '}':
- if (peek.Equals (c)) {
- i++;
- continue;
- } else {
- braces--;
- if (peek != -1)
- needBraces = true;
- }
- break;
- case ';':
- semicolonFound = true;
- break;
- default:
- break;
- }
- lastChar = c;
- }
- if (value [0] == '{' && (lastChar != '}' || (braces == 0 && needBraces))) {
- builder.Append ('{');
- builder.Append (value.Replace ("}", "}}"));
- builder.Append ('}');
- return;
- }
- bool isDriver = (string.Compare (keyword, "Driver", StringComparison.InvariantCultureIgnoreCase) == 0);
- if (isDriver) {
- if (value [0] == '{' && lastChar == '}' && !needBraces) {
- builder.Append (value);
- return;
- }
- builder.Append ('{');
- builder.Append (value.Replace ("}", "}}"));
- builder.Append ('}');
- return;
- }
- if (value [0] == '{' && (braces != 0 || lastChar != '}') && needBraces) {
- builder.Append ('{');
- builder.Append (value.Replace ("}", "}}"));
- builder.Append ('}');
- return;
- }
- if (value [0] != '{' && semicolonFound) {
- builder.Append ('{');
- builder.Append (value.Replace ("}", "}}"));
- builder.Append ('}');
- return;
- }
- builder.Append (value);
- }
- }
- public static void AppendKeyValuePair (StringBuilder builder, string keyword, string value)
- {
- AppendKeyValuePair (builder, keyword, value, false);
- }
- public virtual void Clear ()
- {
- _dictionary.Clear ();
- }
- public virtual bool ContainsKey (string keyword)
- {
- if (keyword == null)
- throw new ArgumentNullException ("keyword");
- return _dictionary.ContainsKey (keyword);
- }
- public virtual bool EquivalentTo (DbConnectionStringBuilder connectionStringBuilder)
- {
- bool ret = true;
- try {
- if (Count != connectionStringBuilder.Count)
- ret = false;
- else {
- foreach (string key in Keys) {
- if (!this [key].Equals (connectionStringBuilder [key])) {
- ret = false;
- break;
- }
- }
- }
- } catch (ArgumentException) {
- ret = false;
- }
- return ret;
- }
- [MonoTODO]
- protected virtual void GetProperties (Hashtable propertyDescriptors)
- {
- throw new NotImplementedException ();
- }
- [MonoTODO]
- protected internal void ClearPropertyDescriptors ()
- {
- throw new NotImplementedException ();
- }
- public virtual bool Remove (string keyword)
- {
- if (keyword == null)
- throw new ArgumentNullException ("keyword");
- return _dictionary.Remove (keyword);
- }
- public virtual bool ShouldSerialize (string keyword)
- {
- throw new NotImplementedException ();
- }
- void ICollection.CopyTo (Array array, int index)
- {
- if (array == null)
- throw new ArgumentNullException ("array");
- KeyValuePair<string, object> [] arr = array as KeyValuePair<string, object> [];
- if (arr == null)
- throw new ArgumentException ("Target array type is not compatible with the type of items in the collection");
- ((ICollection<KeyValuePair<string, object>>) _dictionary).CopyTo (arr, index);
- }
- void IDictionary.Add (object keyword, object value)
- {
- this.Add ((string) keyword, value);
- }
- bool IDictionary.Contains (object keyword)
- {
- return ContainsKey ((string) keyword);
- }
- IDictionaryEnumerator IDictionary.GetEnumerator ()
- {
- return (IDictionaryEnumerator) _dictionary.GetEnumerator ();
- }
- void IDictionary.Remove (object keyword)
- {
- Remove ((string) keyword);
- }
- IEnumerator IEnumerable.GetEnumerator ()
- {
- return (IEnumerator) _dictionary.GetEnumerator ();
- }
- private static object _staticAttributeCollection = null;
- AttributeCollection ICustomTypeDescriptor.GetAttributes ()
- {
- object value = _staticAttributeCollection;
- if (value == null) {
- CLSCompliantAttribute clsAttr = new CLSCompliantAttribute (true);
- DefaultMemberAttribute defMemAttr = new DefaultMemberAttribute ("Item");
- Attribute [] attrs = {clsAttr, defMemAttr};
- value = new AttributeCollection (attrs);
- }
- System.Threading.Interlocked.CompareExchange (ref _staticAttributeCollection, value, null);
- return _staticAttributeCollection as AttributeCollection;
- }
- string ICustomTypeDescriptor.GetClassName ()
- {
- return this.GetType ().ToString ();
- }
- string ICustomTypeDescriptor.GetComponentName ()
- {
- return null;
- }
- TypeConverter ICustomTypeDescriptor.GetConverter ()
- {
- return new CollectionConverter ();
- }
- EventDescriptor ICustomTypeDescriptor.GetDefaultEvent ()
- {
- return null;
- }
- PropertyDescriptor ICustomTypeDescriptor.GetDefaultProperty ()
- {
- return null;
- }
- object ICustomTypeDescriptor.GetEditor (Type editorBaseType)
- {
- return null;
- }
- EventDescriptorCollection ICustomTypeDescriptor.GetEvents ()
- {
- return EventDescriptorCollection.Empty;
- }
- EventDescriptorCollection ICustomTypeDescriptor.GetEvents (Attribute [] attributes)
- {
- return EventDescriptorCollection.Empty;
- }
- PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties ()
- {
- return PropertyDescriptorCollection.Empty;
- }
- PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties (Attribute [] attributes)
- {
- return PropertyDescriptorCollection.Empty;
- }
- object ICustomTypeDescriptor.GetPropertyOwner (PropertyDescriptor pd)
- {
- throw new NotImplementedException ();
- }
- public override string ToString ()
- {
- return ConnectionString;
- }
- public virtual bool TryGetValue (string keyword, out object value)
- {
- // FIXME : not sure, difference between this [keyword] and this method
- bool found = ContainsKey (keyword);
- if (found)
- value = this [keyword];
- else
- value = null;
- return found;
- }
- static ArgumentException CreateInvalidKeywordException (string keyword)
- {
- return new ArgumentException ("A keyword cannot contain "
- + "control characters, leading semicolons or "
- + "leading or trailing whitespace.", keyword);
- }
- static ArgumentException CreateConnectionStringInvalidException (int index)
- {
- return new ArgumentException ("Format of initialization "
- + "string does not conform to specifications at "
- + "index " + index + ".");
- }
- static bool ValueNeedsQuoting (string value)
- {
- foreach (char c in value) {
- if (char.IsWhiteSpace (c))
- return true;
- }
- return false;
- }
- void ParseConnectionString (string connectionString)
- {
- if (useOdbcRules)
- ParseConnectionStringOdbc (connectionString);
- else
- ParseConnectionStringNonOdbc (connectionString);
- }
- void ParseConnectionStringOdbc (string connectionString)
- {
- bool inQuote = false;
- bool inDQuote = false;
- bool inName = true;
- bool inBraces = false;
- string name = String.Empty;
- string val = String.Empty;
- StringBuilder sb = new StringBuilder ();
- int len = connectionString.Length;
- for (int i = 0; i < len; i++) {
- char c = connectionString [i];
- int peek = (i == (len - 1)) ? -1 : connectionString [i + 1];
- switch (c) {
- case '{':
- if (inName) {
- sb.Append (c);
- continue;
- }
- if (sb.Length == 0)
- inBraces = true;
- sb.Append (c);
- break;
- case '}':
- if (inName || !inBraces) {
- sb.Append (c);
- continue;
- }
- if (peek == -1) {
- sb.Append (c);
- inBraces = false;
- } else if (peek.Equals (c)) {
- sb.Append (c);
- sb.Append (c);
- i++;
- } else {
- int next = NextNonWhitespaceChar (connectionString, i);
- if (next != -1 && ((char) next) != ';')
- throw CreateConnectionStringInvalidException (next);
- sb.Append (c);
- inBraces = false;
- }
- break;
- case ';':
- if (inName || inBraces) {
- sb.Append (c);
- continue;
- }
- if (name.Length > 0 && sb.Length > 0) {
- val = sb.ToString ();
- name = name.ToLower ().TrimEnd ();
- this [name] = val;
- } else if (sb.Length > 0)
- throw CreateConnectionStringInvalidException (c);
- inName = true;
- name = String.Empty;
- sb.Length = 0;
- break;
- case '=':
- if (inBraces || !inName) {
- sb.Append (c);
- continue;
- }
- name = sb.ToString ();
- if (name.Length == 0)
- throw CreateConnectionStringInvalidException (c);
- sb.Length = 0;
- inName = false;
- break;
- default:
- if (inDQuote || inQuote || inBraces)
- sb.Append (c);
- else if (char.IsWhiteSpace (c)) {
- // ignore leading whitespace
- if (sb.Length > 0) {
- int nextChar = SkipTrailingWhitespace (connectionString, i);
- if (nextChar == -1)
- sb.Append (c);
- else
- i = nextChar;
- }
- } else
- sb.Append (c);
- break;
- }
- }
- if ((inName && sb.Length > 0) || inDQuote || inQuote || inBraces)
- throw CreateConnectionStringInvalidException (len - 1);
- if (name.Length > 0 && sb.Length > 0) {
- val = sb.ToString ();
- name = name.ToLower ().TrimEnd ();
- this [name] = val;
- }
- }
- void ParseConnectionStringNonOdbc (string connectionString)
- {
- bool inQuote = false;
- bool inDQuote = false;
- bool inName = true;
- string name = String.Empty;
- string val = String.Empty;
- StringBuilder sb = new StringBuilder ();
- int len = connectionString.Length;
- for (int i = 0; i < len; i++) {
- char c = connectionString [i];
- int peek = (i == (len - 1)) ? -1 : connectionString [i + 1];
- switch (c) {
- case '\'':
- if (inName) {
- sb.Append (c);
- continue;
- }
- if (inDQuote)
- sb.Append (c);
- else if (inQuote) {
- if (peek == -1)
- inQuote = false;
- else if (peek.Equals (c)) {
- sb.Append (c);
- i++;
- } else {
- int next = NextNonWhitespaceChar (connectionString, i);
- if (next != -1 && ((char) next) != ';')
- throw CreateConnectionStringInvalidException (next);
- inQuote = false;
- }
- if (!inQuote) {
- val = sb.ToString ();
- name = name.ToLower ().TrimEnd ();
- this [name] = val;
- inName = true;
- name = String.Empty;
- sb.Length = 0;
- }
- } else if (sb.Length == 0)
- inQuote = true;
- else
- sb.Append (c);
- break;
- case '"':
- if (inName) {
- sb.Append (c);
- continue;
- }
- if (inQuote)
- sb.Append (c);
- else if (inDQuote) {
- if (peek == -1)
- inDQuote = false;
- else if (peek.Equals (c)) {
- sb.Append (c);
- i++;
- } else {
- int next = NextNonWhitespaceChar (connectionString, i);
- if (next != -1 && ((char) next) != ';')
- throw CreateConnectionStringInvalidException (next);
- inDQuote = false;
- }
- } else if (sb.Length == 0)
- inDQuote = true;
- else
- sb.Append (c);
- break;
- case ';':
- if (inName) {
- sb.Append (c);
- continue;
- }
- if (inDQuote || inQuote)
- sb.Append (c);
- else {
- if (name.Length > 0 && sb.Length > 0) {
- val = sb.ToString ();
- name = name.ToLower ().TrimEnd ();
- this [name] = val;
- } else if (sb.Length > 0)
- throw CreateConnectionStringInvalidException (c);
- inName = true;
- name = String.Empty;
- sb.Length = 0;
- }
- break;
- case '=':
- if (inDQuote || inQuote || !inName)
- sb.Append (c);
- else if (peek != -1 && peek.Equals (c)) {
- sb.Append (c);
- i++;
- } else {
- name = sb.ToString ();
- if (name.Length == 0)
- throw CreateConnectionStringInvalidException (c);
- sb.Length = 0;
- inName = false;
- }
- break;
- default:
- if (inDQuote || inQuote)
- sb.Append (c);
- else if (char.IsWhiteSpace (c)) {
- // ignore leading whitespace
- if (sb.Length > 0) {
- int nextChar = SkipTrailingWhitespace (connectionString, i);
- if (nextChar == -1)
- sb.Append (c);
- else
- i = nextChar;
- }
- } else
- sb.Append (c);
- break;
- }
- }
- if ((inName && sb.Length > 0) || inDQuote || inQuote)
- throw CreateConnectionStringInvalidException (len -1);
- if (name.Length > 0 && sb.Length > 0) {
- val = sb.ToString ();
- name = name.ToLower ().TrimEnd ();
- this [name] = val;
- }
- }
- static int SkipTrailingWhitespace (string value, int index)
- {
- int len = value.Length;
- for (int i = (index + 1); i < len; i++) {
- char c = value [i];
- if (c == ';')
- return (i - 1);
- if (!char.IsWhiteSpace (c))
- return -1;
- }
- return len - 1;
- }
- static int NextNonWhitespaceChar (string value, int index)
- {
- int len = value.Length;
- for (int i = (index + 1); i < len; i++) {
- char c = value [i];
- if (!char.IsWhiteSpace (c))
- return (int) c;
- }
- return -1;
- }
- #endregion // Public Methods
- }
- }
- #endif // NET_2_0 using
|