Imported Upstream version 5.8.0.22

Former-commit-id: df344e34b07851d296efb3e6604c8db42b6f7aa3
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2017-10-19 20:04:20 +00:00
parent 5f4a27cc8a
commit 7d05485754
5020 changed files with 114082 additions and 186061 deletions

View File

@@ -3,7 +3,7 @@
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
<ItemGroup>
<ProjectReference Include="..\ref\System.Data.SqlClient.csproj">
<SupportedFramework>net461;netcoreapp2.0;$(AllXamarinFrameworks)</SupportedFramework>
<SupportedFramework>net461;netcoreapp2.0;$(UAPvNextTFM);$(AllXamarinFrameworks)</SupportedFramework>
</ProjectReference>
<ProjectReference Include="..\src\System.Data.SqlClient.csproj" />
<HarvestIncludePaths Include="ref/net451;lib/net451;runtimes/win/lib/net451" />

View File

@@ -282,6 +282,7 @@ namespace System.Data.SqlClient
internal SqlClientFactory() { }
public static readonly System.Data.SqlClient.SqlClientFactory Instance;
public override System.Data.Common.DbCommand CreateCommand() { throw null; }
public override System.Data.Common.DbCommandBuilder CreateCommandBuilder() { throw null; }
public override System.Data.Common.DbConnection CreateConnection() { throw null; }
public override System.Data.Common.DbConnectionStringBuilder CreateConnectionStringBuilder() { throw null; }
public override System.Data.Common.DbDataAdapter CreateDataAdapter() { throw null; }
@@ -344,6 +345,33 @@ namespace System.Data.SqlClient
public override void Prepare() { }
public System.Data.Sql.SqlNotificationRequest Notification { get { throw null; } set { } }
}
public sealed class SqlCommandBuilder : System.Data.Common.DbCommandBuilder
{
public SqlCommandBuilder() { }
public SqlCommandBuilder(SqlDataAdapter adapter) { }
public override System.Data.Common.CatalogLocation CatalogLocation { get { throw null; } set { } }
public override string CatalogSeparator { get { throw null; } set { } }
new public SqlDataAdapter DataAdapter { get { throw null; } set { } }
public override string QuotePrefix { get { throw null; } set { } }
public override string QuoteSuffix { get { throw null; } set { } }
public override string SchemaSeparator { get { throw null; } set { } }
new public SqlCommand GetInsertCommand() { throw null; }
new public SqlCommand GetInsertCommand(bool useColumnsForParameterNames) { throw null; }
new public SqlCommand GetUpdateCommand() { throw null; }
new public SqlCommand GetUpdateCommand(bool useColumnsForParameterNames) { throw null; }
new public SqlCommand GetDeleteCommand() { throw null; }
new public SqlCommand GetDeleteCommand(bool useColumnsForParameterNames) { throw null; }
protected override void ApplyParameterInfo(System.Data.Common.DbParameter parameter, System.Data.DataRow datarow, System.Data.StatementType statementType, bool whereClause) { }
protected override string GetParameterName(int parameterOrdinal) { throw null; }
protected override string GetParameterName(string parameterName) { throw null; }
protected override string GetParameterPlaceholder(int parameterOrdinal) { throw null; }
public static void DeriveParameters(SqlCommand command) { }
protected override DataTable GetSchemaTable(System.Data.Common.DbCommand srcCommand) { throw null; }
protected override System.Data.Common.DbCommand InitializeCommand(System.Data.Common.DbCommand command) { throw null; }
public override string QuoteIdentifier(string unquotedIdentifier) { throw null; }
protected override void SetRowUpdatingHandler(System.Data.Common.DbDataAdapter adapter) { }
public override string UnquoteIdentifier(string quotedIdentifier) { throw null; }
}
public sealed partial class SqlConnection : System.Data.Common.DbConnection, System.ICloneable
{
public SqlConnection() { }
@@ -405,6 +433,7 @@ namespace System.Data.SqlClient
public bool PersistSecurityInfo { get { throw null; } set { } }
public bool Pooling { get { throw null; } set { } }
public bool Replication { get { throw null; } set { } }
public string TransactionBinding { get { throw null; } set { } }
public bool TrustServerCertificate { get { throw null; } set { } }
public string TypeSystemVersion { get { throw null; } set { } }
public string UserID { get { throw null; } set { } }

View File

@@ -4,12 +4,15 @@
<PropertyGroup>
<ProjectGuid>{D58E8D2B-3331-4660-8DFB-512D66F8EC63}</ProjectGuid>
<IsPartialFacadeAssembly Condition="'$(TargetGroup)' == 'netfx'">true</IsPartialFacadeAssembly>
<!-- UAPvNext is not yet mapped to netstandard2.0, manually duplicate this ref -->
<PackageTargetFramework Condition="'$(TargetGroup)' == 'netstandard'">netstandard2.0;$(UAPvNextTFM)</PackageTargetFramework>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netfx-Debug|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netfx-Release|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netstandard-Debug|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netstandard-Release|AnyCPU'" />
<ItemGroup>
<SuppressPackageTargetFrameworkCompatibility Include="$(UAPvNextTFM)" />
<Compile Include="System.Data.SqlClient.cs" />
<Compile Include="System.Data.SqlClient.Manual.cs" />
</ItemGroup>

View File

@@ -2,6 +2,7 @@
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<BuildConfigurations>
uap-Windows_NT;
netstandard-Unix;
netstandard-Windows_NT;
netstandard1.2;

View File

@@ -0,0 +1,24 @@
// 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.
using System.Data.SqlClient.SNI;
namespace System.Data.SqlClient
{
internal static partial class SNINativeMethodWrapper
{
internal enum SniSpecialErrors : uint
{
LocalDBErrorCode = SNICommon.LocalDBErrorCode,
// multi-subnet-failover specific error codes
MultiSubnetFailoverWithMoreThan64IPs = SNICommon.MultiSubnetFailoverWithMoreThan64IPs,
MultiSubnetFailoverWithInstanceSpecified = SNICommon.MultiSubnetFailoverWithInstanceSpecified,
MultiSubnetFailoverWithNonTcpProtocol = SNICommon.MultiSubnetFailoverWithNonTcpProtocol,
// max error code value
MaxErrorValue = SNICommon.MaxErrorValue
}
}
}

View File

@@ -4,28 +4,9 @@
using System.Data.SqlClient.SNI;
namespace System.Data.SqlClient
{
internal static class SNINativeMethodWrapper
{
internal enum SniSpecialErrors : uint
{
LocalDBErrorCode = SNICommon.LocalDBErrorCode,
// multi-subnet-failover specific error codes
MultiSubnetFailoverWithMoreThan64IPs = SNICommon.MultiSubnetFailoverWithMoreThan64IPs,
MultiSubnetFailoverWithInstanceSpecified = SNICommon.MultiSubnetFailoverWithInstanceSpecified,
MultiSubnetFailoverWithNonTcpProtocol = SNICommon.MultiSubnetFailoverWithNonTcpProtocol,
// max error code value
MaxErrorValue = SNICommon.MaxErrorValue
}
}
}
namespace System.Data
{
internal static class SafeNativeMethods
internal static partial class SafeNativeMethods
{
internal static IntPtr GetProcAddress(IntPtr HModule, string funcName)
{

View File

@@ -8,7 +8,7 @@ using System.Runtime.InteropServices;
namespace System.Data.SqlClient
{
internal static class SNINativeMethodWrapper
internal static partial class SNINativeMethodWrapper
{
private const string SNI = "sni.dll";
@@ -178,18 +178,6 @@ namespace System.Data.SqlClient
internal uint lineNumber;
}
internal enum SniSpecialErrors : uint
{
LocalDBErrorCode = 50,
// multi-subnet-failover specific error codes
MultiSubnetFailoverWithMoreThan64IPs = 47,
MultiSubnetFailoverWithInstanceSpecified = 48,
MultiSubnetFailoverWithNonTcpProtocol = 49,
// max error code value
MaxErrorValue = 50157
}
#endregion
#region DLL Imports
@@ -414,7 +402,7 @@ namespace System.Data.SqlClient
namespace System.Data
{
internal static class SafeNativeMethods
internal static partial class SafeNativeMethods
{
[DllImport("kernel32.dll", CharSet = CharSet.Ansi, BestFitMapping = false, ThrowOnUnmappableChar = true, SetLastError = true)]
internal static extern IntPtr GetProcAddress(IntPtr HModule, [MarshalAs(UnmanagedType.LPStr), In] string funcName);

View File

@@ -901,20 +901,19 @@ namespace Microsoft.SqlServer.Server
}
return new SmiExtendedMetaData(
colDbType,
maxLength,
precision,
scale,
System.Globalization.CultureInfo.CurrentCulture.LCID,
SmiMetaData.GetDefaultForType(colDbType).CompareOptions,
null, // no support for UDTs from SchemaTable
false, // no support for multi-valued columns in a TVP yet
null, // no support for structured columns yet
null, // no support for structured columns yet
colName,
null,
null,
null);
colDbType,
maxLength,
precision,
scale,
System.Globalization.CultureInfo.CurrentCulture.LCID,
SmiMetaData.GetDefaultForType(colDbType).CompareOptions,
false, // no support for multi-valued columns in a TVP yet
null, // no support for structured columns yet
null, // no support for structured columns yet
colName,
null,
null,
null);
}
}
}

View File

@@ -1,4 +1,5 @@
<!-- Not a bug. sni.dll is a native component that ships as part of the package. -->
kernel32.dll!LoadLibraryExW
sni.dll!GetSniMaxComposedSpnLength
sni.dll!SNIAddProviderWrapper
sni.dll!SNICheckConnectionWrapper
@@ -25,3 +26,19 @@ sni.dll!SNIWaitForSSLHandshakeToCompleteWrapper
sni.dll!SNIWriteAsyncWrapper
sni.dll!SNIWriteSyncOverAsync
sni.dll!UnmanagedIsTokenRestricted
sspicli.dll!AcceptSecurityContext
sspicli.dll!AcquireCredentialsHandleW
sspicli.dll!ApplyControlToken
sspicli.dll!CompleteAuthToken
sspicli.dll!DecryptMessage
sspicli.dll!DeleteSecurityContext
sspicli.dll!EncryptMessage
sspicli.dll!EnumerateSecurityPackagesW
sspicli.dll!FreeContextBuffer
sspicli.dll!FreeCredentialsHandle
sspicli.dll!InitializeSecurityContextW
sspicli.dll!QueryContextAttributesW
sspicli.dll!QuerySecurityContextToken
sspicli.dll!SetContextAttributesW
sspicli.dll!SspiEncodeStringsAsAuthIdentity
sspicli.dll!SspiFreeAuthIdentity

View File

@@ -115,6 +115,12 @@
<data name="ADP_InvalidOffsetValue" xml:space="preserve">
<value>Invalid parameter Offset value '{0}'. The value must be greater than or equal to 0.</value>
</data>
<data name="ADP_TransactionPresent" xml:space="preserve">
<value>Connection currently has transaction enlisted. Finish current transaction and retry.</value>
</data>
<data name="ADP_LocalTransactionPresent" xml:space="preserve">
<value>Cannot enlist in the transaction because a local transaction is in progress on the connection. Finish local transaction and retry.</value>
</data>
<data name="ADP_NoConnectionString" xml:space="preserve">
<value>The ConnectionString property has not been initialized.</value>
</data>
@@ -130,6 +136,15 @@
<data name="ADP_NonPooledOpenTimeout" xml:space="preserve">
<value>Timeout attempting to open the connection. The time period elapsed prior to attempting to open the connection has been exceeded. This may have occurred because of too many simultaneous non-pooled connection attempts.</value>
</data>
<data name="ADP_SingleValuedProperty" xml:space="preserve">
<value>The only acceptable value for the property '{0}' is '{1}'.</value>
</data>
<data name="ADP_DoubleValuedProperty" xml:space="preserve">
<value>The acceptable values for the property '{0}' are '{1}' or '{2}'.</value>
</data>
<data name="ADP_InvalidPrefixSuffix" xml:space="preserve">
<value>Specified QuotePrefix and QuoteSuffix values do not match.</value>
</data>
<data name="Arg_ArrayPlusOffTooSmall" xml:space="preserve">
<value>Destination array is not long enough to copy all the items in the collection. Check array index and length.</value>
</data>
@@ -151,6 +166,12 @@
<data name="SQL_WrongType" xml:space="preserve">
<value>Expecting argument of type {1}, but received type {0}.</value>
</data>
<data name="ADP_DeriveParametersNotSupported" xml:space="preserve">
<value>{0} DeriveParameters only supports CommandType.StoredProcedure, not CommandType.{1}.</value>
</data>
<data name="ADP_NoStoredProcedureExists" xml:space="preserve">
<value>The stored procedure '{0}' doesn't exist.</value>
</data>
<data name="ADP_InvalidConnectionOptionValue" xml:space="preserve">
<value>Invalid value for key '{0}'.</value>
</data>
@@ -175,6 +196,12 @@
<data name="ADP_InvalidMultipartNameToManyParts" xml:space="preserve">
<value>{0} '{1}', the current limit of '{2}' is insufficient.</value>
</data>
<data name="SQL_SqlCommandCommandText" xml:space="preserve">
<value>SqlCommand.DeriveParameters failed because the SqlCommand.CommandText property value is an invalid multipart name</value>
</data>
<data name="SQL_BatchedUpdatesNotAvailableOnContextConnection" xml:space="preserve">
<value>Batching updates is not supported on the context connection.</value>
</data>
<data name="SQL_BulkCopyDestinationTableName" xml:space="preserve">
<value>SqlBulkCopy.WriteToServer failed because the SqlBulkCopy.DestinationTableName is an invalid multipart name</value>
</data>
@@ -400,6 +427,9 @@
<data name="SQL_KerberosTicketMissingError" xml:space="preserve">
<value>Cannot access Kerberos ticket. Ensure Kerberos has been initialized with 'kinit'.</value>
</data>
<data name="SQL_SqlServerBrowserNotAccessible" xml:space="preserve">
<value>Cannot connect to SQL Server Browser. Ensure SQL Server Browser has been started.</value>
</data>
<data name="SQL_InvalidSSPIPacketSize" xml:space="preserve">
<value>Invalid SSPI packet size.</value>
</data>
@@ -472,6 +502,9 @@
<data name="SQL_XmlReaderNotSupportOnColumnType" xml:space="preserve">
<value>Invalid attempt to GetXmlReader on column '{0}'. The GetXmlReader function can only be used on columns of type Xml.</value>
</data>
<data name="SqlDelegatedTransaction_PromotionFailed" xml:space="preserve">
<value>Failure while attempting to promote transaction.</value>
</data>
<data name="SQL_InvalidBufferSizeOrIndex" xml:space="preserve">
<value>Buffer offset '{1}' plus the bytes available '{0}' is greater than the length of the passed in buffer.</value>
</data>
@@ -529,6 +562,9 @@
<data name="SQL_BulkLoadPendingOperation" xml:space="preserve">
<value>Attempt to invoke bulk copy on an object that has a pending operation.</value>
</data>
<data name="SQL_CannotGetDTCAddress" xml:space="preserve">
<value>Unable to get the address of the distributed transaction coordinator for the server, from the server. Is DTC enabled on the server?</value>
</data>
<data name="SQL_ConnectionDoomed" xml:space="preserve">
<value>The requested operation cannot be completed because the connection has been broken.</value>
</data>
@@ -556,6 +592,9 @@
<data name="SQL_ExRoutingDestination" xml:space="preserve">
<value>Routing Destination:{0}</value>
</data>
<data name="SQL_UnsupportedSysTxVersion" xml:space="preserve">
<value>The currently loaded System.Transactions.dll does not support Global Transactions.</value>
</data>
<data name="SqlMisc_NullString" xml:space="preserve">
<value>Null</value>
</data>
@@ -646,6 +685,9 @@
<data name="ADP_OperationAbortedExceptionMessage" xml:space="preserve">
<value>Operation aborted due to an exception (see InnerException for details).</value>
</data>
<data name="ADP_TransactionCompletedButNotDisposed" xml:space="preserve">
<value>The transaction associated with the current connection has completed but has not been disposed. The transaction must be disposed before the connection can be used to execute SQL statements.</value>
</data>
<data name="SqlParameter_UnsupportedTVPOutputParameter" xml:space="preserve">
<value>ParameterDirection '{0}' specified for parameter '{1}' is not supported. Table-valued parameters only support ParameterDirection.Input.</value>
</data>
@@ -667,6 +709,12 @@
<data name="SQL_EnumeratedRecordFieldCountChanged" xml:space="preserve">
<value>Number of fields in record '{0}' does not match the number in the original record.</value>
</data>
<data name="GT_Disabled" xml:space="preserve">
<value>Global Transactions are not enabled for this Azure SQL Database. Please contact Azure SQL Database support for assistance.</value>
</data>
<data name="SQL_UnknownSysTxIsolationLevel" xml:space="preserve">
<value>Unrecognized System.Transactions.IsolationLevel enumeration value: {0}.</value>
</data>
<data name="SQLNotify_AlreadyHasCommand" xml:space="preserve">
<value>This SqlCommand object is already associated with another SqlDependency object.</value>
</data>
@@ -1073,7 +1121,7 @@
<value>'{0}' is not a supported handle type.</value>
</data>
<data name="LocalDBNotSupported" xml:space="preserve">
<value>LocalDB is not supported on this Platform.</value>
<value>LocalDB is not supported on this platform.</value>
</data>
<data name="PlatformNotSupported_DataSqlClient" xml:space="preserve">
<value>System.Data.SqlClient is not supported on this platform.</value>
@@ -1085,28 +1133,28 @@
<value>The size of column '{0}' is not supported. The size is {1}.</value>
</data>
<data name="MDF_InvalidXmlInvalidValue" xml:space="preserve">
<value>The metadata XML is invalid. The {1} column of the {0} collection must contain a non-empty string.</value>
<value>The metadata XML is invalid. The {1} column of the {0} collection must contain a non-empty string.</value>
</data>
<data name="MDF_CollectionNameISNotUnique" xml:space="preserve">
<value>There are multiple collections named '{0}'.</value>
<value>There are multiple collections named '{0}'.</value>
</data>
<data name="MDF_InvalidXmlMissingColumn" xml:space="preserve">
<value>The metadata XML is invalid. The {0} collection must contain a {1} column and it must be a string column.</value>
<value>The metadata XML is invalid. The {0} collection must contain a {1} column and it must be a string column.</value>
</data>
<data name="MDF_InvalidXml" xml:space="preserve">
<value>The metadata XML is invalid.</value>
<value>The metadata XML is invalid.</value>
</data>
<data name="MDF_NoColumns" xml:space="preserve">
<value>The schema table contains no columns.</value>
<value>The schema table contains no columns.</value>
</data>
<data name="MDF_QueryFailed" xml:space="preserve">
<value>Unable to build the '{0}' collection because execution of the SQL query failed. See the inner exception for details.</value>
<value>Unable to build the '{0}' collection because execution of the SQL query failed. See the inner exception for details.</value>
</data>
<data name="MDF_TooManyRestrictions" xml:space="preserve">
<value>More restrictions were provided than the requested schema ('{0}') supports.</value>
<value>More restrictions were provided than the requested schema ('{0}') supports.</value>
</data>
<data name="MDF_DataTableDoesNotExist" xml:space="preserve">
<value>The collection '{0}' is missing from the metadata XML.</value>
<value>The collection '{0}' is missing from the metadata XML.</value>
</data>
<data name="MDF_UndefinedCollection" xml:space="preserve">
<value>The requested collection ({0}) is not defined.</value>
@@ -1135,4 +1183,4 @@
<data name="AmbientTransactionsNotSupported" xml:space="preserve">
<value>Enlisting in Ambient transactions is not supported.</value>
</data>
</root>
</root>

View File

@@ -5,8 +5,6 @@
<ProjectGuid>{D4550556-4745-457F-BA8F-3EBF3836D6B4}</ProjectGuid>
<AssemblyName>System.Data.SqlClient</AssemblyName>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<!-- Although we have a NS configuration, we know we use API that's not currently whitelisted: just validate against OneCore -->
<UWPCompatible>false</UWPCompatible>
<IsPartialFacadeAssembly Condition="'$(TargetGroup)' == 'netfx'">true</IsPartialFacadeAssembly>
<GeneratePlatformNotSupportedAssemblyMessage Condition="'$(OSGroup)' == 'AnyOS'">SR.PlatformNotSupported_DataSqlClient</GeneratePlatformNotSupportedAssemblyMessage>
<AssemblyVersion Condition="'$(TargetGroup)' == 'netstandard1.2'">4.0.0.0</AssemblyVersion>
@@ -14,6 +12,8 @@
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netfx-Windows_NT-Debug|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netfx-Windows_NT-Release|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'uap-Windows_NT-Debug|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'uap-Windows_NT-Release|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netstandard-Debug|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netstandard-Release|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netstandard-Unix-Debug|AnyCPU'" />
@@ -24,7 +24,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netstandard1.2-Release|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netstandard1.3-Debug|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netstandard1.3-Release|AnyCPU'" />
<ItemGroup Condition="'$(TargetGroup)' == 'netstandard'">
<ItemGroup Condition="'$(TargetGroup)' == 'netstandard' OR '$(TargetGroup)' == 'uap' ">
<Compile Include="System.Data.SqlClient.TypeForwards.cs" />
</ItemGroup>
<ItemGroup Condition="'$(IsPartialFacadeAssembly)' != 'true' AND '$(OSGroup)' != 'AnyOS'">
@@ -56,7 +56,11 @@
<Link>System\Data\Common\AdapterUtil.cs</Link>
</Compile>
<Compile Include="System\Data\Common\AdapterUtil.SqlClient.cs" />
<Compile Include="System\Data\Common\SR.cs" />
<Compile Include="System\Data\Common\DbConnectionOptions.cs" />
<Compile Include="$(CommonPath)\System\Data\Common\DbConnectionOptions.Common.cs">
<Link>System\Data\Common\DbConnectionOptions.Common.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\System\Data\Common\DbConnectionPoolKey.cs">
<Link>System\Data\Common\DbConnectionPoolKey.cs</Link>
</Compile>
@@ -103,6 +107,8 @@
<Compile Include="System\Data\SqlClient\SqlClientFactory.cs" />
<Compile Include="System\Data\SqlClient\SqlClientMetaDataCollectionNames.cs" />
<Compile Include="System\Data\SqlClient\SqlCommand.cs" />
<Compile Include="System\Data\SqlClient\SqlCommandBuilder.cs" />
<Compile Include="System\Data\SqlClient\SqlCommandSet.cs" />
<Compile Include="System\Data\SqlClient\SqlConnection.cs" />
<Compile Include="System\Data\SqlClient\SqlConnectionFactory.cs" />
<Compile Include="System\Data\SqlClient\SqlConnectionHelper.cs" />
@@ -117,6 +123,7 @@
<Compile Include="System\Data\SqlClient\SqlDependency.cs" />
<Compile Include="System\Data\SqlClient\SqlDependencyListener.cs" />
<Compile Include="System\Data\SqlClient\SqlDependencyUtils.cs" />
<Compile Include="System\Data\SqlClient\SqlDelegatedTransaction.cs" />
<Compile Include="System\Data\SqlClient\SqlEnums.cs" />
<Compile Include="System\Data\SqlClient\SqlError.cs" />
<Compile Include="System\Data\SqlClient\SqlErrorCollection.cs" />
@@ -181,19 +188,34 @@
<Compile Include="System\Data\SqlClient\SNI\SspiClientContextStatus.cs" />
<Compile Include="System\Data\SqlClient\SNI\SSRP.cs" />
<Compile Include="System\Data\SqlClient\TdsParserStateObjectManaged.cs" />
<Compile Include="Interop\SNINativeMethodWrapper.Common.cs" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetsWindows)' == 'true' And '$(IsPartialFacadeAssembly)' != 'true' ">
<Compile Include="System\Data\ProviderBase\DbConnectionPoolIdentity.Windows.cs" />
<!-- Manage the SNI toggle for Windows netstandard and UWP -->
<ItemGroup Condition="'$(TargetGroup)' == 'netstandard' AND '$(TargetsWindows)' == 'true'">
<Compile Include="System\Data\SqlClient\TdsParserStateObjectFactory.Windows.cs" />
</ItemGroup>
<ItemGroup Condition="'$(TargetGroup)' == 'uap'">
<Compile Include="System\Data\SqlClient\TdsParserStateObjectFactory.Managed.cs" />
<Compile Include="System\Data\SqlClient\LocalDBAPI.uap.cs" />
<Compile Include="System\Data\SqlClient\SNI\LocalDB.uap.cs" />
<Compile Include="System\Data\ProviderBase\DbConnectionPoolIdentity.Unix.cs" />
<Compile Include="System\Data\SqlClient\TdsParser.Unix.cs" />
</ItemGroup>
<!-- Assets needed on Windows but should be avoided on UAP to avoid sni.dll -->
<ItemGroup Condition=" '$(TargetsWindows)' == 'true' And '$(IsPartialFacadeAssembly)' != 'true' and '$(TargetGroup)' != 'uap' ">
<Compile Include="System\Data\SqlClient\TdsParserStateObjectNative.cs" />
<Compile Include="Interop\SNINativeMethodWrapper.Windows.cs" />
<Compile Include="System\Data\SqlClient\TdsParserSafeHandles.cs" />
<Compile Include="System\Data\SqlClient\TdsParserStateObjectNative.cs" />
<Compile Include="System\Data\SqlClient\TdsParserStateObjectFactory.Windows.cs" />
<Compile Include="System\Data\SqlClient\TdsParser.Windows.cs" />
<Compile Include="System\Data\SqlClient\LocalDBAPI.Windows.cs" />
<Compile Include="System\Data\SqlClient\SNI\LocalDB.Windows.cs" />
<Compile Include="System\Data\ProviderBase\DbConnectionPoolIdentity.Windows.cs" />
<Compile Include="System\Data\SqlClient\TdsParser.Windows.cs" />
<Compile Include="$(CommonPath)\Interop\Windows\kernel32\Interop.LoadLibraryEx.cs">
<Link>Common\Interop\Windows\kernel32\Interop.LoadLibraryEx.cs</Link>
</Compile>
</ItemGroup>
<ItemGroup Condition=" '$(TargetsWindows)' == 'true' And '$(IsPartialFacadeAssembly)' != 'true'">
<Compile Include="System\Data\SqlClient\LocalDBAPI.Common.cs" />
<Compile Include="$(CommonPath)\Interop\Windows\kernel32\Interop.FreeLibrary.cs">
<Link>Common\Interop\Windows\kernel32\Interop.FreeLibrary.cs</Link>
</Compile>
@@ -366,12 +388,12 @@
<Compile Include="$(CommonPath)\System\Net\ContextFlagsAdapterPal.Unix.cs">
<Link>Common\System\Net\ContextFlagsAdapterPal.Unix.cs</Link>
</Compile>
<Compile Include="System\Data\SqlClient\TdsParserStateObjectFactory.Unix.cs" />
<Compile Include="System\Data\SqlClient\TdsParserStateObjectFactory.Managed.cs" />
<Compile Include="System\Data\SqlClient\TdsParser.Unix.cs" />
<Compile Include="System\Data\SqlClient\LocalDBAPI.Unix.cs" />
<Compile Include="System\Data\SqlClient\SNI\LocalDB.Unix.cs" />
</ItemGroup>
<ItemGroup Condition="'$(TargetsWindows)' == 'true' And '$(IsPartialFacadeAssembly)' != 'true' ">
<ItemGroup Condition="'$(TargetsWindows)' == 'true' And '$(IsPartialFacadeAssembly)' != 'true' and '$(TargetGroup)' != 'uap'">
<Reference Include="Microsoft.Win32.Registry" />
</ItemGroup>
<ItemGroup Condition="'$(IsPartialFacadeAssembly)' != 'true'">
@@ -387,6 +409,7 @@
<Reference Include="Microsoft.Win32.Primitives" />
<Reference Include="System.Collections" />
<Reference Include="System.Collections.Concurrent" />
<Reference Include="System.ComponentModel" />
<Reference Include="System.ComponentModel.Primitives" />
<Reference Include="System.ComponentModel.TypeConverter" />
<Reference Include="System.Diagnostics.Debug" />
@@ -414,6 +437,10 @@
<Reference Include="System.Net.NameResolution" />
<Reference Include="System.Diagnostics.Tracing" />
</ItemGroup>
<ItemGroup Condition="'$(OSGroup)' != 'AnyOS' AND '$(TargetGroup)' == 'uap'">
<Reference Include="System.Transactions.Local" />
<Reference Include="System.Collections.NonGeneric" />
</ItemGroup>
<ItemGroup Condition="'$(TargetGroup)' == 'netfx'">
<Reference Include="mscorlib" />
<Reference Include="System.Data" />

View File

@@ -51,7 +51,7 @@ namespace System.Data.Common
// Declare the ActivityId which will be stored in TLS. The Id is unique for each thread.
// The Sequence number will be incremented when each event happens.
// Correlation along threads is consistent with the current XEvent mechanism at server.
[ThreadStaticAttribute]
[ThreadStatic]
private static ActivityId t_tlsActivity;
/// <summary>

View File

@@ -9,22 +9,6 @@ using System.IO;
using System.Runtime.CompilerServices;
using System.Transactions;
namespace System
{
internal static partial class SR
{
internal static string GetString(string value)
{
return value;
}
internal static string GetString(string format, params object[] args)
{
return SR.Format(format, args);
}
}
}
namespace System.Data.Common
{
internal static partial class ADP
@@ -47,12 +31,6 @@ namespace System.Data.Common
}
}
internal static void TraceExceptionWithoutRethrow(Exception e)
{
Debug.Assert(ADP.IsCatchableExceptionType(e), "Invalid exception type, should have been re-thrown!");
TraceException("<comm.ADP.TraceException|ERR|CATCH> '%ls'\n", e);
}
//
// COM+ exceptions
//
@@ -334,12 +312,7 @@ namespace System.Data.Common
return InvalidOperation(SR.GetString(SR.ADP_NonSequentialColumnAccess, badCol.ToString(CultureInfo.InvariantCulture), currCol.ToString(CultureInfo.InvariantCulture)));
}
internal static bool CompareInsensitiveInvariant(string strvalue, string strconst)
{
return (0 == CultureInfo.InvariantCulture.CompareInfo.Compare(strvalue, strconst, CompareOptions.IgnoreCase));
}
static internal Exception InvalidXmlInvalidValue(string collectionName, string columnName)
internal static Exception InvalidXmlInvalidValue(string collectionName, string columnName)
{
return Argument(SR.GetString(SR.MDF_InvalidXmlInvalidValue, collectionName, columnName));
}
@@ -422,6 +395,14 @@ namespace System.Data.Common
{
return InvalidOperation(SR.GetString(SR.ADP_ConnectionAlreadyOpen, ADP.ConnectionStateMsg(state)));
}
internal static Exception TransactionPresent()
{
return InvalidOperation(SR.GetString(SR.ADP_TransactionPresent));
}
internal static Exception LocalTransactionPresent()
{
return InvalidOperation(SR.GetString(SR.ADP_LocalTransactionPresent));
}
internal static Exception OpenConnectionPropertySet(string property, ConnectionState state)
{
return InvalidOperation(SR.GetString(SR.ADP_OpenConnectionPropertySet, property, ADP.ConnectionStateMsg(state)));
@@ -489,11 +470,6 @@ namespace System.Data.Common
return Argument(SR.GetString(SR.ADP_UnknownDataType, dataType.FullName));
}
internal static bool IsEmptyArray(string[] array)
{
return (array == null || array.Length == 0);
}
internal static ArgumentException DbTypeNotSupported(DbType type, Type enumtype)
{
return Argument(SR.GetString(SR.ADP_DbTypeNotSupported, type.ToString(), enumtype.Name));
@@ -801,7 +777,7 @@ namespace System.Data.Common
return false;
}
static internal ArgumentOutOfRangeException InvalidDataRowVersion(DataRowVersion value)
internal static ArgumentOutOfRangeException InvalidDataRowVersion(DataRowVersion value)
{
#if DEBUG
switch (value)
@@ -816,5 +792,126 @@ namespace System.Data.Common
#endif
return InvalidEnumerationValue(typeof(DataRowVersion), (int)value);
}
internal static ArgumentException SingleValuedProperty(string propertyName, string value)
{
ArgumentException e = new ArgumentException(SR.GetString(SR.ADP_SingleValuedProperty, propertyName, value));
TraceExceptionAsReturnValue(e);
return e;
}
internal static ArgumentException DoubleValuedProperty(string propertyName, string value1, string value2)
{
ArgumentException e = new ArgumentException(SR.GetString(SR.ADP_DoubleValuedProperty, propertyName, value1, value2));
TraceExceptionAsReturnValue(e);
return e;
}
internal static ArgumentException InvalidPrefixSuffix()
{
ArgumentException e = new ArgumentException(SR.GetString(SR.ADP_InvalidPrefixSuffix));
TraceExceptionAsReturnValue(e);
return e;
}
// the return value is true if the string was quoted and false if it was not
// this allows the caller to determine if it is an error or not for the quotedString to not be quoted
internal static bool RemoveStringQuotes(string quotePrefix, string quoteSuffix, string quotedString, out string unquotedString)
{
int prefixLength = quotePrefix != null ? quotePrefix.Length : 0;
int suffixLength = quoteSuffix != null ? quoteSuffix.Length : 0;
if ((suffixLength + prefixLength) == 0)
{
unquotedString = quotedString;
return true;
}
if (quotedString == null)
{
unquotedString = quotedString;
return false;
}
int quotedStringLength = quotedString.Length;
// is the source string too short to be quoted
if (quotedStringLength < prefixLength + suffixLength)
{
unquotedString = quotedString;
return false;
}
// is the prefix present?
if (prefixLength > 0)
{
if (!quotedString.StartsWith(quotePrefix, StringComparison.Ordinal))
{
unquotedString = quotedString;
return false;
}
}
// is the suffix present?
if (suffixLength > 0)
{
if (!quotedString.EndsWith(quoteSuffix, StringComparison.Ordinal))
{
unquotedString = quotedString;
return false;
}
unquotedString = quotedString.Substring(prefixLength, quotedStringLength - (prefixLength + suffixLength)).Replace(quoteSuffix + quoteSuffix, quoteSuffix);
}
else
{
unquotedString = quotedString.Substring(prefixLength, quotedStringLength - prefixLength);
}
return true;
}
internal static ArgumentOutOfRangeException InvalidCommandBehavior(CommandBehavior value)
{
Debug.Assert((0 > (int)value) || ((int)value > 0x3F), "valid CommandType " + value.ToString());
return InvalidEnumerationValue(typeof(CommandBehavior), (int)value);
}
internal static void ValidateCommandBehavior(CommandBehavior value)
{
if (((int)value < 0) || (0x3F < (int)value))
{
throw InvalidCommandBehavior(value);
}
}
internal static ArgumentOutOfRangeException NotSupportedCommandBehavior(CommandBehavior value, string method)
{
return NotSupportedEnumerationValue(typeof(CommandBehavior), value.ToString(), method);
}
internal static ArgumentException BadParameterName(string parameterName)
{
ArgumentException e = new ArgumentException(SR.GetString(SR.ADP_BadParameterName, parameterName));
TraceExceptionAsReturnValue(e);
return e;
}
internal static Exception DeriveParametersNotSupported(IDbCommand value)
{
return DataAdapter(SR.GetString(SR.ADP_DeriveParametersNotSupported, value.GetType().Name, value.CommandType.ToString()));
}
internal static Exception NoStoredProcedureExists(string sproc)
{
return InvalidOperation(SR.GetString(SR.ADP_NoStoredProcedureExists, sproc));
}
//
// DbProviderException
//
internal static InvalidOperationException TransactionCompletedButNotDisposed()
{
return Provider(SR.GetString(SR.ADP_TransactionCompletedButNotDisposed));
}
}
}

