📄 adonetappender.cs
字号:
InitializeDatabaseCommand();
}
#endregion
#region Override implementation of AppenderSkeleton
/// <summary>
/// Override the parent method to close the database
/// </summary>
/// <remarks>
/// <para>
/// Closes the database command and database connection.
/// </para>
/// </remarks>
override protected void OnClose()
{
base.OnClose();
// Close the cached command and connection objects
if (m_dbCommand != null)
{
try
{
m_dbCommand.Dispose();
}
catch (Exception ex)
{
LogLog.Warn("AdoNetAppender: Exception while disposing cached command object", ex);
}
m_dbCommand = null;
}
if (m_dbConnection != null)
{
try
{
m_dbConnection.Close();
}
catch (Exception ex)
{
LogLog.Warn("AdoNetAppender: Exception while disposing cached connection object", ex);
}
m_dbConnection = null;
}
}
#endregion
#region Override implementation of BufferingAppenderSkeleton
/// <summary>
/// Inserts the events into the database.
/// </summary>
/// <param name="events">The events to insert into the database.</param>
/// <remarks>
/// <para>
/// Insert all the events specified in the <paramref name="events"/>
/// array into the database.
/// </para>
/// </remarks>
override protected void SendBuffer(LoggingEvent[] events)
{
if (m_reconnectOnError && (m_dbConnection == null || m_dbConnection.State != ConnectionState.Open))
{
LogLog.Debug("AdoNetAppender: Attempting to reconnect to database. Current Connection State: " + ((m_dbConnection==null)?"<null>":m_dbConnection.State.ToString()) );
InitializeDatabaseConnection();
InitializeDatabaseCommand();
}
// Check that the connection exists and is open
if (m_dbConnection != null && m_dbConnection.State == ConnectionState.Open)
{
if (m_useTransactions)
{
// Create transaction
// NJC - Do this on 2 lines because it can confuse the debugger
IDbTransaction dbTran = null;
try
{
dbTran = m_dbConnection.BeginTransaction();
SendBuffer(dbTran, events);
// commit transaction
dbTran.Commit();
}
catch(Exception ex)
{
// rollback the transaction
if (dbTran != null)
{
try
{
dbTran.Rollback();
}
catch(Exception)
{
// Ignore exception
}
}
// Can't insert into the database. That's a bad thing
ErrorHandler.Error("Exception while writing to database", ex);
}
}
else
{
// Send without transaction
SendBuffer(null, events);
}
}
}
#endregion // Override implementation of BufferingAppenderSkeleton
#region Public Instance Methods
/// <summary>
/// Adds a parameter to the command.
/// </summary>
/// <param name="parameter">The parameter to add to the command.</param>
/// <remarks>
/// <para>
/// Adds a parameter to the ordered list of command parameters.
/// </para>
/// </remarks>
public void AddParameter(AdoNetAppenderParameter parameter)
{
m_parameters.Add(parameter);
}
#endregion // Public Instance Methods
#region Protected Instance Methods
/// <summary>
/// Writes the events to the database using the transaction specified.
/// </summary>
/// <param name="dbTran">The transaction that the events will be executed under.</param>
/// <param name="events">The array of events to insert into the database.</param>
/// <remarks>
/// <para>
/// The transaction argument can be <c>null</c> if the appender has been
/// configured not to use transactions. See <see cref="UseTransactions"/>
/// property for more information.
/// </para>
/// </remarks>
virtual protected void SendBuffer(IDbTransaction dbTran, LoggingEvent[] events)
{
if (m_usePreparedCommand)
{
// Send buffer using the prepared command object
if (m_dbCommand != null)
{
if (dbTran != null)
{
m_dbCommand.Transaction = dbTran;
}
// run for all events
foreach(LoggingEvent e in events)
{
// Set the parameter values
foreach(AdoNetAppenderParameter param in m_parameters)
{
param.FormatValue(m_dbCommand, e);
}
// Execute the query
m_dbCommand.ExecuteNonQuery();
}
}
}
else
{
// create a new command
using(IDbCommand dbCmd = m_dbConnection.CreateCommand())
{
if (dbTran != null)
{
dbCmd.Transaction = dbTran;
}
// run for all events
foreach(LoggingEvent e in events)
{
// Get the command text from the Layout
string logStatement = GetLogStatement(e);
LogLog.Debug("AdoNetAppender: LogStatement ["+logStatement+"]");
dbCmd.CommandText = logStatement;
dbCmd.ExecuteNonQuery();
}
}
}
}
/// <summary>
/// Formats the log message into database statement text.
/// </summary>
/// <param name="logEvent">The event being logged.</param>
/// <remarks>
/// This method can be overridden by subclasses to provide
/// more control over the format of the database statement.
/// </remarks>
/// <returns>
/// Text that can be passed to a <see cref="System.Data.IDbCommand"/>.
/// </returns>
virtual protected string GetLogStatement(LoggingEvent logEvent)
{
if (Layout == null)
{
ErrorHandler.Error("ADOAppender: No Layout specified.");
return "";
}
else
{
StringWriter writer = new StringWriter(System.Globalization.CultureInfo.InvariantCulture);
Layout.Format(writer, logEvent);
return writer.ToString();
}
}
/// <summary>
/// Connects to the database.
/// </summary>
private void InitializeDatabaseConnection()
{
try
{
// Cleanup any existing command or connection
if (m_dbCommand != null)
{
try
{
m_dbCommand.Dispose();
}
catch (Exception ex)
{
LogLog.Warn("AdoNetAppender: Exception while disposing cached command object", ex);
}
m_dbCommand = null;
}
if (m_dbConnection != null)
{
try
{
m_dbConnection.Close();
}
catch (Exception ex)
{
LogLog.Warn("AdoNetAppender: Exception while disposing cached connection object", ex);
}
m_dbConnection = null;
}
// Create the connection object
m_dbConnection = (IDbConnection)Activator.CreateInstance(ResolveConnectionType());
// Set the connection string
m_dbConnection.ConnectionString = m_connectionString;
using(SecurityContext.Impersonate(this))
{
// Open the database connection
m_dbConnection.Open();
}
}
catch (System.Exception e)
{
// Sadly, your connection string is bad.
ErrorHandler.Error("Could not open database connection [" + m_connectionString + "]", e);
m_dbConnection = null;
}
}
/// <summary>
/// Retrieves the class type of the ADO.NET provider.
/// </summary>
/// <remarks>
/// <para>
/// Gets the Type of the ADO.NET provider to use to connect to the
/// database. This method resolves the type specified in the
/// <see cref="ConnectionType"/> property.
/// </para>
/// <para>
/// Subclasses can override this method to return a different type
/// if necessary.
/// </para>
/// </remarks>
/// <returns>The <see cref="Type"/> of the ADO.NET provider</returns>
virtual protected Type ResolveConnectionType()
{
try
{
return SystemInfo.GetTypeFromString(m_connectionType, true, false);
}
catch(Exception ex)
{
ErrorHandler.Error("Failed to load connection type ["+m_connectionType+"]", ex);
throw;
}
}
/// <summary>
/// Prepares the database command and initialize the parameters.
/// </summary>
private void InitializeDatabaseCommand()
{
if (m_dbConnection != null && m_usePreparedCommand)
{
try
{
// Cleanup any existing command or connection
if (m_dbCommand != null)
{
try
{
m_dbCommand.Dispose();
}
catch (Exception ex)
{
LogLog.Warn("AdoNetAppender: Exception while disposing cached command object", ex);
}
m_dbCommand = null;
}
// Create the command object
m_dbCommand = m_dbConnection.CreateCommand();
// Set the command string
m_dbCommand.CommandText = m_commandText;
// Set the command type
m_dbCommand.CommandType = m_commandType;
}
catch(System.Exception e)
{
ErrorHandler.Error("Could not create database command ["+m_commandText+"]", e);
if (m_dbCommand != null)
{
try
{
m_dbCommand.Dispose();
}
catch
{
// Ignore exception
}
m_dbCommand = null;
}
}
if (m_dbCommand != null)
{
try
{
foreach(AdoNetAppenderParameter param in m_parameters)
{
try
{
param.Prepare(m_dbCommand);
}
catch(System.Exception e)
{
ErrorHandler.Error("Could not add database command parameter ["+param.ParameterName+"]", e);
throw;
}
}
}
catch
{
try
{
m_dbCommand.Dispose();
}
catch
{
// Ignore exception
}
m_dbCommand = null;
}
}
if (m_dbCommand != null)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -