From 24cda5dc15b8c41aba0348744ffc5d6c244f381f Mon Sep 17 00:00:00 2001 From: Ben Russell Date: Tue, 11 Mar 2025 16:51:44 -0500 Subject: [PATCH 1/6] Move diagnostic files into common project in diagnostics folder --- .../netcore/src/Microsoft.Data.SqlClient.csproj | 12 +++++++++--- .../Diagnostics/SqlClientDiagnostic.netcore.cs} | 4 ++++ ...SqlClientDiagnosticListenerExtensions.netcore.cs} | 4 ++++ .../Diagnostics/SqlDiagnosticListener.netcore.cs} | 4 ++++ 4 files changed, 21 insertions(+), 3 deletions(-) rename src/Microsoft.Data.SqlClient/{netcore/src/Microsoft/Data/SqlClient/SqlClientDiagnostic.cs => src/Microsoft/Data/SqlClient/Diagnostics/SqlClientDiagnostic.netcore.cs} (99%) rename src/Microsoft.Data.SqlClient/{netcore/src/Microsoft/Data/SqlClient/SqlClientDiagnosticListenerExtensions.cs => src/Microsoft/Data/SqlClient/Diagnostics/SqlClientDiagnosticListenerExtensions.netcore.cs} (99%) rename src/Microsoft.Data.SqlClient/{netcore/src/Microsoft/Data/SqlClient/SqlDiagnosticListener.cs => src/Microsoft/Data/SqlClient/Diagnostics/SqlDiagnosticListener.netcore.cs} (97%) diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj index 14ac8aab60..4ee0a0b320 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj @@ -179,6 +179,15 @@ Microsoft\Data\SqlClient\DataClassification\SensitivityClassification.cs + + Microsoft\Data\SqlClient\Diagnostics\SqlClientDiagnostic.netcore.cs + + + Microsoft\Data\SqlClient\Diagnostics\SqlClientDiagnosticListenerExtensions.netcore.cs + + + Microsoft\Data\SqlClient\Diagnostics\SqlDiagnosticListener.netcore.cs + Microsoft\Data\SqlClient\DisposableTemporaryOnStack.cs @@ -665,8 +674,6 @@ - - @@ -674,7 +681,6 @@ - diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlClientDiagnostic.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientDiagnostic.netcore.cs similarity index 99% rename from src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlClientDiagnostic.cs rename to src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientDiagnostic.netcore.cs index 51a2f8f0ba..d3c73f75ab 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlClientDiagnostic.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientDiagnostic.netcore.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#if NET + using System; using System.Collections; using System.Collections.Generic; @@ -968,3 +970,5 @@ public IEnumerator> GetEnumerator() } } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlClientDiagnosticListenerExtensions.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientDiagnosticListenerExtensions.netcore.cs similarity index 99% rename from src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlClientDiagnosticListenerExtensions.cs rename to src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientDiagnosticListenerExtensions.netcore.cs index 9f63cbaba8..783534ce73 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlClientDiagnosticListenerExtensions.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientDiagnosticListenerExtensions.netcore.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#if NET + using System; using System.Collections; using System.Collections.Generic; @@ -505,3 +507,5 @@ public static DiagnosticTransactionScope CreateTransactionRollbackScope(SqlDiagn } } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlDiagnosticListener.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlDiagnosticListener.netcore.cs similarity index 97% rename from src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlDiagnosticListener.cs rename to src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlDiagnosticListener.netcore.cs index 8035b460db..2c597cc0c6 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlDiagnosticListener.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlDiagnosticListener.netcore.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#if NET + using System.Diagnostics; using System.Reflection; using System.Runtime.Loader; @@ -21,3 +23,5 @@ private void SqlDiagnosticListener_Unloading(AssemblyLoadContext obj) } } } + +#endif From d7f97a87ed2ec32686036ea0fefd3ada113e03b0 Mon Sep 17 00:00:00 2001 From: Ben Russell Date: Tue, 11 Mar 2025 17:14:03 -0500 Subject: [PATCH 2/6] Add stubs for sqlcommand and sqlconnection (for sqldiagnostic work) --- .../Microsoft/Data/SqlClient/SqlCommand.stub.cs | 15 +++++++++++++++ .../Data/SqlClient/SqlConnection.stub.cs | 17 +++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommand.stub.cs create mode 100644 src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnection.stub.cs diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommand.stub.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommand.stub.cs new file mode 100644 index 0000000000..bb7e537cf8 --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommand.stub.cs @@ -0,0 +1,15 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// @TODO: This is only a stub class for removing clearing errors while merging other files. + +namespace Microsoft.Data.SqlClient +{ + public class SqlCommand + { + public SqlConnection Connection { get; set; } + + internal SqlStatistics Statistics { get; set; } + } +} diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnection.stub.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnection.stub.cs new file mode 100644 index 0000000000..d16088849e --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnection.stub.cs @@ -0,0 +1,17 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// @TODO: This is only a stub class for removing clearing errors while merging other files. + +using System; + +namespace Microsoft.Data.SqlClient +{ + public class SqlConnection + { + internal Guid ClientConnectionId { get; set; } + + internal SqlStatistics Statistics { get; set; } + } +} From fb9e78d7cb2b87a242c2f3ff69b81605f525fa8b Mon Sep 17 00:00:00 2001 From: Ben Russell Date: Wed, 12 Mar 2025 16:15:27 -0500 Subject: [PATCH 3/6] Splitting SqlClientDiagnostic.netcore.cs into one file per class --- .../src/Microsoft.Data.SqlClient.csproj | 46 +- .../SqlClientCommandAfter.netcore.cs | 79 ++ .../SqlClientCommandBefore.netcore.cs | 75 ++ .../SqlClientCommandError.netcore.cs | 79 ++ .../SqlClientConnectionCloseAfter.netcore.cs | 75 ++ .../SqlClientConnectionCloseBefore.netcore.cs | 75 ++ .../SqlClientConnectionCloseError.netcore.cs | 81 ++ .../SqlClientConnectionOpenAfter.netcore.cs | 79 ++ .../SqlClientConnectionOpenBefore.netcore.cs | 71 ++ .../SqlClientConnectionOpenError.netcore.cs | 81 ++ .../SqlClientDiagnostic.netcore.cs | 974 ------------------ ...SqlClientTransactionCommitAfter.netcore.cs | 77 ++ ...qlClientTransactionCommitBefore.netcore.cs | 76 ++ ...SqlClientTransactionCommitError.netcore.cs | 81 ++ ...lClientTransactionRollbackAfter.netcore.cs | 80 ++ ...ClientTransactionRollbackBefore.netcore.cs | 81 ++ ...lClientTransactionRollbackError.netcore.cs | 85 ++ 17 files changed, 1219 insertions(+), 976 deletions(-) create mode 100644 src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientCommandAfter.netcore.cs create mode 100644 src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientCommandBefore.netcore.cs create mode 100644 src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientCommandError.netcore.cs create mode 100644 src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientConnectionCloseAfter.netcore.cs create mode 100644 src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientConnectionCloseBefore.netcore.cs create mode 100644 src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientConnectionCloseError.netcore.cs create mode 100644 src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientConnectionOpenAfter.netcore.cs create mode 100644 src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientConnectionOpenBefore.netcore.cs create mode 100644 src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientConnectionOpenError.netcore.cs delete mode 100644 src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientDiagnostic.netcore.cs create mode 100644 src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientTransactionCommitAfter.netcore.cs create mode 100644 src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientTransactionCommitBefore.netcore.cs create mode 100644 src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientTransactionCommitError.netcore.cs create mode 100644 src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientTransactionRollbackAfter.netcore.cs create mode 100644 src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientTransactionRollbackBefore.netcore.cs create mode 100644 src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientTransactionRollbackError.netcore.cs diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj index 4ee0a0b320..a07a46c8c8 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj @@ -179,12 +179,54 @@ Microsoft\Data\SqlClient\DataClassification\SensitivityClassification.cs - - Microsoft\Data\SqlClient\Diagnostics\SqlClientDiagnostic.netcore.cs + + Microsoft\Data\SqlClient\Diagnostics\SqlClientCommandAfter.netcore.cs + + + Microsoft\Data\SqlClient\Diagnostics\SqlClientCommandBefore.netcore.cs + + + Microsoft\Data\SqlClient\Diagnostics\SqlClientCommandError.netcore.cs + + + Microsoft\Data\SqlClient\Diagnostics\SqlClientConnectionCloseAfter.netcore.cs + + + Microsoft\Data\SqlClient\Diagnostics\SqlClientConnectionCloseBefore.netcore.cs + + + Microsoft\Data\SqlClient\Diagnostics\SqlClientConnectionCloseError.netcore.cs + + + Microsoft\Data\SqlClient\Diagnostics\SqlClientConnectionOpenAfter.netcore.cs + + + Microsoft\Data\SqlClient\Diagnostics\SqlClientConnectionOpenBefore.netcore.cs + + + Microsoft\Data\SqlClient\Diagnostics\SqlClientConnectionOpenError.netcore.cs Microsoft\Data\SqlClient\Diagnostics\SqlClientDiagnosticListenerExtensions.netcore.cs + + Microsoft\Data\SqlClient\Diagnostics\SqlClientTransactionCommitAfter.netcore.cs + + + Microsoft\Data\SqlClient\Diagnostics\SqlClientTransactionCommitBefore.netcore.cs + + + Microsoft\Data\SqlClient\Diagnostics\SqlClientTransactionCommitError.netcore.cs + + + Microsoft\Data\SqlClient\Diagnostics\SqlClientTransactionRollbackAfter.netcore.cs + + + Microsoft\Data\SqlClient\Diagnostics\SqlClientTransactionRollbackBefore.netcore.cs + + + Microsoft\Data\SqlClient\Diagnostics\SqlClientTransactionRollbackError.netcore.cs + Microsoft\Data\SqlClient\Diagnostics\SqlDiagnosticListener.netcore.cs diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientCommandAfter.netcore.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientCommandAfter.netcore.cs new file mode 100644 index 0000000000..d175656031 --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientCommandAfter.netcore.cs @@ -0,0 +1,79 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#if NET + +using System; +using System.Collections; +using System.Collections.Generic; + +namespace Microsoft.Data.SqlClient.Diagnostics +{ + /// + public sealed class SqlClientCommandAfter : IReadOnlyList> + { + /// + public const string Name = "Microsoft.Data.SqlClient.WriteCommandAfter"; + + internal SqlClientCommandAfter(Guid operationId, string operation, long timestamp, Guid? connectionId, long? transactionId, SqlCommand command, IDictionary statistics) + { + OperationId = operationId; + Operation = operation; + Timestamp = timestamp; + ConnectionId = connectionId; + TransactionId = transactionId; + Command = command; + Statistics = statistics; + } + + /// + public Guid OperationId { get; } + /// + public string Operation { get; } + /// + public long Timestamp { get; } + /// + public Guid? ConnectionId { get; } + /// + public long? TransactionId { get; } + /// + public SqlCommand Command { get; } + /// + public IDictionary Statistics { get; } + + /// + public int Count => 3 + 4; + + /// + public KeyValuePair this[int index] + { + get => index switch + { + 0 => new KeyValuePair(nameof(OperationId), OperationId), + 1 => new KeyValuePair(nameof(Operation), Operation), + 2 => new KeyValuePair(nameof(Timestamp), Timestamp), + 3 => new KeyValuePair(nameof(ConnectionId), ConnectionId), + 4 => new KeyValuePair(nameof(TransactionId), TransactionId), + 5 => new KeyValuePair(nameof(Command), Command), + 6 => new KeyValuePair(nameof(Statistics), Statistics), + _ => throw new IndexOutOfRangeException(nameof(index)), + }; + } + + /// + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + + /// + public IEnumerator> GetEnumerator() + { + int count = Count; + for (int index = 0; index < count; index++) + { + yield return this[index]; + } + } + } +} + +#endif diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientCommandBefore.netcore.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientCommandBefore.netcore.cs new file mode 100644 index 0000000000..469b8e9987 --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientCommandBefore.netcore.cs @@ -0,0 +1,75 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#if NET + +using System; +using System.Collections; +using System.Collections.Generic; + +namespace Microsoft.Data.SqlClient.Diagnostics +{ + /// + public sealed class SqlClientCommandBefore : IReadOnlyList> + { + /// + public const string Name = "Microsoft.Data.SqlClient.WriteCommandBefore"; + + internal SqlClientCommandBefore(Guid operationId, string operation, long timestamp, Guid? connectionId, long? transactionId, SqlCommand command) + { + OperationId = operationId; + Operation = operation; + Timestamp = timestamp; + ConnectionId = connectionId; + TransactionId = transactionId; + Command = command; + } + + /// + public Guid OperationId { get; } + /// + public string Operation { get; } + /// + public long Timestamp { get; } + /// + public Guid? ConnectionId { get; } + /// + public long? TransactionId { get; } + /// + public SqlCommand Command { get; } + + /// + public int Count => 3 + 3; + + /// + public KeyValuePair this[int index] + { + get => index switch + { + 0 => new KeyValuePair(nameof(OperationId), OperationId), + 1 => new KeyValuePair(nameof(Operation), Operation), + 2 => new KeyValuePair(nameof(Timestamp), Timestamp), + 3 => new KeyValuePair(nameof(ConnectionId), ConnectionId), + 4 => new KeyValuePair(nameof(TransactionId), TransactionId), + 5 => new KeyValuePair(nameof(Command), Command), + _ => throw new IndexOutOfRangeException(nameof(index)), + }; + } + + /// + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + + /// + public IEnumerator> GetEnumerator() + { + int count = Count; + for (int index = 0; index < count; index++) + { + yield return this[index]; + } + } + } +} + +#endif diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientCommandError.netcore.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientCommandError.netcore.cs new file mode 100644 index 0000000000..ed04636eeb --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientCommandError.netcore.cs @@ -0,0 +1,79 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#if NET + +using System; +using System.Collections; +using System.Collections.Generic; + +namespace Microsoft.Data.SqlClient.Diagnostics +{ + /// + public sealed class SqlClientCommandError : IReadOnlyList> + { + /// + + public const string Name = "Microsoft.Data.SqlClient.WriteCommandError"; + + internal SqlClientCommandError(Guid operationId, string operation, long timestamp, Guid? connectionId, long? transactionId, SqlCommand command, Exception exception) + { + OperationId = operationId; + Operation = operation; + Timestamp = timestamp; + ConnectionId = connectionId; + TransactionId = transactionId; + Command = command; + Exception = exception; + } + /// + public Guid OperationId { get; } + /// + public string Operation { get; } + /// + public long Timestamp { get; } + /// + public Guid? ConnectionId { get; } + /// + public long? TransactionId { get; } + /// + public SqlCommand Command { get; } + /// + public Exception Exception { get; } + + /// + public int Count => 3 + 4; + + /// + public KeyValuePair this[int index] + { + get => index switch + { + 0 => new KeyValuePair(nameof(OperationId), OperationId), + 1 => new KeyValuePair(nameof(Operation), Operation), + 2 => new KeyValuePair(nameof(Timestamp), Timestamp), + 3 => new KeyValuePair(nameof(ConnectionId), ConnectionId), + 4 => new KeyValuePair(nameof(TransactionId), TransactionId), + 5 => new KeyValuePair(nameof(Command), Command), + 6 => new KeyValuePair(nameof(Exception), Exception), + _ => throw new IndexOutOfRangeException(nameof(index)), + }; + } + + /// + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + + /// + public IEnumerator> GetEnumerator() + { + int count = Count; + for (int index = 0; index < count; index++) + { + yield return this[index]; + } + } + } +} + +#endif diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientConnectionCloseAfter.netcore.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientConnectionCloseAfter.netcore.cs new file mode 100644 index 0000000000..d6119d076b --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientConnectionCloseAfter.netcore.cs @@ -0,0 +1,75 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#if NET + +using System; +using System.Collections; +using System.Collections.Generic; + +namespace Microsoft.Data.SqlClient.Diagnostics +{ + /// + public sealed class SqlClientConnectionCloseAfter : IReadOnlyList> + { + /// + public const string Name = "Microsoft.Data.SqlClient.WriteConnectionCloseAfter"; + + internal SqlClientConnectionCloseAfter(Guid operationId, string operation, long timestamp, Guid? connectionId, SqlConnection connection, IDictionary statistics) + { + OperationId = operationId; + Operation = operation; + Timestamp = timestamp; + ConnectionId = connectionId; + Connection = connection; + Statistics = statistics; + } + + /// + public Guid OperationId { get; } + /// + public string Operation { get; } + /// + public long Timestamp { get; } + /// + public Guid? ConnectionId { get; } + /// + public SqlConnection Connection { get; } + /// + public IDictionary Statistics { get; } + + /// + public int Count => 3 + 3; + + /// + public KeyValuePair this[int index] + { + get => index switch + { + 0 => new KeyValuePair(nameof(OperationId), OperationId), + 1 => new KeyValuePair(nameof(Operation), Operation), + 2 => new KeyValuePair(nameof(Timestamp), Timestamp), + 3 => new KeyValuePair(nameof(ConnectionId), ConnectionId), + 4 => new KeyValuePair(nameof(Connection), Connection), + 5 => new KeyValuePair(nameof(Statistics), Statistics), + _ => throw new IndexOutOfRangeException(nameof(index)), + }; + } + + /// + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + + /// + public IEnumerator> GetEnumerator() + { + int count = Count; + for (int index = 0; index < count; index++) + { + yield return this[index]; + } + } + } +} + +#endif diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientConnectionCloseBefore.netcore.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientConnectionCloseBefore.netcore.cs new file mode 100644 index 0000000000..9aec7ff985 --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientConnectionCloseBefore.netcore.cs @@ -0,0 +1,75 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#if NET + +using System; +using System.Collections; +using System.Collections.Generic; + +namespace Microsoft.Data.SqlClient.Diagnostics +{ + /// + public sealed class SqlClientConnectionCloseBefore : IReadOnlyList> + { + /// + public const string Name = "Microsoft.Data.SqlClient.WriteConnectionCloseBefore"; + + internal SqlClientConnectionCloseBefore(Guid operationId, string operation, long timestamp, Guid? connectionId, SqlConnection connection, IDictionary statistics) + { + OperationId = operationId; + Operation = operation; + Timestamp = timestamp; + ConnectionId = connectionId; + Connection = connection; + Statistics = statistics; + } + + /// + public Guid OperationId { get; } + /// + public string Operation { get; } + /// + public long Timestamp { get; } + /// + public Guid? ConnectionId { get; } + /// + public SqlConnection Connection { get; } + /// + public IDictionary Statistics { get; } + + /// + public int Count => 3 + 3; + + /// + public KeyValuePair this[int index] + { + get => index switch + { + 0 => new KeyValuePair(nameof(OperationId), OperationId), + 1 => new KeyValuePair(nameof(Operation), Operation), + 2 => new KeyValuePair(nameof(Timestamp), Timestamp), + 3 => new KeyValuePair(nameof(ConnectionId), ConnectionId), + 4 => new KeyValuePair(nameof(Connection), Connection), + 5 => new KeyValuePair(nameof(Statistics), Statistics), + _ => throw new IndexOutOfRangeException(nameof(index)), + }; + } + + /// + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + + /// + public IEnumerator> GetEnumerator() + { + int count = Count; + for (int index = 0; index < count; index++) + { + yield return this[index]; + } + } + } +} + +#endif diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientConnectionCloseError.netcore.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientConnectionCloseError.netcore.cs new file mode 100644 index 0000000000..72c66ec99a --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientConnectionCloseError.netcore.cs @@ -0,0 +1,81 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#if NET + +using System; +using System.Collections; +using System.Collections.Generic; + +namespace Microsoft.Data.SqlClient.Diagnostics +{ + /// + public sealed class SqlClientConnectionCloseError : IReadOnlyList> + { + /// + public const string Name = "Microsoft.Data.SqlClient.WriteConnectionCloseError"; + + internal SqlClientConnectionCloseError(Guid operationId, string operation, long timestamp, Guid? connectionId, SqlConnection connection, IDictionary statistics, Exception ex) + { + OperationId = operationId; + Operation = operation; + Timestamp = timestamp; + ConnectionId = connectionId; + Connection = connection; + Statistics = statistics; + Exception = ex; + } + + /// + public Guid OperationId { get; } + /// + public string Operation { get; } + /// + public long Timestamp { get; } + + /// + public Guid? ConnectionId { get; } + /// + public SqlConnection Connection { get; } + /// + public IDictionary Statistics { get; } + + /// + public Exception Exception { get; } + + /// + public int Count => 3 + 4; + + /// + public KeyValuePair this[int index] + { + get => index switch + { + 0 => new KeyValuePair(nameof(OperationId), OperationId), + 1 => new KeyValuePair(nameof(Operation), Operation), + 2 => new KeyValuePair(nameof(Timestamp), Timestamp), + 3 => new KeyValuePair(nameof(ConnectionId), ConnectionId), + 4 => new KeyValuePair(nameof(Connection), Connection), + 5 => new KeyValuePair(nameof(Statistics), Statistics), + 6 => new KeyValuePair(nameof(Exception), Exception), + _ => throw new IndexOutOfRangeException(nameof(index)), + }; + } + + /// + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + + /// + public IEnumerator> GetEnumerator() + { + int count = Count; + for (int index = 0; index < count; index++) + { + yield return this[index]; + } + } + } +} + +#endif diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientConnectionOpenAfter.netcore.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientConnectionOpenAfter.netcore.cs new file mode 100644 index 0000000000..0abd06adf2 --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientConnectionOpenAfter.netcore.cs @@ -0,0 +1,79 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#if NET + +using System; +using System.Collections; +using System.Collections.Generic; + +namespace Microsoft.Data.SqlClient.Diagnostics +{ + /// + public sealed class SqlClientConnectionOpenAfter : IReadOnlyList> + { + /// + public const string Name = "Microsoft.Data.SqlClient.WriteConnectionOpenAfter"; + + internal SqlClientConnectionOpenAfter(Guid operationId, string operation, long timestamp, Guid connectionId, SqlConnection connection, string clientVersion, IDictionary statistics) + { + OperationId = operationId; + Operation = operation; + Timestamp = timestamp; + ConnectionId = connectionId; + Connection = connection; + ClientVersion = clientVersion; + Statistics = statistics; + } + + /// + public Guid OperationId { get; } + /// + public string Operation { get; } + /// + public long Timestamp { get; } + /// + public Guid ConnectionId { get; } + /// + public SqlConnection Connection { get; } + /// + public string ClientVersion { get; } + /// + public IDictionary Statistics { get; } + + /// + public int Count => 3 + 4; + + /// + public KeyValuePair this[int index] + { + get => index switch + { + 0 => new KeyValuePair(nameof(OperationId), OperationId), + 1 => new KeyValuePair(nameof(Operation), Operation), + 2 => new KeyValuePair(nameof(Timestamp), Timestamp), + 3 => new KeyValuePair(nameof(ConnectionId), ConnectionId), + 4 => new KeyValuePair(nameof(Connection), Connection), + 5 => new KeyValuePair(nameof(ClientVersion), ClientVersion), + 6 => new KeyValuePair(nameof(Statistics), Statistics), + _ => throw new IndexOutOfRangeException(nameof(index)), + }; + } + + /// + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + + /// + public IEnumerator> GetEnumerator() + { + int count = Count; + for (int index = 0; index < count; index++) + { + yield return this[index]; + } + } + } +} + +#endif diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientConnectionOpenBefore.netcore.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientConnectionOpenBefore.netcore.cs new file mode 100644 index 0000000000..240e267e89 --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientConnectionOpenBefore.netcore.cs @@ -0,0 +1,71 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#if NET + +using System; +using System.Collections; +using System.Collections.Generic; + +namespace Microsoft.Data.SqlClient.Diagnostics +{ + /// + public sealed class SqlClientConnectionOpenBefore : IReadOnlyList> + { + /// + public const string Name = "Microsoft.Data.SqlClient.WriteConnectionOpenBefore"; + + internal SqlClientConnectionOpenBefore(Guid operationId, string operation, long timestamp, SqlConnection connection, string clientVersion) + { + OperationId = operationId; + Operation = operation; + Timestamp = timestamp; + Connection = connection; + ClientVersion = clientVersion; + } + + /// + public Guid OperationId { get; } + /// + public string Operation { get; } + /// + public long Timestamp { get; } + /// + public SqlConnection Connection { get; } + /// + public string ClientVersion { get; } + + /// + public int Count => 3 + 2; + + /// + public KeyValuePair this[int index] + { + get => index switch + { + 0 => new KeyValuePair(nameof(OperationId), OperationId), + 1 => new KeyValuePair(nameof(Operation), Operation), + 2 => new KeyValuePair(nameof(Timestamp), Timestamp), + 3 => new KeyValuePair(nameof(Connection), Connection), + 4 => new KeyValuePair(nameof(ClientVersion), ClientVersion), + _ => throw new IndexOutOfRangeException(nameof(index)), + }; + } + + /// + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + + /// + public IEnumerator> GetEnumerator() + { + int count = Count; + for (int index = 0; index < count; index++) + { + yield return this[index]; + } + } + } +} + +#endif diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientConnectionOpenError.netcore.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientConnectionOpenError.netcore.cs new file mode 100644 index 0000000000..9651e3b1f8 --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientConnectionOpenError.netcore.cs @@ -0,0 +1,81 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#if NET + +using System; +using System.Collections; +using System.Collections.Generic; + +namespace Microsoft.Data.SqlClient.Diagnostics +{ + /// + public sealed class SqlClientConnectionOpenError : IReadOnlyList> + { + /// + + public const string Name = "Microsoft.Data.SqlClient.WriteConnectionOpenError"; + + internal SqlClientConnectionOpenError(Guid operationId, string operation, long timestamp, Guid connectionId, SqlConnection connection, string clientVersion, Exception exception) + { + OperationId = operationId; + Operation = operation; + Timestamp = timestamp; + ConnectionId = connectionId; + Connection = connection; + ClientVersion = clientVersion; + Exception = exception; + } + + /// + public Guid OperationId { get; } + /// + public string Operation { get; } + /// + public long Timestamp { get; } + + /// + public Guid ConnectionId { get; } + /// + public SqlConnection Connection { get; } + /// + public string ClientVersion { get; } + /// + public Exception Exception { get; } + + /// + public int Count => 3 + 4; + + /// + public KeyValuePair this[int index] + { + get => index switch + { + 0 => new KeyValuePair(nameof(OperationId), OperationId), + 1 => new KeyValuePair(nameof(Operation), Operation), + 2 => new KeyValuePair(nameof(Timestamp), Timestamp), + 3 => new KeyValuePair(nameof(ConnectionId), ConnectionId), + 4 => new KeyValuePair(nameof(Connection), Connection), + 5 => new KeyValuePair(nameof(ClientVersion), ClientVersion), + 6 => new KeyValuePair(nameof(Exception), Exception), + _ => throw new IndexOutOfRangeException(nameof(index)), + }; + } + + /// + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + + /// + public IEnumerator> GetEnumerator() + { + int count = Count; + for (int index = 0; index < count; index++) + { + yield return this[index]; + } + } + } +} + +#endif diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientDiagnostic.netcore.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientDiagnostic.netcore.cs deleted file mode 100644 index d3c73f75ab..0000000000 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientDiagnostic.netcore.cs +++ /dev/null @@ -1,974 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -#if NET - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Data; - -namespace Microsoft.Data.SqlClient.Diagnostics -{ - /// - public sealed class SqlClientCommandBefore : IReadOnlyList> - { - /// - public const string Name = "Microsoft.Data.SqlClient.WriteCommandBefore"; - - internal SqlClientCommandBefore(Guid operationId, string operation, long timestamp, Guid? connectionId, long? transactionId, SqlCommand command) - { - OperationId = operationId; - Operation = operation; - Timestamp = timestamp; - ConnectionId = connectionId; - TransactionId = transactionId; - Command = command; - } - - /// - public Guid OperationId { get; } - /// - public string Operation { get; } - /// - public long Timestamp { get; } - /// - public Guid? ConnectionId { get; } - /// - public long? TransactionId { get; } - /// - public SqlCommand Command { get; } - - /// - public int Count => 3 + 3; - - /// - public KeyValuePair this[int index] - { - get => index switch - { - 0 => new KeyValuePair(nameof(OperationId), OperationId), - 1 => new KeyValuePair(nameof(Operation), Operation), - 2 => new KeyValuePair(nameof(Timestamp), Timestamp), - 3 => new KeyValuePair(nameof(ConnectionId), ConnectionId), - 4 => new KeyValuePair(nameof(TransactionId), TransactionId), - 5 => new KeyValuePair(nameof(Command), Command), - _ => throw new IndexOutOfRangeException(nameof(index)), - }; - } - - /// - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - - /// - public IEnumerator> GetEnumerator() - { - int count = Count; - for (int index = 0; index < count; index++) - { - yield return this[index]; - } - } - } - - /// - public sealed class SqlClientCommandAfter : IReadOnlyList> - { - /// - public const string Name = "Microsoft.Data.SqlClient.WriteCommandAfter"; - - internal SqlClientCommandAfter(Guid operationId, string operation, long timestamp, Guid? connectionId, long? transactionId, SqlCommand command, IDictionary statistics) - { - OperationId = operationId; - Operation = operation; - Timestamp = timestamp; - ConnectionId = connectionId; - TransactionId = transactionId; - Command = command; - Statistics = statistics; - } - - /// - public Guid OperationId { get; } - /// - public string Operation { get; } - /// - public long Timestamp { get; } - /// - public Guid? ConnectionId { get; } - /// - public long? TransactionId { get; } - /// - public SqlCommand Command { get; } - /// - public IDictionary Statistics { get; } - - /// - public int Count => 3 + 4; - - /// - public KeyValuePair this[int index] - { - get => index switch - { - 0 => new KeyValuePair(nameof(OperationId), OperationId), - 1 => new KeyValuePair(nameof(Operation), Operation), - 2 => new KeyValuePair(nameof(Timestamp), Timestamp), - 3 => new KeyValuePair(nameof(ConnectionId), ConnectionId), - 4 => new KeyValuePair(nameof(TransactionId), TransactionId), - 5 => new KeyValuePair(nameof(Command), Command), - 6 => new KeyValuePair(nameof(Statistics), Statistics), - _ => throw new IndexOutOfRangeException(nameof(index)), - }; - } - - /// - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - - /// - public IEnumerator> GetEnumerator() - { - int count = Count; - for (int index = 0; index < count; index++) - { - yield return this[index]; - } - } - } - - /// - public sealed class SqlClientCommandError : IReadOnlyList> - { - /// - - public const string Name = "Microsoft.Data.SqlClient.WriteCommandError"; - - internal SqlClientCommandError(Guid operationId, string operation, long timestamp, Guid? connectionId, long? transactionId, SqlCommand command, Exception exception) - { - OperationId = operationId; - Operation = operation; - Timestamp = timestamp; - ConnectionId = connectionId; - TransactionId = transactionId; - Command = command; - Exception = exception; - } - /// - public Guid OperationId { get; } - /// - public string Operation { get; } - /// - public long Timestamp { get; } - /// - public Guid? ConnectionId { get; } - /// - public long? TransactionId { get; } - /// - public SqlCommand Command { get; } - /// - public Exception Exception { get; } - - /// - public int Count => 3 + 4; - - /// - public KeyValuePair this[int index] - { - get => index switch - { - 0 => new KeyValuePair(nameof(OperationId), OperationId), - 1 => new KeyValuePair(nameof(Operation), Operation), - 2 => new KeyValuePair(nameof(Timestamp), Timestamp), - 3 => new KeyValuePair(nameof(ConnectionId), ConnectionId), - 4 => new KeyValuePair(nameof(TransactionId), TransactionId), - 5 => new KeyValuePair(nameof(Command), Command), - 6 => new KeyValuePair(nameof(Exception), Exception), - _ => throw new IndexOutOfRangeException(nameof(index)), - }; - } - - /// - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - - /// - public IEnumerator> GetEnumerator() - { - int count = Count; - for (int index = 0; index < count; index++) - { - yield return this[index]; - } - } - } - - /// - public sealed class SqlClientConnectionOpenBefore : IReadOnlyList> - { - /// - public const string Name = "Microsoft.Data.SqlClient.WriteConnectionOpenBefore"; - - internal SqlClientConnectionOpenBefore(Guid operationId, string operation, long timestamp, SqlConnection connection, string clientVersion) - { - OperationId = operationId; - Operation = operation; - Timestamp = timestamp; - Connection = connection; - ClientVersion = clientVersion; - } - - /// - public Guid OperationId { get; } - /// - public string Operation { get; } - /// - public long Timestamp { get; } - /// - public SqlConnection Connection { get; } - /// - public string ClientVersion { get; } - - /// - public int Count => 3 + 2; - - /// - public KeyValuePair this[int index] - { - get => index switch - { - 0 => new KeyValuePair(nameof(OperationId), OperationId), - 1 => new KeyValuePair(nameof(Operation), Operation), - 2 => new KeyValuePair(nameof(Timestamp), Timestamp), - 3 => new KeyValuePair(nameof(Connection), Connection), - 4 => new KeyValuePair(nameof(ClientVersion), ClientVersion), - _ => throw new IndexOutOfRangeException(nameof(index)), - }; - } - - /// - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - - /// - public IEnumerator> GetEnumerator() - { - int count = Count; - for (int index = 0; index < count; index++) - { - yield return this[index]; - } - } - } - - /// - public sealed class SqlClientConnectionOpenAfter : IReadOnlyList> - { - /// - public const string Name = "Microsoft.Data.SqlClient.WriteConnectionOpenAfter"; - - internal SqlClientConnectionOpenAfter(Guid operationId, string operation, long timestamp, Guid connectionId, SqlConnection connection, string clientVersion, IDictionary statistics) - { - OperationId = operationId; - Operation = operation; - Timestamp = timestamp; - ConnectionId = connectionId; - Connection = connection; - ClientVersion = clientVersion; - Statistics = statistics; - } - - /// - public Guid OperationId { get; } - /// - public string Operation { get; } - /// - public long Timestamp { get; } - /// - public Guid ConnectionId { get; } - /// - public SqlConnection Connection { get; } - /// - public string ClientVersion { get; } - /// - public IDictionary Statistics { get; } - - /// - public int Count => 3 + 4; - - /// - public KeyValuePair this[int index] - { - get => index switch - { - 0 => new KeyValuePair(nameof(OperationId), OperationId), - 1 => new KeyValuePair(nameof(Operation), Operation), - 2 => new KeyValuePair(nameof(Timestamp), Timestamp), - 3 => new KeyValuePair(nameof(ConnectionId), ConnectionId), - 4 => new KeyValuePair(nameof(Connection), Connection), - 5 => new KeyValuePair(nameof(ClientVersion), ClientVersion), - 6 => new KeyValuePair(nameof(Statistics), Statistics), - _ => throw new IndexOutOfRangeException(nameof(index)), - }; - } - - /// - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - - /// - public IEnumerator> GetEnumerator() - { - int count = Count; - for (int index = 0; index < count; index++) - { - yield return this[index]; - } - } - } - - /// - public sealed class SqlClientConnectionOpenError : IReadOnlyList> - { - /// - - public const string Name = "Microsoft.Data.SqlClient.WriteConnectionOpenError"; - - internal SqlClientConnectionOpenError(Guid operationId, string operation, long timestamp, Guid connectionId, SqlConnection connection, string clientVersion, Exception exception) - { - OperationId = operationId; - Operation = operation; - Timestamp = timestamp; - ConnectionId = connectionId; - Connection = connection; - ClientVersion = clientVersion; - Exception = exception; - } - - /// - public Guid OperationId { get; } - /// - public string Operation { get; } - /// - public long Timestamp { get; } - - /// - public Guid ConnectionId { get; } - /// - public SqlConnection Connection { get; } - /// - public string ClientVersion { get; } - /// - public Exception Exception { get; } - - /// - public int Count => 3 + 4; - - /// - public KeyValuePair this[int index] - { - get => index switch - { - 0 => new KeyValuePair(nameof(OperationId), OperationId), - 1 => new KeyValuePair(nameof(Operation), Operation), - 2 => new KeyValuePair(nameof(Timestamp), Timestamp), - 3 => new KeyValuePair(nameof(ConnectionId), ConnectionId), - 4 => new KeyValuePair(nameof(Connection), Connection), - 5 => new KeyValuePair(nameof(ClientVersion), ClientVersion), - 6 => new KeyValuePair(nameof(Exception), Exception), - _ => throw new IndexOutOfRangeException(nameof(index)), - }; - } - - /// - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - - /// - public IEnumerator> GetEnumerator() - { - int count = Count; - for (int index = 0; index < count; index++) - { - yield return this[index]; - } - } - } - - /// - public sealed class SqlClientConnectionCloseBefore : IReadOnlyList> - { - /// - public const string Name = "Microsoft.Data.SqlClient.WriteConnectionCloseBefore"; - - internal SqlClientConnectionCloseBefore(Guid operationId, string operation, long timestamp, Guid? connectionId, SqlConnection connection, IDictionary statistics) - { - OperationId = operationId; - Operation = operation; - Timestamp = timestamp; - ConnectionId = connectionId; - Connection = connection; - Statistics = statistics; - } - - /// - public Guid OperationId { get; } - /// - public string Operation { get; } - /// - public long Timestamp { get; } - /// - public Guid? ConnectionId { get; } - /// - public SqlConnection Connection { get; } - /// - public IDictionary Statistics { get; } - - /// - public int Count => 3 + 3; - - /// - public KeyValuePair this[int index] - { - get => index switch - { - 0 => new KeyValuePair(nameof(OperationId), OperationId), - 1 => new KeyValuePair(nameof(Operation), Operation), - 2 => new KeyValuePair(nameof(Timestamp), Timestamp), - 3 => new KeyValuePair(nameof(ConnectionId), ConnectionId), - 4 => new KeyValuePair(nameof(Connection), Connection), - 5 => new KeyValuePair(nameof(Statistics), Statistics), - _ => throw new IndexOutOfRangeException(nameof(index)), - }; - } - - /// - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - - /// - public IEnumerator> GetEnumerator() - { - int count = Count; - for (int index = 0; index < count; index++) - { - yield return this[index]; - } - } - } - - /// - public sealed class SqlClientConnectionCloseAfter : IReadOnlyList> - { - /// - public const string Name = "Microsoft.Data.SqlClient.WriteConnectionCloseAfter"; - - internal SqlClientConnectionCloseAfter(Guid operationId, string operation, long timestamp, Guid? connectionId, SqlConnection connection, IDictionary statistics) - { - OperationId = operationId; - Operation = operation; - Timestamp = timestamp; - ConnectionId = connectionId; - Connection = connection; - Statistics = statistics; - } - - /// - public Guid OperationId { get; } - /// - public string Operation { get; } - /// - public long Timestamp { get; } - /// - public Guid? ConnectionId { get; } - /// - public SqlConnection Connection { get; } - /// - public IDictionary Statistics { get; } - - /// - public int Count => 3 + 3; - - /// - public KeyValuePair this[int index] - { - get => index switch - { - 0 => new KeyValuePair(nameof(OperationId), OperationId), - 1 => new KeyValuePair(nameof(Operation), Operation), - 2 => new KeyValuePair(nameof(Timestamp), Timestamp), - 3 => new KeyValuePair(nameof(ConnectionId), ConnectionId), - 4 => new KeyValuePair(nameof(Connection), Connection), - 5 => new KeyValuePair(nameof(Statistics), Statistics), - _ => throw new IndexOutOfRangeException(nameof(index)), - }; - } - - /// - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - - /// - public IEnumerator> GetEnumerator() - { - int count = Count; - for (int index = 0; index < count; index++) - { - yield return this[index]; - } - } - } - - /// - public sealed class SqlClientConnectionCloseError : IReadOnlyList> - { - /// - public const string Name = "Microsoft.Data.SqlClient.WriteConnectionCloseError"; - - internal SqlClientConnectionCloseError(Guid operationId, string operation, long timestamp, Guid? connectionId, SqlConnection connection, IDictionary statistics, Exception ex) - { - OperationId = operationId; - Operation = operation; - Timestamp = timestamp; - ConnectionId = connectionId; - Connection = connection; - Statistics = statistics; - Exception = ex; - } - - /// - public Guid OperationId { get; } - /// - public string Operation { get; } - /// - public long Timestamp { get; } - - /// - public Guid? ConnectionId { get; } - /// - public SqlConnection Connection { get; } - /// - public IDictionary Statistics { get; } - - /// - public Exception Exception { get; } - - /// - public int Count => 3 + 4; - - /// - public KeyValuePair this[int index] - { - get => index switch - { - 0 => new KeyValuePair(nameof(OperationId), OperationId), - 1 => new KeyValuePair(nameof(Operation), Operation), - 2 => new KeyValuePair(nameof(Timestamp), Timestamp), - 3 => new KeyValuePair(nameof(ConnectionId), ConnectionId), - 4 => new KeyValuePair(nameof(Connection), Connection), - 5 => new KeyValuePair(nameof(Statistics), Statistics), - 6 => new KeyValuePair(nameof(Exception), Exception), - _ => throw new IndexOutOfRangeException(nameof(index)), - }; - } - - /// - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - - /// - public IEnumerator> GetEnumerator() - { - int count = Count; - for (int index = 0; index < count; index++) - { - yield return this[index]; - } - } - } - - /// - public sealed class SqlClientTransactionCommitBefore : IReadOnlyList> - { - /// - public const string Name = "Microsoft.Data.SqlClient.WriteTransactionCommitBefore"; - - internal SqlClientTransactionCommitBefore(Guid operationId, string operation, long timestamp, IsolationLevel isolationLevel, SqlConnection connection, long? transactionId) - { - OperationId = operationId; - Operation = operation; - Timestamp = timestamp; - IsolationLevel = isolationLevel; - Connection = connection; - TransactionId = transactionId; - } - - /// - public Guid OperationId { get; } - /// - public string Operation { get; } - /// - public long Timestamp { get; } - /// - public IsolationLevel IsolationLevel { get; } - /// - public SqlConnection Connection { get; } - /// - public long? TransactionId { get; } - - /// - public int Count => 3 + 3; - - /// - public KeyValuePair this[int index] - { - get => index switch - { - 0 => new KeyValuePair(nameof(OperationId), OperationId), - 1 => new KeyValuePair(nameof(Operation), Operation), - 2 => new KeyValuePair(nameof(Timestamp), Timestamp), - 3 => new KeyValuePair(nameof(IsolationLevel), IsolationLevel), - 4 => new KeyValuePair(nameof(Connection), Connection), - 5 => new KeyValuePair(nameof(TransactionId), TransactionId), - _ => throw new IndexOutOfRangeException(nameof(index)), - }; - } - - /// - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - - /// - public IEnumerator> GetEnumerator() - { - int count = Count; - for (int index = 0; index < count; index++) - { - yield return this[index]; - } - } - } - - /// - public sealed class SqlClientTransactionCommitAfter : IReadOnlyList> - { - /// - public const string Name = "Microsoft.Data.SqlClient.WriteTransactionCommitAfter"; - - internal SqlClientTransactionCommitAfter(Guid operationId, string operation, long timestamp, IsolationLevel isolationLevel, SqlConnection connection, long? transactionId) - { - OperationId = operationId; - Operation = operation; - Timestamp = timestamp; - IsolationLevel = isolationLevel; - Connection = connection; - TransactionId = transactionId; - } - - /// - public Guid OperationId { get; } - /// - public string Operation { get; } - /// - public long Timestamp { get; } - - /// - public IsolationLevel IsolationLevel { get; } - /// - public SqlConnection Connection { get; } - /// - public long? TransactionId { get; } - - /// - public int Count => 3 + 3; - - /// - public KeyValuePair this[int index] - { - get => index switch - { - 0 => new KeyValuePair(nameof(OperationId), OperationId), - 1 => new KeyValuePair(nameof(Operation), Operation), - 2 => new KeyValuePair(nameof(Timestamp), Timestamp), - 3 => new KeyValuePair(nameof(IsolationLevel), IsolationLevel), - 4 => new KeyValuePair(nameof(Connection), Connection), - 5 => new KeyValuePair(nameof(TransactionId), TransactionId), - _ => throw new IndexOutOfRangeException(nameof(index)), - }; - } - - /// - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - - /// - public IEnumerator> GetEnumerator() - { - int count = Count; - for (int index = 0; index < count; index++) - { - yield return this[index]; - } - } - } - - /// - public sealed class SqlClientTransactionCommitError : IReadOnlyList> - { - /// - public const string Name = "Microsoft.Data.SqlClient.WriteTransactionCommitError"; - - internal SqlClientTransactionCommitError(Guid operationId, string operation, long timestamp, IsolationLevel isolationLevel, SqlConnection connection, long? transactionId, Exception ex) - { - OperationId = operationId; - Operation = operation; - Timestamp = timestamp; - IsolationLevel = isolationLevel; - Connection = connection; - TransactionId = transactionId; - Exception = ex; - } - - /// - public Guid OperationId { get; } - /// - public string Operation { get; } - /// - public long Timestamp { get; } - - /// - public IsolationLevel IsolationLevel { get; } - /// - public SqlConnection Connection { get; } - /// - public long? TransactionId { get; } - /// - public Exception Exception { get; } - - /// - public int Count => 3 + 4; - - /// - public KeyValuePair this[int index] - { - get => index switch - { - 0 => new KeyValuePair(nameof(OperationId), OperationId), - 1 => new KeyValuePair(nameof(Operation), Operation), - 2 => new KeyValuePair(nameof(Timestamp), Timestamp), - 3 => new KeyValuePair(nameof(IsolationLevel), IsolationLevel), - 4 => new KeyValuePair(nameof(Connection), Connection), - 5 => new KeyValuePair(nameof(TransactionId), TransactionId), - 6 => new KeyValuePair(nameof(Exception), Exception), - _ => throw new IndexOutOfRangeException(nameof(index)), - }; - } - - /// - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - - /// - public IEnumerator> GetEnumerator() - { - int count = Count; - for (int index = 0; index < count; index++) - { - yield return this[index]; - } - } - } - - /// - public sealed class SqlClientTransactionRollbackBefore : IReadOnlyList> - { - /// - public const string Name = "Microsoft.Data.SqlClient.WriteTransactionRollbackBefore"; - - internal SqlClientTransactionRollbackBefore(Guid operationId, string operation, long timestamp, IsolationLevel isolationLevel, SqlConnection connection, long? transactionId, string transactionName) - { - OperationId = operationId; - Operation = operation; - Timestamp = timestamp; - IsolationLevel = isolationLevel; - Connection = connection; - TransactionId = transactionId; - TransactionName = transactionName; - } - - /// - public Guid OperationId { get; } - /// - public string Operation { get; } - /// - public long Timestamp { get; } - - /// - public IsolationLevel IsolationLevel { get; } - /// - public SqlConnection Connection { get; } - /// - public long? TransactionId { get; } - /// - public string TransactionName { get; } - - /// - public int Count => 3 + 4; - - /// - public KeyValuePair this[int index] - { - get => index switch - { - 0 => new KeyValuePair(nameof(OperationId), OperationId), - 1 => new KeyValuePair(nameof(Operation), Operation), - 2 => new KeyValuePair(nameof(Timestamp), Timestamp), - 3 => new KeyValuePair(nameof(IsolationLevel), IsolationLevel), - 4 => new KeyValuePair(nameof(Connection), Connection), - 5 => new KeyValuePair(nameof(TransactionId), TransactionId), - 6 => new KeyValuePair(nameof(TransactionName), TransactionName), - _ => throw new IndexOutOfRangeException(nameof(index)), - }; - } - - /// - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - - /// - public IEnumerator> GetEnumerator() - { - int count = Count; - for (int index = 0; index < count; index++) - { - yield return this[index]; - } - } - } - - /// - public sealed class SqlClientTransactionRollbackAfter : IReadOnlyList> - { - /// - public const string Name = "Microsoft.Data.SqlClient.WriteTransactionRollbackAfter"; - - internal SqlClientTransactionRollbackAfter(Guid operationId, string operation, long timestamp, IsolationLevel isolationLevel, SqlConnection connection, long? transactionId, string transactionName) - { - OperationId = operationId; - Operation = operation; - Timestamp = timestamp; - IsolationLevel = isolationLevel; - Connection = connection; - TransactionId = transactionId; - TransactionName = transactionName; - } - - /// - public Guid OperationId { get; } - /// - public string Operation { get; } - /// - public long Timestamp { get; } - /// - public IsolationLevel IsolationLevel { get; } - /// - public SqlConnection Connection { get; } - /// - public long? TransactionId { get; } - /// - public string TransactionName { get; } - - /// - public int Count => 3 + 4; - - /// - public KeyValuePair this[int index] - { - get => index switch - { - 0 => new KeyValuePair(nameof(OperationId), OperationId), - 1 => new KeyValuePair(nameof(Operation), Operation), - 2 => new KeyValuePair(nameof(Timestamp), Timestamp), - 3 => new KeyValuePair(nameof(IsolationLevel), IsolationLevel), - 4 => new KeyValuePair(nameof(Connection), Connection), - 5 => new KeyValuePair(nameof(TransactionId), TransactionId), - 6 => new KeyValuePair(nameof(TransactionName), TransactionName), - _ => throw new IndexOutOfRangeException(nameof(index)), - }; - } - - /// - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - - /// - public IEnumerator> GetEnumerator() - { - int count = Count; - for (int index = 0; index < count; index++) - { - yield return this[index]; - } - } - } - - /// - public sealed class SqlClientTransactionRollbackError : IReadOnlyList> - { - /// - public const string Name = "Microsoft.Data.SqlClient.WriteTransactionRollbackError"; - - internal SqlClientTransactionRollbackError(Guid operationId, string operation, long timestamp, IsolationLevel isolationLevel, SqlConnection connection, long? transactionId, string transactionName, Exception ex) - { - OperationId = operationId; - Operation = operation; - Timestamp = timestamp; - IsolationLevel = isolationLevel; - Connection = connection; - TransactionId = transactionId; - TransactionName = transactionName; - Exception = ex; - } - - - /// - public Guid OperationId { get; } - /// - public string Operation { get; } - /// - public long Timestamp { get; } - /// - public IsolationLevel IsolationLevel { get; } - /// - public SqlConnection Connection { get; } - /// - public long? TransactionId { get; } - /// - public string TransactionName { get; } - /// - public Exception Exception { get; } - - /// - public int Count => 3 + 5; - - /// - public KeyValuePair this[int index] - { - get => index switch - { - 0 => new KeyValuePair(nameof(OperationId), OperationId), - 1 => new KeyValuePair(nameof(Operation), Operation), - 2 => new KeyValuePair(nameof(Timestamp), Timestamp), - 3 => new KeyValuePair(nameof(IsolationLevel), IsolationLevel), - 4 => new KeyValuePair(nameof(Connection), Connection), - 5 => new KeyValuePair(nameof(TransactionId), TransactionId), - 6 => new KeyValuePair(nameof(TransactionName), TransactionName), - 7 => new KeyValuePair(nameof(Exception), Exception), - _ => throw new IndexOutOfRangeException(nameof(index)), - }; - } - - /// - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - - /// - public IEnumerator> GetEnumerator() - { - int count = Count; - for (int index = 0; index < count; index++) - { - yield return this[index]; - } - } - } -} - -#endif diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientTransactionCommitAfter.netcore.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientTransactionCommitAfter.netcore.cs new file mode 100644 index 0000000000..d2d8eb1ed7 --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientTransactionCommitAfter.netcore.cs @@ -0,0 +1,77 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#if NET + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Data; + +namespace Microsoft.Data.SqlClient.Diagnostics +{ + /// + public sealed class SqlClientTransactionCommitAfter : IReadOnlyList> + { + /// + public const string Name = "Microsoft.Data.SqlClient.WriteTransactionCommitAfter"; + + internal SqlClientTransactionCommitAfter(Guid operationId, string operation, long timestamp, IsolationLevel isolationLevel, SqlConnection connection, long? transactionId) + { + OperationId = operationId; + Operation = operation; + Timestamp = timestamp; + IsolationLevel = isolationLevel; + Connection = connection; + TransactionId = transactionId; + } + + /// + public Guid OperationId { get; } + /// + public string Operation { get; } + /// + public long Timestamp { get; } + + /// + public IsolationLevel IsolationLevel { get; } + /// + public SqlConnection Connection { get; } + /// + public long? TransactionId { get; } + + /// + public int Count => 3 + 3; + + /// + public KeyValuePair this[int index] + { + get => index switch + { + 0 => new KeyValuePair(nameof(OperationId), OperationId), + 1 => new KeyValuePair(nameof(Operation), Operation), + 2 => new KeyValuePair(nameof(Timestamp), Timestamp), + 3 => new KeyValuePair(nameof(IsolationLevel), IsolationLevel), + 4 => new KeyValuePair(nameof(Connection), Connection), + 5 => new KeyValuePair(nameof(TransactionId), TransactionId), + _ => throw new IndexOutOfRangeException(nameof(index)), + }; + } + + /// + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + + /// + public IEnumerator> GetEnumerator() + { + int count = Count; + for (int index = 0; index < count; index++) + { + yield return this[index]; + } + } + } +} + +#endif diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientTransactionCommitBefore.netcore.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientTransactionCommitBefore.netcore.cs new file mode 100644 index 0000000000..14bba6039d --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientTransactionCommitBefore.netcore.cs @@ -0,0 +1,76 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#if NET + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Data; + +namespace Microsoft.Data.SqlClient.Diagnostics +{ + /// + public sealed class SqlClientTransactionCommitBefore : IReadOnlyList> + { + /// + public const string Name = "Microsoft.Data.SqlClient.WriteTransactionCommitBefore"; + + internal SqlClientTransactionCommitBefore(Guid operationId, string operation, long timestamp, IsolationLevel isolationLevel, SqlConnection connection, long? transactionId) + { + OperationId = operationId; + Operation = operation; + Timestamp = timestamp; + IsolationLevel = isolationLevel; + Connection = connection; + TransactionId = transactionId; + } + + /// + public Guid OperationId { get; } + /// + public string Operation { get; } + /// + public long Timestamp { get; } + /// + public IsolationLevel IsolationLevel { get; } + /// + public SqlConnection Connection { get; } + /// + public long? TransactionId { get; } + + /// + public int Count => 3 + 3; + + /// + public KeyValuePair this[int index] + { + get => index switch + { + 0 => new KeyValuePair(nameof(OperationId), OperationId), + 1 => new KeyValuePair(nameof(Operation), Operation), + 2 => new KeyValuePair(nameof(Timestamp), Timestamp), + 3 => new KeyValuePair(nameof(IsolationLevel), IsolationLevel), + 4 => new KeyValuePair(nameof(Connection), Connection), + 5 => new KeyValuePair(nameof(TransactionId), TransactionId), + _ => throw new IndexOutOfRangeException(nameof(index)), + }; + } + + /// + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + + /// + public IEnumerator> GetEnumerator() + { + int count = Count; + for (int index = 0; index < count; index++) + { + yield return this[index]; + } + } + } +} + +#endif diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientTransactionCommitError.netcore.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientTransactionCommitError.netcore.cs new file mode 100644 index 0000000000..da73014993 --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientTransactionCommitError.netcore.cs @@ -0,0 +1,81 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#if NET + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Data; + +namespace Microsoft.Data.SqlClient.Diagnostics +{ + /// + public sealed class SqlClientTransactionCommitError : IReadOnlyList> + { + /// + public const string Name = "Microsoft.Data.SqlClient.WriteTransactionCommitError"; + + internal SqlClientTransactionCommitError(Guid operationId, string operation, long timestamp, IsolationLevel isolationLevel, SqlConnection connection, long? transactionId, Exception ex) + { + OperationId = operationId; + Operation = operation; + Timestamp = timestamp; + IsolationLevel = isolationLevel; + Connection = connection; + TransactionId = transactionId; + Exception = ex; + } + + /// + public Guid OperationId { get; } + /// + public string Operation { get; } + /// + public long Timestamp { get; } + + /// + public IsolationLevel IsolationLevel { get; } + /// + public SqlConnection Connection { get; } + /// + public long? TransactionId { get; } + /// + public Exception Exception { get; } + + /// + public int Count => 3 + 4; + + /// + public KeyValuePair this[int index] + { + get => index switch + { + 0 => new KeyValuePair(nameof(OperationId), OperationId), + 1 => new KeyValuePair(nameof(Operation), Operation), + 2 => new KeyValuePair(nameof(Timestamp), Timestamp), + 3 => new KeyValuePair(nameof(IsolationLevel), IsolationLevel), + 4 => new KeyValuePair(nameof(Connection), Connection), + 5 => new KeyValuePair(nameof(TransactionId), TransactionId), + 6 => new KeyValuePair(nameof(Exception), Exception), + _ => throw new IndexOutOfRangeException(nameof(index)), + }; + } + + /// + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + + /// + public IEnumerator> GetEnumerator() + { + int count = Count; + for (int index = 0; index < count; index++) + { + yield return this[index]; + } + } + } +} + +#endif diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientTransactionRollbackAfter.netcore.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientTransactionRollbackAfter.netcore.cs new file mode 100644 index 0000000000..9042e2dac2 --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientTransactionRollbackAfter.netcore.cs @@ -0,0 +1,80 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#if NET + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Data; + +namespace Microsoft.Data.SqlClient.Diagnostics +{ + /// + public sealed class SqlClientTransactionRollbackAfter : IReadOnlyList> + { + /// + public const string Name = "Microsoft.Data.SqlClient.WriteTransactionRollbackAfter"; + + internal SqlClientTransactionRollbackAfter(Guid operationId, string operation, long timestamp, IsolationLevel isolationLevel, SqlConnection connection, long? transactionId, string transactionName) + { + OperationId = operationId; + Operation = operation; + Timestamp = timestamp; + IsolationLevel = isolationLevel; + Connection = connection; + TransactionId = transactionId; + TransactionName = transactionName; + } + + /// + public Guid OperationId { get; } + /// + public string Operation { get; } + /// + public long Timestamp { get; } + /// + public IsolationLevel IsolationLevel { get; } + /// + public SqlConnection Connection { get; } + /// + public long? TransactionId { get; } + /// + public string TransactionName { get; } + + /// + public int Count => 3 + 4; + + /// + public KeyValuePair this[int index] + { + get => index switch + { + 0 => new KeyValuePair(nameof(OperationId), OperationId), + 1 => new KeyValuePair(nameof(Operation), Operation), + 2 => new KeyValuePair(nameof(Timestamp), Timestamp), + 3 => new KeyValuePair(nameof(IsolationLevel), IsolationLevel), + 4 => new KeyValuePair(nameof(Connection), Connection), + 5 => new KeyValuePair(nameof(TransactionId), TransactionId), + 6 => new KeyValuePair(nameof(TransactionName), TransactionName), + _ => throw new IndexOutOfRangeException(nameof(index)), + }; + } + + /// + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + + /// + public IEnumerator> GetEnumerator() + { + int count = Count; + for (int index = 0; index < count; index++) + { + yield return this[index]; + } + } + } +} + +#endif diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientTransactionRollbackBefore.netcore.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientTransactionRollbackBefore.netcore.cs new file mode 100644 index 0000000000..5b88192c8d --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientTransactionRollbackBefore.netcore.cs @@ -0,0 +1,81 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#if NET + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Data; + +namespace Microsoft.Data.SqlClient.Diagnostics +{ + /// + public sealed class SqlClientTransactionRollbackBefore : IReadOnlyList> + { + /// + public const string Name = "Microsoft.Data.SqlClient.WriteTransactionRollbackBefore"; + + internal SqlClientTransactionRollbackBefore(Guid operationId, string operation, long timestamp, IsolationLevel isolationLevel, SqlConnection connection, long? transactionId, string transactionName) + { + OperationId = operationId; + Operation = operation; + Timestamp = timestamp; + IsolationLevel = isolationLevel; + Connection = connection; + TransactionId = transactionId; + TransactionName = transactionName; + } + + /// + public Guid OperationId { get; } + /// + public string Operation { get; } + /// + public long Timestamp { get; } + + /// + public IsolationLevel IsolationLevel { get; } + /// + public SqlConnection Connection { get; } + /// + public long? TransactionId { get; } + /// + public string TransactionName { get; } + + /// + public int Count => 3 + 4; + + /// + public KeyValuePair this[int index] + { + get => index switch + { + 0 => new KeyValuePair(nameof(OperationId), OperationId), + 1 => new KeyValuePair(nameof(Operation), Operation), + 2 => new KeyValuePair(nameof(Timestamp), Timestamp), + 3 => new KeyValuePair(nameof(IsolationLevel), IsolationLevel), + 4 => new KeyValuePair(nameof(Connection), Connection), + 5 => new KeyValuePair(nameof(TransactionId), TransactionId), + 6 => new KeyValuePair(nameof(TransactionName), TransactionName), + _ => throw new IndexOutOfRangeException(nameof(index)), + }; + } + + /// + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + + /// + public IEnumerator> GetEnumerator() + { + int count = Count; + for (int index = 0; index < count; index++) + { + yield return this[index]; + } + } + } +} + +#endif diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientTransactionRollbackError.netcore.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientTransactionRollbackError.netcore.cs new file mode 100644 index 0000000000..3af5e3c18f --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientTransactionRollbackError.netcore.cs @@ -0,0 +1,85 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#if NET + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Data; + +namespace Microsoft.Data.SqlClient.Diagnostics +{ + /// + public sealed class SqlClientTransactionRollbackError : IReadOnlyList> + { + /// + public const string Name = "Microsoft.Data.SqlClient.WriteTransactionRollbackError"; + + internal SqlClientTransactionRollbackError(Guid operationId, string operation, long timestamp, IsolationLevel isolationLevel, SqlConnection connection, long? transactionId, string transactionName, Exception ex) + { + OperationId = operationId; + Operation = operation; + Timestamp = timestamp; + IsolationLevel = isolationLevel; + Connection = connection; + TransactionId = transactionId; + TransactionName = transactionName; + Exception = ex; + } + + + /// + public Guid OperationId { get; } + /// + public string Operation { get; } + /// + public long Timestamp { get; } + /// + public IsolationLevel IsolationLevel { get; } + /// + public SqlConnection Connection { get; } + /// + public long? TransactionId { get; } + /// + public string TransactionName { get; } + /// + public Exception Exception { get; } + + /// + public int Count => 3 + 5; + + /// + public KeyValuePair this[int index] + { + get => index switch + { + 0 => new KeyValuePair(nameof(OperationId), OperationId), + 1 => new KeyValuePair(nameof(Operation), Operation), + 2 => new KeyValuePair(nameof(Timestamp), Timestamp), + 3 => new KeyValuePair(nameof(IsolationLevel), IsolationLevel), + 4 => new KeyValuePair(nameof(Connection), Connection), + 5 => new KeyValuePair(nameof(TransactionId), TransactionId), + 6 => new KeyValuePair(nameof(TransactionName), TransactionName), + 7 => new KeyValuePair(nameof(Exception), Exception), + _ => throw new IndexOutOfRangeException(nameof(index)), + }; + } + + /// + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + + /// + public IEnumerator> GetEnumerator() + { + int count = Count; + for (int index = 0; index < count; index++) + { + yield return this[index]; + } + } + } +} + +#endif From 5c7ef3ef903258f0d14fb7fff44260b99abb2a57 Mon Sep 17 00:00:00 2001 From: Ben Russell Date: Wed, 12 Mar 2025 16:48:11 -0500 Subject: [PATCH 4/6] Put extension methods back in the listener class itself. --- .../Microsoft/Data/SqlClient/SqlCommand.cs | 2 +- .../Microsoft/Data/SqlClient/SqlConnection.cs | 2 +- .../Data/SqlClient/SqlTransaction.cs | 2 +- ...entDiagnosticListenerExtensions.netcore.cs | 357 ------------------ .../SqlDiagnosticListener.netcore.cs | 351 +++++++++++++++++ 5 files changed, 354 insertions(+), 360 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlCommand.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlCommand.cs index 13317a80e4..070d35ab73 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlCommand.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlCommand.cs @@ -159,7 +159,7 @@ protected override void AfterCleared(SqlCommand owner) private static bool _forceRetryableEnclaveQueryExecutionExceptionDuringGenerateEnclavePackage = false; #endif - private static readonly SqlDiagnosticListener s_diagnosticListener = new SqlDiagnosticListener(SqlClientDiagnosticListenerExtensions.DiagnosticListenerName); + private static readonly SqlDiagnosticListener s_diagnosticListener = new SqlDiagnosticListener(SqlDiagnosticListener.DiagnosticListenerName); private bool _parentOperationStarted = false; internal static readonly Action s_cancelIgnoreFailure = CancelIgnoreFailureCallback; diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnection.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnection.cs index 6956e3ae61..6a7339e973 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnection.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnection.cs @@ -67,7 +67,7 @@ private enum CultureCheckState : uint private SqlRetryLogicBaseProvider _retryLogicProvider; // diagnostics listener - private static readonly SqlDiagnosticListener s_diagnosticListener = new SqlDiagnosticListener(SqlClientDiagnosticListenerExtensions.DiagnosticListenerName); + private static readonly SqlDiagnosticListener s_diagnosticListener = new SqlDiagnosticListener(SqlDiagnosticListener.DiagnosticListenerName); // Transient Fault handling flag. This is needed to convey to the downstream mechanism of connection establishment, if Transient Fault handling should be used or not // The downstream handling of Connection open is the same for idle connection resiliency. Currently we want to apply transient fault handling only to the connections opened diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlTransaction.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlTransaction.cs index 7b048a6198..59a8d19faa 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlTransaction.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlTransaction.cs @@ -12,7 +12,7 @@ namespace Microsoft.Data.SqlClient /// public sealed partial class SqlTransaction : DbTransaction { - private static readonly SqlDiagnosticListener s_diagnosticListener = new(SqlClientDiagnosticListenerExtensions.DiagnosticListenerName); + private static readonly SqlDiagnosticListener s_diagnosticListener = new(SqlDiagnosticListener.DiagnosticListenerName); //////////////////////////////////////////////////////////////////////////////////////// // PUBLIC METHODS diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientDiagnosticListenerExtensions.netcore.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientDiagnosticListenerExtensions.netcore.cs index 783534ce73..f4915e6903 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientDiagnosticListenerExtensions.netcore.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientDiagnosticListenerExtensions.netcore.cs @@ -5,368 +5,11 @@ #if NET using System; -using System.Collections; -using System.Collections.Generic; using System.Data; -using System.Diagnostics; using System.Runtime.CompilerServices; -using Microsoft.Data.SqlClient.Diagnostics; namespace Microsoft.Data.SqlClient { - /// - /// Extension methods on the DiagnosticListener class to log SqlCommand data - /// - internal static class SqlClientDiagnosticListenerExtensions - { - public const string DiagnosticListenerName = "SqlClientDiagnosticListener"; - - public static Guid WriteCommandBefore(this SqlDiagnosticListener @this, SqlCommand sqlCommand, SqlTransaction transaction, [CallerMemberName] string operation = "") - { - if (@this.IsEnabled(SqlClientCommandBefore.Name)) - { - Guid operationId = Guid.NewGuid(); - - @this.Write( - SqlClientCommandBefore.Name, - new SqlClientCommandBefore( - operationId, - operation, - Stopwatch.GetTimestamp(), - sqlCommand.Connection?.ClientConnectionId, - transaction?.InternalTransaction?.TransactionId, - sqlCommand - ) - ); - - return operationId; - } - else - { - return Guid.Empty; - } - } - - public static void WriteCommandAfter(this SqlDiagnosticListener @this, Guid operationId, SqlCommand sqlCommand, SqlTransaction transaction, [CallerMemberName] string operation = "") - { - if (@this.IsEnabled(SqlClientCommandAfter.Name)) - { - @this.Write( - SqlClientCommandAfter.Name, - new SqlClientCommandAfter( - operationId, - operation, - Stopwatch.GetTimestamp(), - sqlCommand.Connection?.ClientConnectionId, - transaction?.InternalTransaction?.TransactionId, - sqlCommand, - sqlCommand.Statistics?.GetDictionary() - ) - ); - } - } - - public static void WriteCommandError(this SqlDiagnosticListener @this, Guid operationId, SqlCommand sqlCommand, SqlTransaction transaction, Exception ex, [CallerMemberName] string operation = "") - { - if (@this.IsEnabled(SqlClientCommandError.Name)) - { - @this.Write( - SqlClientCommandError.Name, - new SqlClientCommandError - ( - operationId, - operation, - Stopwatch.GetTimestamp(), - sqlCommand.Connection?.ClientConnectionId, - transaction?.InternalTransaction?.TransactionId, - sqlCommand, - ex - ) - ); - } - } - - public static Guid WriteConnectionOpenBefore(this SqlDiagnosticListener @this, SqlConnection sqlConnection, [CallerMemberName] string operation = "") - { - if (@this.IsEnabled(SqlClientConnectionOpenBefore.Name)) - { - Guid operationId = Guid.NewGuid(); - - @this.Write( - SqlClientConnectionOpenBefore.Name, - new SqlClientConnectionOpenBefore - ( - operationId, - operation, - Stopwatch.GetTimestamp(), - sqlConnection, - ThisAssembly.InformationalVersion - ) - ); - - return operationId; - } - else - { - return Guid.Empty; - } - } - - public static void WriteConnectionOpenAfter(this SqlDiagnosticListener @this, Guid operationId, SqlConnection sqlConnection, [CallerMemberName] string operation = "") - { - if (@this.IsEnabled(SqlClientConnectionOpenAfter.Name)) - { - @this.Write( - SqlClientConnectionOpenAfter.Name, - new SqlClientConnectionOpenAfter - ( - operationId, - operation, - Stopwatch.GetTimestamp(), - sqlConnection.ClientConnectionId, - sqlConnection, - ThisAssembly.InformationalVersion, - sqlConnection.Statistics?.GetDictionary() - ) - ); - } - } - - public static void WriteConnectionOpenError(this SqlDiagnosticListener @this, Guid operationId, SqlConnection sqlConnection, Exception ex, [CallerMemberName] string operation = "") - { - if (@this.IsEnabled(SqlClientConnectionOpenError.Name)) - { - @this.Write( - SqlClientConnectionOpenError.Name, - new SqlClientConnectionOpenError - ( - operationId, - operation, - Stopwatch.GetTimestamp(), - sqlConnection.ClientConnectionId, - sqlConnection, - ThisAssembly.InformationalVersion, - ex - ) - ); - } - } - - public static Guid WriteConnectionCloseBefore(this SqlDiagnosticListener @this, SqlConnection sqlConnection, [CallerMemberName] string operation = "") - { - if (@this.IsEnabled(SqlClientConnectionCloseBefore.Name)) - { - Guid operationId = Guid.NewGuid(); - - @this.Write( - SqlClientConnectionCloseBefore.Name, - new SqlClientConnectionCloseBefore - ( - operationId, - operation, - Stopwatch.GetTimestamp(), - sqlConnection.ClientConnectionId, - sqlConnection, - sqlConnection.Statistics?.GetDictionary() - ) - ); - - return operationId; - } - else - return Guid.Empty; - } - - public static void WriteConnectionCloseAfter(this SqlDiagnosticListener @this, Guid operationId, Guid clientConnectionId, SqlConnection sqlConnection, [CallerMemberName] string operation = "") - { - if (@this.IsEnabled(SqlClientConnectionCloseAfter.Name)) - { - @this.Write( - SqlClientConnectionCloseAfter.Name, - new SqlClientConnectionCloseAfter - ( - operationId, - operation, - Stopwatch.GetTimestamp(), - clientConnectionId, - sqlConnection, - sqlConnection.Statistics?.GetDictionary() - ) - ); - } - } - - public static void WriteConnectionCloseError(this SqlDiagnosticListener @this, Guid operationId, Guid clientConnectionId, SqlConnection sqlConnection, Exception ex, [CallerMemberName] string operation = "") - { - if (@this.IsEnabled(SqlClientConnectionCloseError.Name)) - { - @this.Write( - SqlClientConnectionCloseError.Name, - new SqlClientConnectionCloseError - ( - operationId, - operation, - Stopwatch.GetTimestamp(), - clientConnectionId, - sqlConnection, - sqlConnection.Statistics?.GetDictionary(), - ex - ) - ); - } - } - - public static Guid WriteTransactionCommitBefore(this SqlDiagnosticListener @this, IsolationLevel isolationLevel, SqlConnection connection, SqlInternalTransaction transaction, [CallerMemberName] string operation = "") - { - if (@this.IsEnabled(SqlClientTransactionCommitBefore.Name)) - { - Guid operationId = Guid.NewGuid(); - - @this.Write( - SqlClientTransactionCommitBefore.Name, - new SqlClientTransactionCommitBefore - ( - operationId, - operation, - Stopwatch.GetTimestamp(), - isolationLevel, - connection, - transaction?.TransactionId - ) - ); - - return operationId; - } - else - { - return Guid.Empty; - } - } - - public static void WriteTransactionCommitAfter(this SqlDiagnosticListener @this, Guid operationId, IsolationLevel isolationLevel, SqlConnection connection, SqlInternalTransaction transaction, [CallerMemberName] string operation = "") - { - if (@this.IsEnabled(SqlClientTransactionCommitAfter.Name)) - { - @this.Write( - SqlClientTransactionCommitAfter.Name, - new SqlClientTransactionCommitAfter - ( - operationId, - operation, - Stopwatch.GetTimestamp(), - isolationLevel, - connection, - transaction?.TransactionId - ) - ); - } - } - - public static void WriteTransactionCommitError(this SqlDiagnosticListener @this, Guid operationId, IsolationLevel isolationLevel, SqlConnection connection, SqlInternalTransaction transaction, Exception ex, [CallerMemberName] string operation = "") - { - if (@this.IsEnabled(SqlClientTransactionCommitError.Name)) - { - @this.Write( - SqlClientTransactionCommitError.Name, - new SqlClientTransactionCommitError - ( - operationId, - operation, - Stopwatch.GetTimestamp(), - isolationLevel, - connection, - transaction?.TransactionId, - ex - ) - ); - } - } - - public static Guid WriteTransactionRollbackBefore(this SqlDiagnosticListener @this, IsolationLevel isolationLevel, SqlConnection connection, SqlInternalTransaction transaction, string transactionName = null, [CallerMemberName] string operation = "") - { - if (@this.IsEnabled(SqlClientTransactionRollbackBefore.Name)) - { - Guid operationId = Guid.NewGuid(); - - @this.Write( - SqlClientTransactionRollbackBefore.Name, - new SqlClientTransactionRollbackBefore - ( - operationId, - operation, - Stopwatch.GetTimestamp(), - isolationLevel, - connection, - transaction?.TransactionId, - transactionName - ) - ); - - return operationId; - } - else - { - return Guid.Empty; - } - } - - public static void WriteTransactionRollbackAfter(this SqlDiagnosticListener @this, Guid operationId, IsolationLevel isolationLevel, SqlConnection connection, SqlInternalTransaction transaction, string transactionName = null, [CallerMemberName] string operation = "") - { - if (@this.IsEnabled(SqlClientTransactionRollbackAfter.Name)) - { - @this.Write( - SqlClientTransactionRollbackAfter.Name, - new SqlClientTransactionRollbackAfter - ( - operationId, - operation, - Stopwatch.GetTimestamp(), - isolationLevel, - connection, - transaction?.TransactionId, - transactionName - ) - ); - } - } - - public static void WriteTransactionRollbackError(this SqlDiagnosticListener @this, Guid operationId, IsolationLevel isolationLevel, SqlConnection connection, SqlInternalTransaction transaction, Exception ex, string transactionName = null, [CallerMemberName] string operation = "") - { - if (@this.IsEnabled(SqlClientTransactionRollbackError.Name)) - { - @this.Write( - SqlClientTransactionRollbackError.Name, - new SqlClientTransactionRollbackError - ( - operationId, - operation, - Stopwatch.GetTimestamp(), - isolationLevel, - connection, - transaction?.TransactionId, - transactionName, - ex - ) - ); - } - } - - public static DiagnosticScope CreateCommandScope(this SqlDiagnosticListener @this, SqlCommand command, SqlTransaction transaction, [CallerMemberName] string operationName = "") - { - return DiagnosticScope.CreateCommandScope(@this, command, transaction, operationName); - } - - public static DiagnosticTransactionScope CreateTransactionCommitScope(this SqlDiagnosticListener @this, IsolationLevel isolationLevel, SqlConnection connection, SqlInternalTransaction transaction, [CallerMemberName] string operationName = "") - { - return DiagnosticTransactionScope.CreateTransactionCommitScope(@this, isolationLevel, connection, transaction, operationName); - } - - public static DiagnosticTransactionScope CreateTransactionRollbackScope(this SqlDiagnosticListener @this, IsolationLevel isolationLevel, SqlConnection connection, SqlInternalTransaction transaction, string transactionName, [CallerMemberName] string operationName = "") - { - return DiagnosticTransactionScope.CreateTransactionRollbackScope(@this, isolationLevel, connection, transaction, transactionName, operationName); - } - } - internal ref struct DiagnosticScope //: IDisposable //ref structs cannot implement interfaces but the compiler will use pattern matching { private const int CommandOperation = 1; diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlDiagnosticListener.netcore.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlDiagnosticListener.netcore.cs index 2c597cc0c6..c0c3a7f0f0 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlDiagnosticListener.netcore.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlDiagnosticListener.netcore.cs @@ -4,19 +4,370 @@ #if NET +using System; +using System.Data; using System.Diagnostics; using System.Reflection; +using System.Runtime.CompilerServices; using System.Runtime.Loader; +using Microsoft.Data.SqlClient.Diagnostics; namespace Microsoft.Data.SqlClient { internal sealed class SqlDiagnosticListener : DiagnosticListener { + public const string DiagnosticListenerName = "SqlClientDiagnosticListener"; + public SqlDiagnosticListener(string name) : base(name) { AssemblyLoadContext.GetLoadContext(Assembly.GetExecutingAssembly()).Unloading += SqlDiagnosticListener_Unloading; } + public DiagnosticScope CreateCommandScope(SqlCommand command, SqlTransaction transaction, [CallerMemberName] string operationName = "") + { + return DiagnosticScope.CreateCommandScope(this, command, transaction, operationName); + } + + public DiagnosticTransactionScope CreateTransactionCommitScope(IsolationLevel isolationLevel, SqlConnection connection, SqlInternalTransaction transaction, [CallerMemberName] string operationName = "") + { + return DiagnosticTransactionScope.CreateTransactionCommitScope(this, isolationLevel, connection, transaction, operationName); + } + + public DiagnosticTransactionScope CreateTransactionRollbackScope(IsolationLevel isolationLevel, SqlConnection connection, SqlInternalTransaction transaction, string transactionName, [CallerMemberName] string operationName = "") + { + return DiagnosticTransactionScope.CreateTransactionRollbackScope(this, isolationLevel, connection, transaction, transactionName, operationName); + } + + public void WriteCommandAfter(Guid operationId, SqlCommand sqlCommand, SqlTransaction transaction, [CallerMemberName] string operation = "") + { + if (IsEnabled(SqlClientCommandAfter.Name)) + { + Write( + SqlClientCommandAfter.Name, + new SqlClientCommandAfter( + operationId, + operation, + Stopwatch.GetTimestamp(), + sqlCommand.Connection?.ClientConnectionId, + transaction?.InternalTransaction?.TransactionId, + sqlCommand, + sqlCommand.Statistics?.GetDictionary() + ) + ); + } + } + + public Guid WriteCommandBefore(SqlCommand sqlCommand, SqlTransaction transaction, [CallerMemberName] string operation = "") + { + if (IsEnabled(SqlClientCommandBefore.Name)) + { + Guid operationId = Guid.NewGuid(); + + Write( + SqlClientCommandBefore.Name, + new SqlClientCommandBefore( + operationId, + operation, + Stopwatch.GetTimestamp(), + sqlCommand.Connection?.ClientConnectionId, + transaction?.InternalTransaction?.TransactionId, + sqlCommand + ) + ); + + return operationId; + } + else + { + return Guid.Empty; + } + } + + public void WriteCommandError(Guid operationId, SqlCommand sqlCommand, SqlTransaction transaction, Exception ex, [CallerMemberName] string operation = "") + { + if (IsEnabled(SqlClientCommandError.Name)) + { + Write( + SqlClientCommandError.Name, + new SqlClientCommandError + ( + operationId, + operation, + Stopwatch.GetTimestamp(), + sqlCommand.Connection?.ClientConnectionId, + transaction?.InternalTransaction?.TransactionId, + sqlCommand, + ex + ) + ); + } + } + + public void WriteConnectionCloseAfter(Guid operationId, Guid clientConnectionId, SqlConnection sqlConnection, [CallerMemberName] string operation = "") + { + if (IsEnabled(SqlClientConnectionCloseAfter.Name)) + { + Write( + SqlClientConnectionCloseAfter.Name, + new SqlClientConnectionCloseAfter + ( + operationId, + operation, + Stopwatch.GetTimestamp(), + clientConnectionId, + sqlConnection, + sqlConnection.Statistics?.GetDictionary() + ) + ); + } + } + + public Guid WriteConnectionCloseBefore(SqlConnection sqlConnection, [CallerMemberName] string operation = "") + { + if (IsEnabled(SqlClientConnectionCloseBefore.Name)) + { + Guid operationId = Guid.NewGuid(); + + Write( + SqlClientConnectionCloseBefore.Name, + new SqlClientConnectionCloseBefore + ( + operationId, + operation, + Stopwatch.GetTimestamp(), + sqlConnection.ClientConnectionId, + sqlConnection, + sqlConnection.Statistics?.GetDictionary() + ) + ); + + return operationId; + } + else + return Guid.Empty; + } + + public void WriteConnectionCloseError(Guid operationId, Guid clientConnectionId, SqlConnection sqlConnection, Exception ex, [CallerMemberName] string operation = "") + { + if (IsEnabled(SqlClientConnectionCloseError.Name)) + { + Write( + SqlClientConnectionCloseError.Name, + new SqlClientConnectionCloseError + ( + operationId, + operation, + Stopwatch.GetTimestamp(), + clientConnectionId, + sqlConnection, + sqlConnection.Statistics?.GetDictionary(), + ex + ) + ); + } + } + + public void WriteConnectionOpenAfter(Guid operationId, SqlConnection sqlConnection, [CallerMemberName] string operation = "") + { + if (IsEnabled(SqlClientConnectionOpenAfter.Name)) + { + Write( + SqlClientConnectionOpenAfter.Name, + new SqlClientConnectionOpenAfter + ( + operationId, + operation, + Stopwatch.GetTimestamp(), + sqlConnection.ClientConnectionId, + sqlConnection, + ThisAssembly.InformationalVersion, + sqlConnection.Statistics?.GetDictionary() + ) + ); + } + } + + public Guid WriteConnectionOpenBefore(SqlConnection sqlConnection, [CallerMemberName] string operation = "") + { + if (IsEnabled(SqlClientConnectionOpenBefore.Name)) + { + Guid operationId = Guid.NewGuid(); + + Write( + SqlClientConnectionOpenBefore.Name, + new SqlClientConnectionOpenBefore + ( + operationId, + operation, + Stopwatch.GetTimestamp(), + sqlConnection, + ThisAssembly.InformationalVersion + ) + ); + + return operationId; + } + else + { + return Guid.Empty; + } + } + + public void WriteConnectionOpenError(Guid operationId, SqlConnection sqlConnection, Exception ex, [CallerMemberName] string operation = "") + { + if (IsEnabled(SqlClientConnectionOpenError.Name)) + { + Write( + SqlClientConnectionOpenError.Name, + new SqlClientConnectionOpenError + ( + operationId, + operation, + Stopwatch.GetTimestamp(), + sqlConnection.ClientConnectionId, + sqlConnection, + ThisAssembly.InformationalVersion, + ex + ) + ); + } + } + + public void WriteTransactionCommitAfter(Guid operationId, IsolationLevel isolationLevel, SqlConnection connection, SqlInternalTransaction transaction, [CallerMemberName] string operation = "") + { + if (IsEnabled(SqlClientTransactionCommitAfter.Name)) + { + Write( + SqlClientTransactionCommitAfter.Name, + new SqlClientTransactionCommitAfter + ( + operationId, + operation, + Stopwatch.GetTimestamp(), + isolationLevel, + connection, + transaction?.TransactionId + ) + ); + } + } + + public Guid WriteTransactionCommitBefore(IsolationLevel isolationLevel, SqlConnection connection, SqlInternalTransaction transaction, [CallerMemberName] string operation = "") + { + if (IsEnabled(SqlClientTransactionCommitBefore.Name)) + { + Guid operationId = Guid.NewGuid(); + + Write( + SqlClientTransactionCommitBefore.Name, + new SqlClientTransactionCommitBefore + ( + operationId, + operation, + Stopwatch.GetTimestamp(), + isolationLevel, + connection, + transaction?.TransactionId + ) + ); + + return operationId; + } + else + { + return Guid.Empty; + } + } + + public void WriteTransactionCommitError(Guid operationId, IsolationLevel isolationLevel, SqlConnection connection, SqlInternalTransaction transaction, Exception ex, [CallerMemberName] string operation = "") + { + if (IsEnabled(SqlClientTransactionCommitError.Name)) + { + Write( + SqlClientTransactionCommitError.Name, + new SqlClientTransactionCommitError + ( + operationId, + operation, + Stopwatch.GetTimestamp(), + isolationLevel, + connection, + transaction?.TransactionId, + ex + ) + ); + } + } + + public void WriteTransactionRollbackAfter(Guid operationId, IsolationLevel isolationLevel, SqlConnection connection, SqlInternalTransaction transaction, string transactionName = null, [CallerMemberName] string operation = "") + { + if (IsEnabled(SqlClientTransactionRollbackAfter.Name)) + { + Write( + SqlClientTransactionRollbackAfter.Name, + new SqlClientTransactionRollbackAfter + ( + operationId, + operation, + Stopwatch.GetTimestamp(), + isolationLevel, + connection, + transaction?.TransactionId, + transactionName + ) + ); + } + } + + public Guid WriteTransactionRollbackBefore(IsolationLevel isolationLevel, SqlConnection connection, SqlInternalTransaction transaction, string transactionName = null, [CallerMemberName] string operation = "") + { + if (IsEnabled(SqlClientTransactionRollbackBefore.Name)) + { + Guid operationId = Guid.NewGuid(); + + Write( + SqlClientTransactionRollbackBefore.Name, + new SqlClientTransactionRollbackBefore + ( + operationId, + operation, + Stopwatch.GetTimestamp(), + isolationLevel, + connection, + transaction?.TransactionId, + transactionName + ) + ); + + return operationId; + } + else + { + return Guid.Empty; + } + } + + public void WriteTransactionRollbackError(Guid operationId, IsolationLevel isolationLevel, SqlConnection connection, SqlInternalTransaction transaction, Exception ex, string transactionName = null, [CallerMemberName] string operation = "") + { + if (IsEnabled(SqlClientTransactionRollbackError.Name)) + { + Write( + SqlClientTransactionRollbackError.Name, + new SqlClientTransactionRollbackError + ( + operationId, + operation, + Stopwatch.GetTimestamp(), + isolationLevel, + connection, + transaction?.TransactionId, + transactionName, + ex + ) + ); + } + } + private void SqlDiagnosticListener_Unloading(AssemblyLoadContext obj) { Dispose(); From 6bcb79b92c8221a6c0c06ff409bd71410dfd0455 Mon Sep 17 00:00:00 2001 From: Ben Russell Date: Wed, 12 Mar 2025 17:02:19 -0500 Subject: [PATCH 5/6] Decompose the extensions file into separate files for diagnostic scopes --- .../src/Microsoft.Data.SqlClient.csproj | 9 ++- .../Diagnostics/DiagnosticScope.netcore.cs | 79 +++++++++++++++++++ ... => DiagnosticTransactionScope.netcore.cs} | 69 +--------------- 3 files changed, 87 insertions(+), 70 deletions(-) create mode 100644 src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/DiagnosticScope.netcore.cs rename src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/{SqlClientDiagnosticListenerExtensions.netcore.cs => DiagnosticTransactionScope.netcore.cs} (58%) diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj index a07a46c8c8..43faf5dc2d 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj @@ -179,6 +179,12 @@ Microsoft\Data\SqlClient\DataClassification\SensitivityClassification.cs + + Microsoft\Data\SqlClient\Diagnostics\DiagnosticScope.netcore.cs + + + Microsoft\Data\SqlClient\Diagnostics\DiagnosticTransactionScope.netcore.cs + Microsoft\Data\SqlClient\Diagnostics\SqlClientCommandAfter.netcore.cs @@ -206,9 +212,6 @@ Microsoft\Data\SqlClient\Diagnostics\SqlClientConnectionOpenError.netcore.cs - - Microsoft\Data\SqlClient\Diagnostics\SqlClientDiagnosticListenerExtensions.netcore.cs - Microsoft\Data\SqlClient\Diagnostics\SqlClientTransactionCommitAfter.netcore.cs diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/DiagnosticScope.netcore.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/DiagnosticScope.netcore.cs new file mode 100644 index 0000000000..b2097ea73c --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/DiagnosticScope.netcore.cs @@ -0,0 +1,79 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#if NET + +using System; +using System.Runtime.CompilerServices; + +namespace Microsoft.Data.SqlClient +{ + internal ref struct DiagnosticScope //: IDisposable //ref structs cannot implement interfaces but the compiler will use pattern matching + { + private const int CommandOperation = 1; + private const int ConnectionOpenOperation = 2; + + 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 Exception _exception; + + private DiagnosticScope(SqlDiagnosticListener diagnostics, int operation, Guid operationsId, string operationName, object context1, object context2) + { + _diagnostics = diagnostics; + _operation = operation; + _operationId = operationsId; + _operationName = operationName; + _context1 = context1; + _context2 = context2; + _exception = null; + } + + public void Dispose() + { + switch (_operation) + { + case CommandOperation: + if (_exception != null) + { + _diagnostics.WriteCommandError(_operationId, (SqlCommand)_context1, (SqlTransaction)_context2, _exception, _operationName); + } + else + { + _diagnostics.WriteCommandAfter(_operationId, (SqlCommand)_context1, (SqlTransaction)_context2, _operationName); + } + break; + + case ConnectionOpenOperation: + if (_exception != null) + { + _diagnostics.WriteConnectionOpenError(_operationId, (SqlConnection)_context1, _exception, _operationName); + } + else + { + _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 + } + } + + 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); + } + } +} + +#endif diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientDiagnosticListenerExtensions.netcore.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/DiagnosticTransactionScope.netcore.cs similarity index 58% rename from src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientDiagnosticListenerExtensions.netcore.cs rename to src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/DiagnosticTransactionScope.netcore.cs index f4915e6903..038cac6a19 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlClientDiagnosticListenerExtensions.netcore.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/DiagnosticTransactionScope.netcore.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -8,74 +8,9 @@ using System.Data; using System.Runtime.CompilerServices; + namespace Microsoft.Data.SqlClient { - internal ref struct DiagnosticScope //: IDisposable //ref structs cannot implement interfaces but the compiler will use pattern matching - { - private const int CommandOperation = 1; - private const int ConnectionOpenOperation = 2; - - 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 Exception _exception; - - private DiagnosticScope(SqlDiagnosticListener diagnostics, int operation, Guid operationsId, string operationName, object context1, object context2) - { - _diagnostics = diagnostics; - _operation = operation; - _operationId = operationsId; - _operationName = operationName; - _context1 = context1; - _context2 = context2; - _exception = null; - } - - public void Dispose() - { - switch (_operation) - { - case CommandOperation: - if (_exception != null) - { - _diagnostics.WriteCommandError(_operationId, (SqlCommand)_context1, (SqlTransaction)_context2, _exception, _operationName); - } - else - { - _diagnostics.WriteCommandAfter(_operationId, (SqlCommand)_context1, (SqlTransaction)_context2, _operationName); - } - break; - - case ConnectionOpenOperation: - if (_exception != null) - { - _diagnostics.WriteConnectionOpenError(_operationId, (SqlConnection)_context1, _exception, _operationName); - } - else - { - _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 - } - } - - 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); - } - } - internal ref struct DiagnosticTransactionScope //: IDisposable //ref structs cannot implement interfaces but the compiler will use pattern matching { public const int TransactionCommit = 1; From 03b245913130219f0ffa6b3775250e7e5ca2b612 Mon Sep 17 00:00:00 2001 From: Ben Russell Date: Wed, 12 Mar 2025 17:06:10 -0500 Subject: [PATCH 6/6] Move remaining files to diagnostics namespace --- .../netcore/src/Microsoft/Data/SqlClient/SqlTransaction.cs | 1 + .../Data/SqlClient/Diagnostics/DiagnosticScope.netcore.cs | 2 +- .../Diagnostics/DiagnosticTransactionScope.netcore.cs | 3 +-- .../SqlClient/Diagnostics/SqlDiagnosticListener.netcore.cs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlTransaction.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlTransaction.cs index 59a8d19faa..89e9919f77 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlTransaction.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlTransaction.cs @@ -6,6 +6,7 @@ using System.ComponentModel; using System.Data.Common; using Microsoft.Data.Common; +using Microsoft.Data.SqlClient.Diagnostics; namespace Microsoft.Data.SqlClient { diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/DiagnosticScope.netcore.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/DiagnosticScope.netcore.cs index b2097ea73c..b79bec88df 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/DiagnosticScope.netcore.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/DiagnosticScope.netcore.cs @@ -7,7 +7,7 @@ using System; using System.Runtime.CompilerServices; -namespace Microsoft.Data.SqlClient +namespace Microsoft.Data.SqlClient.Diagnostics { internal ref struct DiagnosticScope //: IDisposable //ref structs cannot implement interfaces but the compiler will use pattern matching { diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/DiagnosticTransactionScope.netcore.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/DiagnosticTransactionScope.netcore.cs index 038cac6a19..e01ac1a817 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/DiagnosticTransactionScope.netcore.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/DiagnosticTransactionScope.netcore.cs @@ -8,8 +8,7 @@ using System.Data; using System.Runtime.CompilerServices; - -namespace Microsoft.Data.SqlClient +namespace Microsoft.Data.SqlClient.Diagnostics { internal ref struct DiagnosticTransactionScope //: IDisposable //ref structs cannot implement interfaces but the compiler will use pattern matching { diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlDiagnosticListener.netcore.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlDiagnosticListener.netcore.cs index c0c3a7f0f0..50f2c21b27 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlDiagnosticListener.netcore.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Diagnostics/SqlDiagnosticListener.netcore.cs @@ -12,7 +12,7 @@ using System.Runtime.Loader; using Microsoft.Data.SqlClient.Diagnostics; -namespace Microsoft.Data.SqlClient +namespace Microsoft.Data.SqlClient.Diagnostics { internal sealed class SqlDiagnosticListener : DiagnosticListener {