#region Disclaimer / License // Copyright (C) 2009, Kenneth Skovhede // http://www.hexad.dk, opensource@hexad.dk // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // #endregion using System; using System.Collections; using System.Collections.Specialized; namespace OSGeo.MapGuide.Maestro.ResourceEditors.FeatureSourceEditors.ODBC { /// /// Contains static methods for manipulating a connectionstring /// public class ConnectionStringManager { /// /// A list of known setting names for the user id /// private static string[] m_Uid = new string[] { "Uid", "User Id", "User" }; /// /// A list of known setting names for the password /// private static string[] m_Pwd = new string[] { "Pwd", "Password" }; /// /// A list of alternative Pwd names for known providers /// private static string[] m_PwdOverrides = new string[] { "{Oracle ODBC Driver}", "Password", "{MySQL ODBC 3.51 Driver}", "Password" }; /// /// A list of alternative Uid names for known providers /// private static string[] m_UidOverrides = new string[] { "{Oracle ODBC Driver}", "User Id", "{MySQL ODBC 3.51 Driver}", "User" }; /// /// Builds a file based connection string /// /// Feature source /// Name of file /// A full connectionstring public static string BuildConnectionString(OSGeo.MapGuide.MaestroAPI.FeatureSource item, string file) { ArrayList parts = new ArrayList(); int x = file.LastIndexOf("."); string ext = ""; if (x >= 0) ext = file.Substring(x + 1).Trim().ToLower(); switch(ext) { case "mdb": parts.Add("Driver={Microsoft Access Driver (*.mdb)}"); parts.Add("Dbq=" + file); break; case "asc": case "csv": case "tab": case "txt": parts.Add("Driver={Microsoft Text Driver (*.txt; *.csv)}"); parts.Add("Dbq=" + file); parts.Add("Extensions=asc,csv,tab,txt"); break; case "xls": parts.Add("Driver={Microsoft Excel Driver (*.xls)}"); parts.Add("DriverId=790"); parts.Add("Dbq=" + file); break; case "sqlite": case "db": parts.Add("DRIVER=SQLite3 ODBC Driver"); parts.Add("LongNames=0"); parts.Add("Timeout=1000"); parts.Add("NoTXN=0"); parts.Add("SyncPragma=NORMAL"); parts.Add("StepAPI=0"); parts.Add("Database=" + file); break; case "fdb": parts.Add("Driver=Firebird/InterBase(r) driver"); parts.Add("DbName=" + file); break; case "dbf": parts.Add("Driver={Microsoft dBASE Driver (*.dbf)}"); parts.Add("DriverID=277"); parts.Add("Dbq=" + file); break; default: parts.Add("Driver="); parts.Add("=" + file); break; } NameValueCollection nvc = SplitConnectionString(string.Join(";", (string[])parts.ToArray(typeof(string)))); NameValueCollection nv = SplitConnectionString(item.Parameter["ConnectionString"]); MergeCredentialsIntoConnectionString(nv, nvc); return JoinConnectionString(nvc); } /// /// Returns the user id from the connection string /// /// The parsed connectionstring setting dictionary /// The user id found in the connectionstring public static string GetUserId(NameValueCollection nv) { foreach(string s in m_Uid) if (nv[s] != null) return nv[s]; return ""; } /// /// Returns the password from the connection string /// /// The parsed connectionstring setting dictionary /// The password found in the connectionstring public static string GetPassword(NameValueCollection nv) { foreach(string s in m_Pwd) if (nv[s] != null) return nv[s]; return ""; } /// /// Inserts user id and password from the previous dictionary into the new. /// /// The dictionary containing the credentials /// The dictionary recieving the credentials public static void MergeCredentialsIntoConnectionString(NameValueCollection prevDict, NameValueCollection newDict) { newDict[GetUidName(newDict)] = GetUserId(prevDict); newDict[GetPwdName(newDict)] = GetPassword(prevDict); } /// /// Gets the name of the Pwd setting for the given provider /// /// The parsed connectionstring setting dictionary /// The name of the Pwd field for the given provider public static string GetPwdName(NameValueCollection nv) { string pwdname = m_Pwd[0]; for(int i = 0; i < m_PwdOverrides.Length; i+=2) if (m_PwdOverrides[i].ToLower().Trim() == nv["Driver"] || m_PwdOverrides[i].ToLower().Trim() == nv["Provider"]) pwdname = m_PwdOverrides[i + 1]; return pwdname; } /// /// Gets the name of the Uid setting for the given provider /// /// The parsed connectionstring setting dictionary /// The name of the Uid field for the given provider public static string GetUidName(NameValueCollection nv) { string uidname = m_Uid[0]; for(int i = 0; i < m_UidOverrides.Length; i+=2) if (m_UidOverrides[i].ToLower().Trim() == nv["Driver"] || m_UidOverrides[i].ToLower().Trim() == nv["Provider"]) uidname = m_UidOverrides[i + 1]; return uidname; } /// /// Parses a connection string, and returns a dictionary of settings /// /// The connectionstring to parse /// The setting dictionary public static NameValueCollection SplitConnectionString(string connectionstring) { return SplitConnectionString(connectionstring, ';'); } /// /// Parses a connection string, and returns a dictionary of settings /// /// The connectionstring to parse /// The charater that separates the items /// The setting dictionary public static NameValueCollection SplitConnectionString(string connectionstring, char separator) { if (connectionstring == null) return new NameValueCollection(); NameValueCollection ht = new NameValueCollection(); foreach(string s in TokenizeConnectionString(connectionstring, separator, -1)) { if (s.Trim().Length > 0) { string[] pars = TokenizeConnectionString(s, '=', 2); if (pars.Length == 2) ht[pars[0]] = pars[1]; else ht[s] = ""; } } return ht; } /// /// Tokenizes a connectionstring by a delimiter. /// Curly braces and backslash escapes. /// Double delim also escapes. /// /// The connectionstring to tokenize /// The delimiting character /// The max number of pairs to return /// An array of tokens private static string[] TokenizeConnectionString(string connectionstring, char delim, int maxcount) { bool inCurly = false; ArrayList vals = new ArrayList(); int first = 0; for(int i = 0; i < connectionstring.Length; i++) { //Everything in a curly is escaped if (inCurly) { if (connectionstring[i] == '}') inCurly = false; continue; } if (connectionstring[i] == '{') { inCurly = true; continue; } if (connectionstring[i] == delim) { if (vals.Count + 1 == maxcount) { vals.Add(connectionstring.Substring(first)); first = connectionstring.Length; break; } vals.Add(connectionstring.Substring(first, i - first)); first = i + 1; } //Backslash escapes the next char if (connectionstring[i] == '\\') i++; } if (first <= connectionstring.Length - 1) vals.Add(connectionstring.Substring(first)); return (string[])vals.ToArray(typeof(string)); } /// /// Builds a connection string from a setting dictionary /// /// The dictionary to build the connection string from /// The combined connection string public static string JoinConnectionString(NameValueCollection ht) { string[] items = new string[ht.Keys.Count]; for(int i = 0; i < ht.Keys.Count; i++) items[i] = ht.Keys[i] + "=" + ht[ht.Keys[i]]; return string.Join(";", items); } /// /// Inserts known default values into the setting dictionary /// /// The dictionary to update /// The ODBC driver name public static void InsertDefaultValues(NameValueCollection nv, string drivername) { switch(drivername) { case "{MySQL ODBC 3.51 Driver}": SetDefault(nv, "Server", "localhost"); SetDefault(nv, "Port", "3306"); SetDefault(nv, "Option", "3"); SetDefault(nv, "Database", "database"); break; case "{SQL Server}": SetDefault(nv, "Server", "localhost"); SetDefault(nv, "Database", "database"); break; case "{PostgreSQL}": SetDefault(nv, "Server", "127.0.0.1"); SetDefault(nv, "Port", "5432"); SetDefault(nv, "Database", "database"); break; case "{INFORMIX 3.30 32 BIT}": SetDefault(nv, "Host", "hostname"); SetDefault(nv, "Server", "localhost"); SetDefault(nv, "Service", "service-name"); SetDefault(nv, "Protocol", "olsoctcp"); SetDefault(nv, "Database", "database"); break; case "{Microsoft ODBC for Oracle}": SetDefault(nv, "Server", "localhost"); SetDefault(nv, "Database", "database"); break; case "{Oracle ODBC Driver}": SetDefault(nv, "Dbq", "Database"); break; } } private static void SetDefault(NameValueCollection nv, string propertyname, string value) { if (nv[propertyname] == null || nv[propertyname].Trim().Length == 0) nv[propertyname] = value; } } }