View File

@@ -224,11 +224,10 @@ namespace System.Data.Common
}
}
internal static class DbConnectionStringDefaults
internal static partial class DbConnectionStringDefaults
{
// all
// internal const string NamedConnection = "";
// internal const string NamedConnection = "";
// SqlClient
internal const ApplicationIntent ApplicationIntent = System.Data.SqlClient.ApplicationIntent.ReadWrite;
@@ -263,11 +262,10 @@ namespace System.Data.Common
}
internal static class DbConnectionStringKeywords
internal static partial class DbConnectionStringKeywords
{
// all
// internal const string NamedConnection = "Named Connection";
// internal const string NamedConnection = "Named Connection";
// SqlClient
internal const string ApplicationIntent = "ApplicationIntent";

View File

@@ -0,0 +1,19 @@
// 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 System
{
internal static partial class SR
{
internal static string GetString(string value)
{
return value;
}
internal static string GetString(string format, params object[] args)
{
return SR.Format(format, args);
}
}
}

View File

@@ -9,6 +9,7 @@
using System.Data.Common;
using System.Diagnostics;
using System.Threading.Tasks;
using System.Transactions;
namespace System.Data.ProviderBase
@@ -20,7 +21,7 @@ namespace System.Data.ProviderBase
{
}
override public string ServerVersion
public override string ServerVersion
{
get
{
@@ -28,17 +29,17 @@ namespace System.Data.ProviderBase
}
}
override protected void Activate()
protected override void Activate(Transaction transaction)
{
throw ADP.ClosedConnectionError();
}
override public DbTransaction BeginTransaction(IsolationLevel il)
public override DbTransaction BeginTransaction(IsolationLevel il)
{
throw ADP.ClosedConnectionError();
}
override public void ChangeDatabase(string database)
public override void ChangeDatabase(string database)
{
throw ADP.ClosedConnectionError();
}
@@ -48,11 +49,15 @@ namespace System.Data.ProviderBase
// not much to do here...
}
override protected void Deactivate()
protected override void Deactivate()
{
throw ADP.ClosedConnectionError();
}
public override void EnlistTransaction(Transaction transaction)
{
throw ADP.ClosedConnectionError();
}
protected override DbReferenceCollection CreateReferenceCollection()
{

View File

@@ -20,7 +20,6 @@ namespace System.Data.ProviderBase
private readonly List<DbConnectionPool> _poolsToRelease;
private readonly List<DbConnectionPoolGroup> _poolGroupsToRelease;
private readonly Timer _pruningTimer;
private const int PruningDueTime = 4 * 60 * 1000; // 4 minutes
private const int PruningPeriod = 30 * 1000; // thirty seconds
@@ -219,13 +218,22 @@ namespace System.Data.ProviderBase
// If it is a new slot or a completed task, this continuation will start right away.
newTask = s_pendingOpenNonPooled[idx].ContinueWith((_) =>
{
var newConnection = CreateNonPooledConnection(owningConnection, poolGroup, userOptions);
if ((oldConnection != null) && (oldConnection.State == ConnectionState.Open))
Transactions.Transaction originalTransaction = ADP.GetCurrentTransaction();
try
{
oldConnection.PrepareForReplaceConnection();
oldConnection.Dispose();
ADP.SetCurrentTransaction(retry.Task.AsyncState as Transactions.Transaction);
var newConnection = CreateNonPooledConnection(owningConnection, poolGroup, userOptions);
if ((oldConnection != null) && (oldConnection.State == ConnectionState.Open))
{
oldConnection.PrepareForReplaceConnection();
oldConnection.Dispose();
}
return newConnection;
}
finally
{
ADP.SetCurrentTransaction(originalTransaction);
}
return newConnection;
}, cancellationTokenSource.Token, TaskContinuationOptions.LongRunning, TaskScheduler.Default);
// Place this new task in the slot so any future work will be queued behind it

View File

@@ -11,6 +11,7 @@ using System.Data.SqlClient;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using System.Transactions;
namespace System.Data.ProviderBase
@@ -32,9 +33,17 @@ namespace System.Data.ProviderBase
private bool _connectionIsDoomed; // true when the connection should no longer be used.
private bool _cannotBePooled; // true when the connection should no longer be pooled.
private bool _isInStasis;
private DateTime _createTime; // when the connection was created.
private Transaction _enlistedTransaction; // [usage must be thread-safe] the transaction that we're enlisted in, either manually or automatically
// _enlistedTransaction is a clone, so that transaction information can be queried even if the original transaction object is disposed.
// However, there are times when we need to know if the original transaction object was disposed, so we keep a reference to it here.
// This field should only be assigned a value at the same time _enlistedTransaction is updated.
// Also, this reference should not be disposed, since we aren't taking ownership of it.
private Transaction _enlistedTransactionOriginal;
#if DEBUG
private int _activateCount; // debug only counter to verify activate/deactivates are in sync.
@@ -69,6 +78,164 @@ namespace System.Data.ProviderBase
}
}
protected internal Transaction EnlistedTransaction
{
get
{
return _enlistedTransaction;
}
set
{
Transaction currentEnlistedTransaction = _enlistedTransaction;
if (((null == currentEnlistedTransaction) && (null != value))
|| ((null != currentEnlistedTransaction) && !currentEnlistedTransaction.Equals(value)))
{ // WebData 20000024
// Pay attention to the order here:
// 1) defect from any notifications
// 2) replace the transaction
// 3) re-enlist in notifications for the new transaction
// SQLBUDT #230558 we need to use a clone of the transaction
// when we store it, or we'll end up keeping it past the
// duration of the using block of the TransactionScope
Transaction valueClone = null;
Transaction previousTransactionClone = null;
try
{
if (null != value)
{
valueClone = value.Clone();
}
// NOTE: rather than take locks around several potential round-
// trips to the server, and/or virtual function calls, we simply
// presume that you aren't doing something illegal from multiple
// threads, and check once we get around to finalizing things
// inside a lock.
lock (this)
{
// NOTE: There is still a race condition here, when we are
// called from EnlistTransaction (which cannot re-enlist)
// instead of EnlistDistributedTransaction (which can),
// however this should have been handled by the outer
// connection which checks to ensure that it's OK. The
// only case where we have the race condition is multiple
// concurrent enlist requests to the same connection, which
// is a bit out of line with something we should have to
// support.
// enlisted transaction can be nullified in Dispose call without lock
previousTransactionClone = Interlocked.Exchange(ref _enlistedTransaction, valueClone);
_enlistedTransactionOriginal = value;
value = valueClone;
valueClone = null; // we've stored it, don't dispose it.
}
}
finally
{
// we really need to dispose our clones; they may have
// native resources and GC may not happen soon enough.
// VSDevDiv 479564: don't dispose if still holding reference in _enlistedTransaction
if (null != previousTransactionClone &&
!Object.ReferenceEquals(previousTransactionClone, _enlistedTransaction))
{
previousTransactionClone.Dispose();
}
if (null != valueClone && !Object.ReferenceEquals(valueClone, _enlistedTransaction))
{
valueClone.Dispose();
}
}
// I don't believe that we need to lock to protect the actual
// enlistment in the transaction; it would only protect us
// against multiple concurrent calls to enlist, which really
// isn't supported anyway.
if (null != value)
{
TransactionOutcomeEnlist(value);
}
}
}
}
/// <summary>
/// Get boolean value that indicates whether the enlisted transaction has been disposed.
/// </summary>
/// <value>
/// True if there is an enlisted transaction, and it has been diposed.
/// False if there is an enlisted transaction that has not been disposed, or if the transaction reference is null.
/// </value>
/// <remarks>
/// This method must be called while holding a lock on the DbConnectionInternal instance.
/// </remarks>
protected bool EnlistedTransactionDisposed
{
get
{
// Until the Transaction.Disposed property is public it is necessary to access a member
// that throws if the object is disposed to determine if in fact the transaction is disposed.
try
{
bool disposed;
Transaction currentEnlistedTransactionOriginal = _enlistedTransactionOriginal;
if (currentEnlistedTransactionOriginal != null)
{
disposed = currentEnlistedTransactionOriginal.TransactionInformation == null;
}
else
{
// Don't expect to get here in the general case,
// Since this getter is called by CheckEnlistedTransactionBinding
// after checking for a non-null enlisted transaction (and it does so under lock).
disposed = false;
}
return disposed;
}
catch (ObjectDisposedException)
{
return true;
}
}
}
internal bool IsTxRootWaitingForTxEnd
{
get
{
return _isInStasis;
}
}
virtual protected bool UnbindOnTransactionCompletion
{
get
{
return true;
}
}
// Is this a connection that must be put in stasis (or is already in stasis) pending the end of it's transaction?
virtual protected internal bool IsNonPoolableTransactionRoot
{
get
{
return false; // if you want to have delegated transactions that are non-poolable, you better override this...
}
}
virtual internal bool IsTransactionRoot
{
get
{
return false; // if you want to have delegated transactions, you better override this...
}
}
protected internal bool IsConnectionDoomed
{
@@ -138,6 +305,13 @@ namespace System.Data.ProviderBase
}
}
virtual protected bool ReadyToPrepareTransaction
{
get
{
return true;
}
}
protected internal DbReferenceCollection ReferenceCollection
{
@@ -177,20 +351,14 @@ namespace System.Data.ProviderBase
}
}
abstract protected void Activate();
abstract protected void Activate(Transaction transaction);
internal void ActivateConnection()
internal void ActivateConnection(Transaction transaction)
{
// Internal method called from the connection pooler so we don't expose
// the Activate method publicly.
#if DEBUG
int activateCount = Interlocked.Increment(ref _activateCount);
Debug.Assert(1 == activateCount, "activated multiple times?");
#endif // DEBUG
Activate();
Activate(transaction);
}
internal void AddWeakReference(object value, int tag)
@@ -272,6 +440,8 @@ namespace System.Data.ProviderBase
DbConnectionPool connectionPool = Pool;
// Detach from enlisted transactions that are no longer active on close
DetachCurrentTransactionIfEnded();
// The singleton closed classes won't have owners and
// connection pools, and we won't want to put them back
@@ -296,7 +466,14 @@ namespace System.Data.ProviderBase
// certain.
_owningObject.Target = null;
Dispose();
if (IsTransactionRoot)
{
SetInStasis();
}
else
{
Dispose();
}
}
}
finally
@@ -344,7 +521,6 @@ namespace System.Data.ProviderBase
#if DEBUG
int activateCount = Interlocked.Decrement(ref _activateCount);
Debug.Assert(0 == activateCount, "activated multiple times?");
#endif // DEBUG
@@ -362,11 +538,71 @@ namespace System.Data.ProviderBase
Deactivate();
}
virtual internal void DelegatedTransactionEnded()
{
// Called by System.Transactions when the delegated transaction has
// completed. We need to make closed connections that are in stasis
// available again, or disposed closed/leaked non-pooled connections.
// IMPORTANT NOTE: You must have taken a lock on the object before
// you call this method to prevent race conditions with Clear and
// ReclaimEmancipatedObjects.
if (1 == _pooledCount)
{
// When _pooledCount is 1, it indicates a closed, pooled,
// connection so it is ready to put back into the pool for
// general use.
TerminateStasis(true);
Deactivate(); // call it one more time just in case
DbConnectionPool pool = Pool;
if (null == pool)
{
throw ADP.InternalError(ADP.InternalErrorCode.PooledObjectWithoutPool); // pooled connection does not have a pool
}
pool.PutObjectFromTransactedPool(this);
}
else if (-1 == _pooledCount && !_owningObject.IsAlive)
{
// When _pooledCount is -1 and the owning object no longer exists,
// it indicates a closed (or leaked), non-pooled connection so
// it is safe to dispose.
TerminateStasis(false);
Deactivate(); // call it one more time just in case
// it's a non-pooled connection, we need to dispose of it
// once and for all, or the server will have fits about us
// leaving connections open until the client-side GC kicks
// in.
Dispose();
}
// When _pooledCount is 0, the connection is a pooled connection
// that is either open (if the owning object is alive) or leaked (if
// the owning object is not alive) In either case, we can't muck
// with the connection here.
}
public virtual void Dispose()
{
_connectionPool = null;
_connectionIsDoomed = true;
_enlistedTransactionOriginal = null; // should not be disposed
// Dispose of the _enlistedTransaction since it is a clone
// of the original reference.
// VSDD 780271 - _enlistedTransaction can be changed by another thread (TX end event)
Transaction enlistedTransaction = Interlocked.Exchange(ref _enlistedTransaction, null);
if (enlistedTransaction != null)
{
enlistedTransaction.Dispose();
}
}
protected internal void DoNotPoolThisConnection()
@@ -380,6 +616,17 @@ namespace System.Data.ProviderBase
_connectionIsDoomed = true;
}
abstract public void EnlistTransaction(Transaction transaction);
protected internal virtual DataTable GetSchema(DbConnectionFactory factory, DbConnectionPoolGroup poolGroup, DbConnection outerConnection, string collectionName, string[] restrictions)
{
Debug.Assert(outerConnection != null, "outerConnection may not be null.");
DbMetaDataFactory metaDataFactory = factory.GetMetaDataFactory(poolGroup, this);
Debug.Assert(metaDataFactory != null, "metaDataFactory may not be null.");
return metaDataFactory.GetSchema(outerConnection, collectionName, restrictions);
}
internal void MakeNonPooledObject(object owningObject)
{
@@ -539,6 +786,98 @@ namespace System.Data.ProviderBase
}
}
// Cleanup connection's transaction-specific structures (currently used by Delegated transaction).
// This is a separate method because cleanup can be triggered in multiple ways for a delegated
// transaction.
virtual protected void CleanupTransactionOnCompletion(Transaction transaction)
{
}
internal void DetachCurrentTransactionIfEnded()
{
Transaction enlistedTransaction = EnlistedTransaction;
if (enlistedTransaction != null)
{
bool transactionIsDead;
try
{
transactionIsDead = (TransactionStatus.Active != enlistedTransaction.TransactionInformation.Status);
}
catch (TransactionException)
{
// If the transaction is being processed (i.e. is part way through a rollback\commit\etc then TransactionInformation.Status will throw an exception)
transactionIsDead = true;
}
if (transactionIsDead)
{
DetachTransaction(enlistedTransaction, true);
}
}
}
// Detach transaction from connection.
internal void DetachTransaction(Transaction transaction, bool isExplicitlyReleasing)
{
// potentially a multi-threaded event, so lock the connection to make sure we don't enlist in a new
// transaction between compare and assignment. No need to short circuit outside of lock, since failed comparisons should
// be the exception, not the rule.
lock (this)
{
// Detach if detach-on-end behavior, or if outer connection was closed
DbConnection owner = (DbConnection)Owner;
if (isExplicitlyReleasing || UnbindOnTransactionCompletion || null == owner)
{
Transaction currentEnlistedTransaction = _enlistedTransaction;
if (currentEnlistedTransaction != null && transaction.Equals(currentEnlistedTransaction))
{
EnlistedTransaction = null;
if (IsTxRootWaitingForTxEnd)
{
DelegatedTransactionEnded();
}
}
}
}
}
// Handle transaction detach, pool cleanup and other post-transaction cleanup tasks associated with
internal void CleanupConnectionOnTransactionCompletion(Transaction transaction)
{
DetachTransaction(transaction, false);
DbConnectionPool pool = Pool;
if (null != pool)
{
pool.TransactionEnded(transaction, this);
}
}
void TransactionCompletedEvent(object sender, TransactionEventArgs e)
{
Transaction transaction = e.Transaction;
CleanupTransactionOnCompletion(transaction);
CleanupConnectionOnTransactionCompletion(transaction);
}
// TODO: Review whether we need the unmanaged code permission when we have the new object model available.
// [SecurityPermission(SecurityAction.Assert, Flags = SecurityPermissionFlag.UnmanagedCode)]
private void TransactionOutcomeEnlist(Transaction transaction)
{
transaction.TransactionCompleted += new TransactionCompletedEventHandler(TransactionCompletedEvent);
}
internal void SetInStasis()
{
_isInStasis = true;
}
private void TerminateStasis(bool returningToPool)
{
_isInStasis = false;
}
/// <summary>
/// When overridden in a derived class, will check if the underlying connection is still actually alive
@@ -550,15 +889,5 @@ namespace System.Data.ProviderBase
{
return true;
}
protected internal virtual DataTable GetSchema(DbConnectionFactory factory, DbConnectionPoolGroup poolGroup, DbConnection outerConnection, string collectionName, string[] restrictions)
{
Debug.Assert(outerConnection != null, "outerConnection may not be null.");
DbMetaDataFactory metaDataFactory = factory.GetMetaDataFactory(poolGroup, this);
Debug.Assert(metaDataFactory != null, "metaDataFactory may not be null.");
return metaDataFactory.GetSchema(outerConnection, collectionName, restrictions);
}
}
}

Some files were not shown because too many files have changed in this diff Show More