Skip to content

Cleanup | SqlDiagnosticListener Classes #3232

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Mar 20, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Light cleanup of DiagnosticScope classes
  • Loading branch information
benrr101 committed Mar 19, 2025
commit c8b3f7ebce88c48e1296975093b3a9babeb9b07f
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,27 @@

namespace Microsoft.Data.SqlClient.Diagnostics
{
internal ref struct DiagnosticScope //: IDisposable //ref structs cannot implement interfaces but the compiler will use pattern matching
internal ref struct DiagnosticScope //: IDisposable
{
private const int CommandOperation = 1;
private const int ConnectionOpenOperation = 2;

private readonly object _context1;
private readonly object _context2;
private readonly SqlDiagnosticListener _diagnostics;
private readonly int _operation;
private readonly string _operationName;
private readonly Guid _operationId;
private readonly object _context1;
private readonly object _context2;
private readonly string _operationName;

private Exception _exception;

private DiagnosticScope(SqlDiagnosticListener diagnostics, int operation, Guid operationsId, string operationName, object context1, object context2)
private DiagnosticScope(
SqlDiagnosticListener diagnostics,
int operation,
Guid operationsId,
string operationName,
object context1,
object context2)
{
_diagnostics = diagnostics;
_operation = operation;
Expand All @@ -33,46 +40,70 @@ private DiagnosticScope(SqlDiagnosticListener diagnostics, int operation, Guid o
_exception = null;
}

public static DiagnosticScope CreateCommandScope(
SqlDiagnosticListener diagnostics,
SqlCommand command,
SqlTransaction transaction,
[CallerMemberName]
string operationName = "")
{
Guid operationId = diagnostics.WriteCommandBefore(command, transaction, operationName);
return new DiagnosticScope(diagnostics, CommandOperation, operationId, operationName, command, transaction);
}

// Although ref structs do not allow for inheriting from interfaces (< C#13), but the
// compiler will know to treat this like an IDisposable (> C# 8)
public void Dispose()
{
switch (_operation)
{
case CommandOperation:
if (_exception != null)
{
_diagnostics.WriteCommandError(_operationId, (SqlCommand)_context1, (SqlTransaction)_context2, _exception, _operationName);
_diagnostics.WriteCommandError(
_operationId,
(SqlCommand)_context1,
(SqlTransaction)_context2,
_exception,
_operationName);
}
else
{
_diagnostics.WriteCommandAfter(_operationId, (SqlCommand)_context1, (SqlTransaction)_context2, _operationName);
_diagnostics.WriteCommandAfter(
_operationId,
(SqlCommand)_context1,
(SqlTransaction)_context2,
_operationName);
}
break;

case ConnectionOpenOperation:
if (_exception != null)
{
_diagnostics.WriteConnectionOpenError(_operationId, (SqlConnection)_context1, _exception, _operationName);
_diagnostics.WriteConnectionOpenError(
_operationId,
(SqlConnection)_context1,
_exception,
_operationName);
}
else
{
_diagnostics.WriteConnectionOpenAfter(_operationId, (SqlConnection)_context1, _operationName);
_diagnostics.WriteConnectionOpenAfter(
_operationId,
(SqlConnection)_context1,
_operationName);
}
break;

// ConnectionCloseOperation is not implemented because it is conditionally emitted and that requires manual calls to the write apis
// ConnectionCloseOperation is not implemented because it is conditionally
// emitted and that requires manual calls to the write apis
}
}

public void SetException(Exception ex)
{
_exception = ex;
}

public static DiagnosticScope CreateCommandScope(SqlDiagnosticListener diagnostics, SqlCommand command, SqlTransaction transaction, [CallerMemberName] string operationName = "")
{
Guid operationId = diagnostics.WriteCommandBefore(command, transaction, operationName);
return new DiagnosticScope(diagnostics, CommandOperation, operationId, operationName, command, transaction);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,31 @@

namespace Microsoft.Data.SqlClient.Diagnostics
{
internal ref struct DiagnosticTransactionScope //: IDisposable //ref structs cannot implement interfaces but the compiler will use pattern matching
internal ref struct DiagnosticTransactionScope //: IDisposable
{
public const int TransactionCommit = 1;
public const int TransactionRollback = 2;

private readonly SqlConnection _connection;
private readonly SqlDiagnosticListener _diagnostics;
private readonly int _operation;
private readonly Guid _operationId;
private readonly string _operationName;
private readonly IsolationLevel _isolationLevel;
private readonly SqlConnection _connection;
private readonly SqlInternalTransaction _transaction;
private readonly string _transactionName;

private Exception _exception;

public DiagnosticTransactionScope(SqlDiagnosticListener diagnostics, int operation, Guid operationId, string operationName, IsolationLevel isolationLevel, SqlConnection connection, SqlInternalTransaction transaction, string transactionName)
public DiagnosticTransactionScope(
SqlDiagnosticListener diagnostics,
int operation,
Guid operationId,
string operationName,
IsolationLevel isolationLevel,
SqlConnection connection,
SqlInternalTransaction transaction,
string transactionName)
{
_diagnostics = diagnostics;
_operation = operation;
Expand All @@ -38,29 +47,105 @@ public DiagnosticTransactionScope(SqlDiagnosticListener diagnostics, int operati
_exception = null;
}

public static DiagnosticTransactionScope CreateTransactionCommitScope(
SqlDiagnosticListener diagnostics,
IsolationLevel isolationLevel,
SqlConnection connection,
SqlInternalTransaction transaction,
[CallerMemberName]
string operationName = "")
{
Guid operationId = diagnostics.WriteTransactionCommitBefore(
isolationLevel,
connection,
transaction,
operationName);
return new DiagnosticTransactionScope(
diagnostics,
TransactionCommit,
operationId,
operationName,
isolationLevel,
connection,
transaction,
transactionName: null);
}

public static DiagnosticTransactionScope CreateTransactionRollbackScope(
SqlDiagnosticListener diagnostics,
IsolationLevel isolationLevel,
SqlConnection connection,
SqlInternalTransaction transaction,
string transactionName,
[CallerMemberName]
string operationName = "")
{
Guid operationId = diagnostics.WriteTransactionRollbackBefore(
isolationLevel,
connection,
transaction,
transactionName,
operationName);
return new DiagnosticTransactionScope(
diagnostics,
TransactionCommit,
operationId,
operationName,
isolationLevel,
connection,
transaction,
transactionName);
}

// Although ref structs do not allow for inheriting from interfaces (< C#13), but the
// compiler will know to treat this like an IDisposable (> C# 8)
public void Dispose()
{
switch (_operation)
{
case TransactionCommit:
if (_exception != null)
{
_diagnostics.WriteTransactionCommitError(_operationId, _isolationLevel, _connection, _transaction, _exception, _operationName);
_diagnostics.WriteTransactionCommitError(
_operationId,
_isolationLevel,
_connection,
_transaction,
_exception,
_operationName);
}
else
{
_diagnostics.WriteTransactionCommitAfter(_operationId, _isolationLevel, _connection, _transaction, _operationName);
_diagnostics.WriteTransactionCommitAfter(
_operationId,
_isolationLevel,
_connection,
_transaction,
_operationName);
}
break;

case TransactionRollback:
if (_exception != null)
{
_diagnostics.WriteTransactionRollbackError(_operationId, _isolationLevel, _connection, _transaction, _exception, _transactionName, _operationName);
_diagnostics.WriteTransactionRollbackError(
_operationId,
_isolationLevel,
_connection,
_transaction,
_exception,
_transactionName,
_operationName);
}
else
{
_diagnostics.WriteTransactionRollbackAfter(_operationId, _isolationLevel, _connection, _transaction, _transactionName, _operationName);
_diagnostics.WriteTransactionRollbackAfter(
_operationId,
_isolationLevel,
_connection,
_transaction,
_transactionName,
_operationName);
}
break;
}
Expand All @@ -70,18 +155,6 @@ public void SetException(Exception ex)
{
_exception = ex;
}

public static DiagnosticTransactionScope CreateTransactionCommitScope(SqlDiagnosticListener diagnostics, IsolationLevel isolationLevel, SqlConnection connection, SqlInternalTransaction transaction, [CallerMemberName] string operationName = "")
{
Guid operationId = diagnostics.WriteTransactionCommitBefore(isolationLevel, connection, transaction, operationName);
return new DiagnosticTransactionScope(diagnostics, TransactionCommit, operationId, operationName, isolationLevel, connection, transaction, null);
}

public static DiagnosticTransactionScope CreateTransactionRollbackScope(SqlDiagnosticListener diagnostics, IsolationLevel isolationLevel, SqlConnection connection, SqlInternalTransaction transaction, string transactionName, [CallerMemberName] string operationName = "")
{
Guid operationId = diagnostics.WriteTransactionRollbackBefore(isolationLevel, connection, transaction, transactionName, operationName);
return new DiagnosticTransactionScope(diagnostics, TransactionCommit, operationId, operationName, isolationLevel, connection, transaction, transactionName);
}
}
}

Expand Down