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 f17e61ae94..d2a5e111e3 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj @@ -322,6 +322,12 @@ Microsoft\Data\SqlClient\Server\SmiTypedGetterSetter.cs + + Microsoft\Data\SqlClient\Server\SmiEventSink.cs + + + Microsoft\Data\SqlClient\Server\SmiEventSink_Default.Common.cs + Microsoft\Data\SqlClient\Reliability\SqlRetryingEventArgs.cs @@ -455,8 +461,6 @@ - - diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/Server/SmiEventSink.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/Server/SmiEventSink.cs deleted file mode 100644 index 04ae3bedc5..0000000000 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/Server/SmiEventSink.cs +++ /dev/null @@ -1,25 +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. - -namespace Microsoft.Data.SqlClient.Server -{ - // SqlEventSink is implemented by calling code. In all methods that accept - // a SqlEventSink directly the sink must be able to handle multiple callbacks - // without control returning from the original call. - - // Methods that do not accept SmiEventSync are (generally) ProcessEvent on - // the SmiEventStream methods returning a SmiEventStream and methods that - // are certain to never call to the server (most will, for in-proc back end). - - // Methods are commented with their corresponding TDS token - - // NOTE: Throwing from these methods will not usually produce the desired - // effect -- the managed to native boundary will eat any exceptions, - // and will cause a simple "Something bad happened" exception to be - // thrown in the native to managed boundary... - internal abstract class SmiEventSink - { - } -} - diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj index 124164a053..d1b0a98015 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj @@ -228,6 +228,15 @@ Microsoft\Data\SqlClient\ColumnEncryptionKeyInfo.cs + + Microsoft\Data\SqlClient\Server\SmiEventSink.cs + + + Microsoft\Data\SqlClient\Server\SmiEventSink_Default.Common.cs + + + Microsoft\Data\SqlClient\Server\SmiEventSink_Default.netfx.cs + Microsoft\Data\SqlClient\OnChangedEventHandler.cs @@ -558,8 +567,6 @@ - - diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/Server/SmiEventSink.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Server/SmiEventSink.cs similarity index 83% rename from src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/Server/SmiEventSink.cs rename to src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Server/SmiEventSink.cs index 1c672da82c..a7de4b1947 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/Server/SmiEventSink.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Server/SmiEventSink.cs @@ -4,25 +4,25 @@ namespace Microsoft.Data.SqlClient.Server { - - // SqlEventSink is implemented by calling code. In all methods that accept - // a SqlEventSink directly the sink must be able to handle multiple callbacks - // without control returning from the original call. - - // Methods that do not accept SmiEventSync are (generally) ProcessEvent on - // the SmiEventStream methods returning a SmiEventStream and methods that - // are certain to never call to the server (most will, for in-proc back end). - - // Methods are commented with their corresponding TDS token - - // NOTE: Throwing from these methods will not usually produce the desired - // effect -- the managed to native boundary will eat any exceptions, - // and will cause a simple "Something bad happened" exception to be - // thrown in the native to managed boundary... + /// + /// SqlEventSink is implemented by calling code. In all methods that accept + /// a SqlEventSink directly the sink must be able to handle multiple callbacks + /// without control returning from the original call. + /// + /// Methods that do not accept SmiEventSync are (generally) ProcessEvent on + /// the SmiEventStream methods returning a SmiEventStream and methods that + /// are certain to never call to the server (most will, for in-proc back end). + /// + /// Methods are commented with their corresponding TDS token + /// + /// NOTE: Throwing from these methods will not usually produce the desired + /// effect -- the managed to native boundary will eat any exceptions, + /// and will cause a simple "Something bad happened" exception to be + /// thrown in the native to managed boundary... + /// internal abstract class SmiEventSink { - - #region Active methods +#if NETFRAMEWORK // Called at end of stream whether errors or no internal abstract void BatchCompleted(); @@ -80,10 +80,9 @@ internal virtual void RowAvailable(SmiTypedGetterSetter rowData) // Called when a transaction is started (ENVCHANGE token) internal abstract void TransactionStarted(long transactionId); - #endregion - #region OBSOLETE METHODS - #region OBSOLETED as of V200 but active in previous version +#region OBSOLETE METHODS +#region OBSOLETED as of V200 but active in previous version // Called zero or one time when output parameters are available (errors could prevent event from occuring) internal virtual void ParametersAvailable(SmiParameterMetaData[] metaData, ITypedGettersV3 paramValues) { @@ -108,9 +107,9 @@ internal virtual void RowAvailable(ITypedGettersV3 rowData) Microsoft.Data.Common.ADP.InternalError(Microsoft.Data.Common.ADP.InternalErrorCode.UnimplementedSMIMethod); } - #endregion +#endregion - #region OBSOLETED and never shipped (without ObsoleteAttribute) +#region OBSOLETED and never shipped (without ObsoleteAttribute) // Called when a new row arrives (ROW token) internal virtual void RowAvailable(ITypedGetters rowData) { @@ -123,8 +122,9 @@ internal virtual void RowAvailable(ITypedGetters rowData) Microsoft.Data.Common.ADP.InternalError(Microsoft.Data.Common.ADP.InternalErrorCode.UnimplementedSMIMethod); } - #endregion - #endregion +#endregion +#endregion + +#endif } } - diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/Server/SmiEventSink_Default.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Server/SmiEventSink_Default.cs similarity index 64% rename from src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/Server/SmiEventSink_Default.cs rename to src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Server/SmiEventSink_Default.cs index 9b94b49c13..39f87beaae 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/Server/SmiEventSink_Default.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Server/SmiEventSink_Default.cs @@ -6,16 +6,29 @@ namespace Microsoft.Data.SqlClient.Server { - internal class SmiEventSink_Default : SmiEventSink + internal partial class SmiEventSink_Default : SmiEventSink { private SqlErrorCollection _errors; private SqlErrorCollection _warnings; + internal virtual string ServerVersion => null; + + internal SmiEventSink_Default() + { + } internal bool HasMessages { get { +#if NETFRAMEWORK + SmiEventSink_Default parent = (SmiEventSink_Default)_parent; + if (null != parent) + { + return parent.HasMessages; + } + else +#endif { bool result = (null != _errors || null != _warnings); return result; @@ -23,31 +36,43 @@ internal bool HasMessages } } - virtual internal string ServerVersion - { - get - { - return null; - } - } - - - protected virtual void DispatchMessages() + protected virtual void DispatchMessages( +#if NETFRAMEWORK + bool ignoreNonFatalMessages +#endif + ) { // virtual because we want a default implementation in the cases // where we don't have a connection to process stuff, but we want to // provide the connection the ability to fire info messages when it // hooks up. +#if NETFRAMEWORK + SmiEventSink_Default parent = (SmiEventSink_Default)_parent; + if (null != parent) { - SqlException errors = ProcessMessages(true); // ignore warnings, because there's no place to send them... + parent.DispatchMessages(ignoreNonFatalMessages); + } + else +#endif + { + SqlException errors = ProcessMessages(true +#if NETFRAMEWORK + , ignoreNonFatalMessages +#endif + ); // ignore warnings, because there's no place to send them... if (null != errors) { throw errors; } } + } - protected SqlException ProcessMessages(bool ignoreWarnings) + protected SqlException ProcessMessages(bool ignoreWarnings +#if NETFRAMEWORK + , bool ignoreNonFatalMessages +#endif + ) { SqlException result = null; SqlErrorCollection temp = null; // temp variable to store that which is being thrown - so that local copies can be deleted @@ -55,7 +80,24 @@ protected SqlException ProcessMessages(bool ignoreWarnings) if (null != _errors) { Debug.Assert(0 != _errors.Count, "empty error collection?"); // must be something in the collection - +#if NETFRAMEWORK + if (ignoreNonFatalMessages) + { + temp = new SqlErrorCollection(); + foreach (SqlError error in _errors) + { + if (error.Class >= TdsEnums.FATAL_ERROR_CLASS) + { + temp.Add(error); + } + } + if (temp.Count <= 0) + { + temp = null; + } + } + else +#endif { if (null != _warnings) { @@ -92,20 +134,16 @@ protected SqlException ProcessMessages(bool ignoreWarnings) return result; } - internal void ProcessMessagesAndThrow() { +#if NETFRAMEWORK + ProcessMessagesAndThrow(false); +#else if (HasMessages) { DispatchMessages(); } - } - - - - internal SmiEventSink_Default() - { +#endif } } } - diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/Server/SmiEventSink_Default.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Server/SmiEventSink_Default.netfx.cs similarity index 64% rename from src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/Server/SmiEventSink_Default.cs rename to src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Server/SmiEventSink_Default.netfx.cs index 663d042127..75d61f09ff 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/Server/SmiEventSink_Default.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Server/SmiEventSink_Default.netfx.cs @@ -6,14 +6,9 @@ namespace Microsoft.Data.SqlClient.Server { - internal class SmiEventSink_Default : SmiEventSink + internal partial class SmiEventSink_Default : SmiEventSink { - private SmiEventSink _parent; // next level up, which we'll defer to if we don't need to handle the event. - - private SqlErrorCollection _errors; - private SqlErrorCollection _warnings; - private SqlErrorCollection Errors { get @@ -27,41 +22,10 @@ private SqlErrorCollection Errors } } - internal bool HasMessages - { - get - { - SmiEventSink_Default parent = (SmiEventSink_Default)_parent; - if (null != parent) - { - return parent.HasMessages; - } - else - { - bool result = (null != _errors || null != _warnings); - return result; - } - } - } - - virtual internal string ServerVersion - { - get - { - return null; - } - } - internal SmiEventSink Parent { - get - { - return _parent; - } - set - { - _parent = value; - } + get => _parent; + set => _parent = value; } private SqlErrorCollection Warnings @@ -77,86 +41,12 @@ private SqlErrorCollection Warnings } } - protected virtual void DispatchMessages(bool ignoreNonFatalMessages) - { - // virtual because we want a default implementation in the cases - // where we don't have a connection to process stuff, but we want to - // provide the connection the ability to fire info messages when it - // hooks up. - SmiEventSink_Default parent = (SmiEventSink_Default)_parent; - if (null != parent) - { - parent.DispatchMessages(ignoreNonFatalMessages); - } - else - { - SqlException errors = ProcessMessages(true, ignoreNonFatalMessages); // ignore warnings, because there's no place to send them... - if (null != errors) - { - throw errors; - } - } - } - - protected SqlException ProcessMessages(bool ignoreWarnings, bool ignoreNonFatalMessages) + internal void ProcessMessagesAndThrow(bool ignoreNonFatalMessages) { - SqlException result = null; - SqlErrorCollection temp = null; // temp variable to store that which is being thrown - so that local copies can be deleted - - if (null != _errors) - { - Debug.Assert(0 != _errors.Count, "empty error collection?"); // must be something in the collection - - if (ignoreNonFatalMessages) - { - temp = new SqlErrorCollection(); - foreach (SqlError error in _errors) - { - if (error.Class >= TdsEnums.FATAL_ERROR_CLASS) - { - temp.Add(error); - } - } - if (temp.Count <= 0) - { - temp = null; - } - } - else - { - if (null != _warnings) - { - // When we throw an exception we place all the warnings that - // occurred at the end of the collection - after all the errors. - // That way the user can see all the errors AND warnings that - // occurred for the exception. - foreach (SqlError warning in _warnings) - { - _errors.Add(warning); - } - } - temp = _errors; - } - - _errors = null; - _warnings = null; - } - else - { - Debug.Assert(null == _warnings || 0 != _warnings.Count, "empty warning collection?");// must be something in the collection - - if (!ignoreWarnings) - { - temp = _warnings; - } - _warnings = null; - } - - if (null != temp) + if (HasMessages) { - result = SqlException.CreateException(temp, ServerVersion); + DispatchMessages(ignoreNonFatalMessages); } - return result; } internal void CleanMessages() @@ -173,19 +63,6 @@ internal void CleanMessages() } } - internal void ProcessMessagesAndThrow() - { - ProcessMessagesAndThrow(false); - } - - internal void ProcessMessagesAndThrow(bool ignoreNonFatalMessages) - { - if (HasMessages) - { - DispatchMessages(ignoreNonFatalMessages); - } - } - internal enum UnexpectedEventType { BatchCompleted, @@ -206,25 +83,19 @@ internal enum UnexpectedEventType TransactionStarted, } - - internal SmiEventSink_Default() - { - } - internal SmiEventSink_Default(SmiEventSink parent) { _parent = parent; } - - // NOTE: See the note in SmiEventSink about throwing from these methods; - // We're throwing here because we don't want to miss something, but - // you'll need to turn on Bid tracing to figure out what it is that - // was thrown, because they will be eaten by the server and replaced - // with a different exception. - - + // + //NOTE: See the note in SmiEventSink about throwing from these methods; + // We're throwing here because we don't want to miss something, but + //you'll need to turn on Bid tracing to figure out what it is that + //was thrown, because they will be eaten by the server and replaced + //with a different exception. // Called at end of stream + // internal override void BatchCompleted() { if (null == _parent)