using System; using System.Collections.Generic; using System.Text; using System.Data.SqlClient; using System.Data.Common; using System.Data; using System.Text.RegularExpressions; namespace AnywhereTS.DBSupport { public interface IDBConnector : IDisposable where DBParameter : DbParameter, new() where DBCommand : DbCommand, new() where DBConnection : DbConnection, new() where DBDataAdapter : DbDataAdapter, new() { bool ConnectionIsOpen { get; } void CreateConnection(out Exception ErrorInfo); void OpenConnection(out Exception ErrorInfo); void CloseConnection(out Exception ErrorInfo); DbDataReader ExecuteQuery(string command, List Params, out Exception ErrorInfo); void ExecuteNonQuery(string command, List Params, out Exception ErrorInfo); List ExecuteColumnNamesReader(string command, List Params, out Exception ErrorInfo); DBCommand CreateCommandInstance(string command, List Params, out Exception ErrorInfo); bool RunScript(string strFile, out Exception ErrorInfo); } public abstract class DBConnector : IDBConnector where DBParameter : DbParameter, new() where DBCommand : DbCommand, new() where DBConnection : DbConnection, new() where DBDataAdapter : DbDataAdapter, new() { public DBConnector(string Server, string Instance, string Database) { DBServerAddress = Server; DBServerInstance = Instance; DBDatabase = Database; using (log4net.NDC.Push(string.Format("[Server={0}] [Instance={1}] [Database={2}]", Server, Instance, Database))) { Logging.DatabaseLog.Debug("Creating DBConnector instance"); } } public static string GetConnectionString() { return string.Format(@"Data Source={0}\{1};Database={2};Integrated Security=SSPI", DBServerAddress, DBServerInstance, DBDatabase); } protected DBConnection connection; #region DBServerAddress, DBServerInstance, DBDatabase internal static string DBServerAddress = ""; internal static string DBServerInstance = ""; internal static string DBDatabase = ""; #endregion #region private string SafeSqlLiteral(string inputSQL) private string SafeSqlLiteral(string inputSQL) { return inputSQL.Replace("'", "''"); } #endregion #region IDBConnector members #region public virtual bool ConnectionIsOpen public virtual bool ConnectionIsOpen { get; protected set; } #endregion #region public virtual DBCommand CreateCommandInstance(string command, List Params, out Exception ErrorInfo) public virtual DBCommand CreateCommandInstance(string command, List Params, out Exception ErrorInfo) { ErrorInfo = null; try { command = this.SafeSqlLiteral(command); DBCommand sqlComm = new DBCommand(); sqlComm.CommandText = command; sqlComm.Connection = connection; foreach (DBParameter p in Params) { sqlComm.Parameters.Add(p); } return sqlComm; } catch (SqlException ex) { using (log4net.NDC.Push(string.Format("SqlException: ID={0} MESSAGE={1}{2}Diagnostics:{2}{3}", ex.Number.ToString(), ex.Message, System.Environment.NewLine, ex.ToString()))) { Logging.DatabaseLog.Error(string.Format("Failed to create command instance using command: {0}", command)); } ErrorInfo = ex; throw ErrorInfo; } catch (Exception ex) { using (log4net.NDC.Push(string.Format("{0}: MESSAGE={1}{2}Diagnostics:{2}{3}", ex.GetType().Name, ex.Message, System.Environment.NewLine, ex.ToString()))) { Logging.DatabaseLog.Error(string.Format("Failed to create command instance using command: {0}", command)); } ErrorInfo = ex; throw ErrorInfo; } } #endregion #region public virtual void CreateConnection(out Exception ErrorInfo) public virtual void CreateConnection(out Exception ErrorInfo) { ErrorInfo = null; try { string connetionString = null; connetionString = GetConnectionString(); connection = new DBConnection(); connection.ConnectionString = connetionString; } catch (SqlException ex) { using (log4net.NDC.Push(string.Format("SqlException: ID={0} MESSAGE={1}{2}Diagnostics:{2}{3}", ex.Number.ToString(), ex.Message, System.Environment.NewLine, ex.ToString()))) { Logging.DatabaseLog.Error(string.Format("Failed to create connection to {0} Database", DBDatabase)); } ErrorInfo = ex; throw ErrorInfo; } catch (Exception ex) { using (log4net.NDC.Push(string.Format("{0}: MESSAGE={1}{2}Diagnostics:{2}{3}", ex.GetType().Name, ex.Message, System.Environment.NewLine, ex.ToString()))) { Logging.DatabaseLog.Error(string.Format("Failed to create connection to {0} Database", DBDatabase)); } ErrorInfo = ex; throw ErrorInfo; } } #endregion #region public virtual void OpenConnection(out Exception ErrorInfo) public virtual void OpenConnection(out Exception ErrorInfo) { ErrorInfo = null; try { //this.CloseConnection(out ErrorInfo); connection.Open(); this.ConnectionIsOpen = true; } //catch (SqlException ex) { Console.WriteLine(ex.ToString()); ErrorInfo = ex; throw ErrorInfo;} catch (SqlException ex) { using (log4net.NDC.Push(string.Format("SqlException: ID={0} MESSAGE={1}{2}Diagnostics:{2}{3}", ex.Number.ToString(), ex.Message, System.Environment.NewLine, ex.ToString()))) { Logging.DatabaseLog.Error(string.Format("Failed to open connection to {0} Database", DBDatabase)); } ErrorInfo = ex; throw ErrorInfo; } catch (Exception ex) { using (log4net.NDC.Push(string.Format("{0}: MESSAGE={1}{2}Diagnostics:{2}{3}", ex.GetType().Name, ex.Message, System.Environment.NewLine, ex.ToString()))) { Logging.DatabaseLog.Error(string.Format("Failed to open connection to {0} Database", DBDatabase)); } ErrorInfo = ex; throw ErrorInfo; } } #endregion #region public virtual void CloseConnection(out Exception ErrorInfo) public virtual void CloseConnection(out Exception ErrorInfo) { ErrorInfo = null; try { if (this.ConnectionIsOpen) connection.Close(); } catch (SqlException ex) { using (log4net.NDC.Push(string.Format("SqlException: ID={0} MESSAGE={1}{2}Diagnostics:{2}{3}", ex.Number.ToString(), ex.Message, System.Environment.NewLine, ex.ToString()))) { Logging.DatabaseLog.Error(string.Format("Failed to close connection to {0} Database", DBDatabase)); } ErrorInfo = ex; throw ErrorInfo; } catch (Exception ex) { using (log4net.NDC.Push(string.Format("{0}: MESSAGE={1}{2}Diagnostics:{2}{3}", ex.GetType().Name, ex.Message, System.Environment.NewLine, ex.ToString()))) { Logging.DatabaseLog.Error(string.Format("Failed to close connection to {0} Database", DBDatabase)); } ErrorInfo = ex; throw ErrorInfo; } } #endregion #region public virtual DbDataReader ExecuteQuery(string command, List Params, out Exception ErrorInfo) public virtual DbDataReader ExecuteQuery(string command, List Params, out Exception ErrorInfo) { ErrorInfo = null; if (!this.ConnectionIsOpen) { ErrorInfo = new Exception("Cannot execute query.", new Exception("A connection to the database has not, yet, been established.")); } try { command = this.SafeSqlLiteral(command); DBCommand sqlComm = new DBCommand(); sqlComm.CommandText = command; sqlComm.Connection = connection; foreach (DBParameter p in Params) { sqlComm.Parameters.Add(p); } DbDataReader r = sqlComm.ExecuteReader(); return r; } catch (SqlException ex) { using (log4net.NDC.Push(string.Format("SqlException: ID={0} MESSAGE={1}{2}Diagnostics:{2}{3}", ex.Number.ToString(), ex.Message, System.Environment.NewLine, ex.ToString()))) { Logging.DatabaseLog.Error(string.Format("Failed to execute query: {0}", command)); } ErrorInfo = ex; throw ErrorInfo; } catch (Exception ex) { using (log4net.NDC.Push(string.Format("{0}: MESSAGE={1}{2}Diagnostics:{2}{3}", ex.GetType().Name, ex.Message, System.Environment.NewLine, ex.ToString()))) { Logging.DatabaseLog.Error(string.Format("Failed to execute querey: {0}", command)); } ErrorInfo = ex; throw ErrorInfo; } } #endregion #region public virtual void ExecuteNonQuery(string command, List Params, out Exception ErrorInfo) public virtual void ExecuteNonQuery(string command, List Params, out Exception ErrorInfo) { ErrorInfo = null; if (!this.ConnectionIsOpen) { ErrorInfo = new Exception("Cannot execute non-query.", new Exception("A connection to the database has not, yet, been established.")); } try { command = this.SafeSqlLiteral(command); DBCommand sqlComm = new DBCommand(); sqlComm.CommandText = command; sqlComm.Connection = connection; foreach (DBParameter p in Params) { sqlComm.Parameters.Add(p); } sqlComm.ExecuteNonQuery(); } catch (SqlException ex) { using (log4net.NDC.Push(string.Format("SqlException: ID={0} MESSAGE={1}{2}Diagnostics:{2}{3}", ex.Number.ToString(), ex.Message, System.Environment.NewLine, ex.ToString()))) { Logging.DatabaseLog.Error(string.Format("Failed to execute non querey: {0}", command)); } ErrorInfo = ex; throw ErrorInfo; } catch (Exception ex) { using (log4net.NDC.Push(string.Format("{0}: MESSAGE={1}{2}Diagnostics:{2}{3}", ex.GetType().Name, ex.Message, System.Environment.NewLine, ex.ToString()))) { Logging.DatabaseLog.Error(string.Format("Failed to execute non querey: {0}", command)); } ErrorInfo = ex; throw ErrorInfo; } } #endregion #region public virtual List ExecuteColumnNamesReader(string command, List Params, out Exception ErrorInfo) public virtual List ExecuteColumnNamesReader(string command, List Params, out Exception ErrorInfo) { ErrorInfo = null; try { List ColumnNames = new List(); DBDataAdapter da = new DBDataAdapter(); command = this.SafeSqlLiteral(command); DBCommand sqlComm = new DBCommand(); sqlComm.CommandText = command; sqlComm.Connection = connection; foreach (DBParameter p in Params) { sqlComm.Parameters.Add(p); } da.SelectCommand = sqlComm; DataTable dt = new DataTable(); da.Fill(dt); DataRow row = dt.Rows[0]; for (int ordinal = 0; ordinal < dt.Columns.Count; ordinal++) { string value = row[ordinal].ToString(); string column_name = dt.Columns[ordinal].ColumnName; ColumnNames.Add(column_name); } return ColumnNames; } catch (SqlException ex) { using (log4net.NDC.Push(string.Format("SqlException: ID={0} MESSAGE={1}{2}Diagnostics:{2}{3}", ex.Number.ToString(), ex.Message, System.Environment.NewLine, ex.ToString()))) { Logging.DatabaseLog.Error(string.Format("Failed to get colum names from reader: {0}", command)); } ErrorInfo = ex; throw ErrorInfo; } catch (Exception ex) { using (log4net.NDC.Push(string.Format("{0}: MESSAGE={1}{2}Diagnostics:{2}{3}", ex.GetType().Name, ex.Message, System.Environment.NewLine, ex.ToString()))) { Logging.DatabaseLog.Error(string.Format("Failed to get colum names from reader: {0}", command)); } ErrorInfo = ex; throw ErrorInfo; } } #endregion #region public string[] ParseScriptToCommands(string strScript) public string[] ParseScriptToCommands(string strScript) { string[] commands; commands = strScript.Split(new string[] { string.Format("GO{0}", System.Environment.NewLine) }, StringSplitOptions.RemoveEmptyEntries); return commands; } #endregion #region public virtual bool RunScript(string strFile, out Exception ErrorInfo) public bool RunScript(string strFile, out Exception ErrorInfo) { ErrorInfo = null; try { string[] strCommands; strCommands = ParseScriptToCommands(strFile); if (this.ConnectionIsOpen) { if (!ClientRunScript(strCommands, out ErrorInfo)) { return false; } } else { Logging.DatabaseLog.Fatal(string.Format("Failed to run script: [database connection is not open] {0}{1}", System.Environment.NewLine, strFile)); return false; } } catch (SqlException ex) { using (log4net.NDC.Push(string.Format("SqlException: ID={0} MESSAGE={1}{2}Diagnostics:{2}{3}", ex.Number.ToString(), ex.Message, System.Environment.NewLine, ex.ToString()))) { Logging.DatabaseLog.Error(string.Format("Failed to run script: {0}{1}", System.Environment.NewLine, strFile)); } ErrorInfo = ex; } catch (Exception ex) { using (log4net.NDC.Push(string.Format("{0}: MESSAGE={1}{2}Diagnostics:{2}{3}", ex.GetType().Name, ex.Message, System.Environment.NewLine, ex.ToString()))) { Logging.DatabaseLog.Error(string.Format("Failed to run script: {0}{1}", System.Environment.NewLine, strFile)); } ErrorInfo = ex; } return false; } public abstract bool ClientRunScript(string[] strCommands, out Exception ErrorInfo); #endregion #endregion #region IDisposable Members public virtual void Dispose() { try { Exception ErrorInfo; CloseConnection(out ErrorInfo); } catch { } } #endregion } }