From 4dd02496aea781a06e8c6161b6258e7705e576db Mon Sep 17 00:00:00 2001 From: Lawrence LCI Date: Wed, 20 Oct 2021 17:11:00 -0700 Subject: [PATCH 01/13] Merge netfx into netcore for TdsEnums.cs --- .../src/Microsoft/Data/SqlClient/TdsEnums.cs | 45 ++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsEnums.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsEnums.cs index 728e521847..9ea9fa2d38 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsEnums.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsEnums.cs @@ -20,6 +20,22 @@ internal static class TdsEnums public static readonly decimal SQL_SMALL_MONEY_MIN = new decimal(-214748.3648); public static readonly decimal SQL_SMALL_MONEY_MAX = new decimal(214748.3647); +#if NETFRAMEWORK + // sql debugging constants, sdci is the structure passed in + public const string SDCI_MAPFILENAME = "SqlClientSSDebug"; + public const byte SDCI_MAX_MACHINENAME = 32; + public const byte SDCI_MAX_DLLNAME = 16; + public const byte SDCI_MAX_DATA = 255; + public const int SQLDEBUG_OFF = 0; + public const int SQLDEBUG_ON = 1; + public const int SQLDEBUG_CONTEXT = 2; + public const string SP_SDIDEBUG = "sp_sdidebug"; + public static readonly string[] SQLDEBUG_MODE_NAMES = new string[3] { + "off", + "on", + "context" + }; +#endif // HACK!!! // Constant for SqlDbType.SmallVarBinary... store internal variable here instead of on @@ -208,6 +224,7 @@ public enum EnvChangeType : byte public const byte FEATUREEXT_TERMINATOR = 0xFF; public const byte FEATUREEXT_SRECOVERY = 0x01; public const byte FEATUREEXT_FEDAUTH = 0x02; + // 0x03 is for x_eFeatureExtensionId_Rcs public const byte FEATUREEXT_TCE = 0x04; public const byte FEATUREEXT_GLOBALTRANSACTIONS = 0x05; // 0x06 is for x_eFeatureExtensionId_LoginToken @@ -317,20 +334,28 @@ public enum ActiveDirectoryWorkflow : byte 0x72xx0002 -> Yukon RTM */ + // Pre Shiloh SP1 versioning scheme: + public const int SPHINXORSHILOH_MAJOR = 0x07; // The high byte (b3) is not sufficient to distinguish + public const int SPHINX_INCREMENT = 0x00; // Sphinx and Shiloh + public const int SHILOH_INCREMENT = 0x01; // So we need to look at the high-mid byte (b2) as well + public const int DEFAULT_MINOR = 0x0000; // Shiloh SP1 and beyond versioning scheme: // Majors: + public const int SHILOHSP1_MAJOR = 0x71; // For Shiloh SP1 and later the versioning schema changed and public const int YUKON_MAJOR = 0x72; // the high-byte is sufficient to distinguish later versions public const int KATMAI_MAJOR = 0x73; public const int DENALI_MAJOR = 0x74; // Increments: + public const int SHILOHSP1_INCREMENT = 0x00; public const int YUKON_INCREMENT = 0x09; public const int KATMAI_INCREMENT = 0x0b; public const int DENALI_INCREMENT = 0x00; // Minors: + public const int SHILOHSP1_MINOR = 0x0001; public const int YUKON_RTM_MINOR = 0x0002; public const int KATMAI_MINOR = 0x0003; public const int DENALI_MINOR = 0x0004; @@ -478,6 +503,10 @@ public enum ActiveDirectoryWorkflow : byte public const byte TVP_ORDERDESC_FLAG = 0x2; public const byte TVP_UNIQUE_FLAG = 0x4; +#if NETFRAMEWORK + public const bool Is68K = false; + public const bool TraceTDS = false; +#endif // RPC function names public const string SP_EXECUTESQL = "sp_executesql"; // used against 7.0 servers @@ -559,6 +588,10 @@ public enum ActiveDirectoryWorkflow : byte // dbnetlib error values public const short TIMEOUT_EXPIRED = -2; public const short ENCRYPTION_NOT_SUPPORTED = 20; +#if NETFRAMEWORK + public const short CTAIP_NOT_SUPPORTED = 21; +#endif + // CAUTION: These are not error codes returned by SNI. This is used for backward compatibility // since netlib (now removed from sqlclient) returned these codes. @@ -885,6 +918,13 @@ public enum ActiveDirectoryWorkflow : byte 0, /* 255 */ }; +#if NETFRAMEWORK + internal enum UDTFormatType + { + Native = 1, + UserDefined = 2 + } +#endif internal enum TransactionManagerRequestType { @@ -1160,7 +1200,10 @@ public enum SqlAuthenticationMethod ActiveDirectoryMSI, /// - ActiveDirectoryDefault + ActiveDirectoryDefault, +#if ADONET_CERT_AUTH && NETFRAMEWORK + SqlCertificate +#endif } // This enum indicates the state of TransparentNetworkIPResolution // The first attempt when TNIR is on should be sequential. If the first attempt failes next attempts should be parallel. From 850fde589ac98f2e78170d92b991ea091f1586e4 Mon Sep 17 00:00:00 2001 From: Lawrence LCI Date: Thu, 21 Oct 2021 08:45:26 -0700 Subject: [PATCH 02/13] Move TdsEnums.cs from netcore to shared src and update references in the csprojs --- .../src/Microsoft.Data.SqlClient.csproj | 4 +- .../netfx/src/Microsoft.Data.SqlClient.csproj | 4 +- .../src/Microsoft/Data/SqlClient/TdsEnums.cs | 1183 ----------------- .../src/Microsoft/Data/SqlClient/TdsEnums.cs | 0 4 files changed, 6 insertions(+), 1185 deletions(-) delete mode 100644 src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsEnums.cs rename src/Microsoft.Data.SqlClient/{netcore => }/src/Microsoft/Data/SqlClient/TdsEnums.cs (100%) 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 5b808d9b78..3bf596e22c 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj @@ -367,6 +367,9 @@ Microsoft\Data\SqlClient\SignatureVerificationCache.cs + + Microsoft\Data\SqlClient\TdsEnums.cs + Microsoft\Data\SqlClient\TdsValueSetter.cs @@ -594,7 +597,6 @@ Microsoft\Data\SqlClient\SqlUdtInfo.cs - 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 040dde902c..1b2f70b40f 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj @@ -426,6 +426,9 @@ Microsoft\Data\SqlClient\SqlSymmetricKeyCache.cs + + Microsoft\Data\SqlClient\TdsEnums.cs + Microsoft\Data\SqlClient\VirtualSecureModeEnclaveProvider.cs @@ -588,7 +591,6 @@ Microsoft\Data\SqlClient\SqlUdtInfo.cs - diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsEnums.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsEnums.cs deleted file mode 100644 index 20a7fad79e..0000000000 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsEnums.cs +++ /dev/null @@ -1,1183 +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. - -using System; -using System.Data; - -namespace Microsoft.Data.SqlClient -{ - /// Class of variables for the Tds connection. - /// - internal static class TdsEnums - { - - // internal tdsparser constants - - public const short SQL_SERVER_VERSION_SEVEN = 7; - - public const string SQL_PROVIDER_NAME = Common.DbConnectionStringDefaults.ApplicationName; - - public static readonly Decimal SQL_SMALL_MONEY_MIN = new Decimal(-214748.3648); - public static readonly Decimal SQL_SMALL_MONEY_MAX = new Decimal(214748.3647); - - // sql debugging constants, sdci is the structure passed in - public const string SDCI_MAPFILENAME = "SqlClientSSDebug"; - public const byte SDCI_MAX_MACHINENAME = 32; - public const byte SDCI_MAX_DLLNAME = 16; - public const byte SDCI_MAX_DATA = 255; - public const int SQLDEBUG_OFF = 0; - public const int SQLDEBUG_ON = 1; - public const int SQLDEBUG_CONTEXT = 2; - public const string SP_SDIDEBUG = "sp_sdidebug"; - public static readonly string[] SQLDEBUG_MODE_NAMES = new string[3] { - "off", - "on", - "context" - }; - - // HACK!!! - // Constant for SqlDbType.SmallVarBinary... store internal variable here instead of on - // SqlDbType so that it is not surfaced to the user!!! Related to dtc and the fact that - // the TransactionManager TDS stream is the only token left that uses VarBinarys instead of - // BigVarBinarys. - public const SqlDbType SmallVarBinary = (SqlDbType)(SqlDbType.Variant) + 1; - - // network protocol string constants - public const string TCP = "tcp"; - public const string NP = "np"; - public const string RPC = "rpc"; - public const string BV = "bv"; - public const string ADSP = "adsp"; - public const string SPX = "spx"; - public const string VIA = "via"; - public const string LPC = "lpc"; - - // network function string contants - public const string INIT_SSPI_PACKAGE = "InitSSPIPackage"; - public const string INIT_SESSION = "InitSession"; - public const string CONNECTION_GET_SVR_USER = "ConnectionGetSvrUser"; - public const string GEN_CLIENT_CONTEXT = "GenClientContext"; - - // tdsparser packet handling constants - public const byte SOFTFLUSH = 0; - public const byte HARDFLUSH = 1; - public const byte IGNORE = 2; - - // header constants - public const int HEADER_LEN = 8; - public const int HEADER_LEN_FIELD_OFFSET = 2; - public const int SPID_OFFSET = 4; - public const int YUKON_HEADER_LEN = 12; //Yukon headers also include a MARS session id - public const int MARS_ID_OFFSET = 8; - public const int HEADERTYPE_QNOTIFICATION = 1; - public const int HEADERTYPE_MARS = 2; - public const int HEADERTYPE_TRACE = 3; - - // other various constants - public const int SUCCEED = 1; - public const int FAIL = 0; - public const short TYPE_SIZE_LIMIT = 8000; - public const int MIN_PACKET_SIZE = 512; - // Login packet can be no greater than 4k until server sends us env-change - // increasing packet size. - public const int DEFAULT_LOGIN_PACKET_SIZE = 4096; - public const int MAX_PRELOGIN_PAYLOAD_LENGTH = 1024; - public const int MAX_PACKET_SIZE = 32768; - public const int MAX_SERVER_USER_NAME = 256; // obtained from luxor - - // Severity 0 - 10 indicates informational (non-error) messages - // Severity 11 - 16 indicates errors that can be corrected by user (syntax errors, etc...) - // Severity 17 - 19 indicates failure due to insufficient resources in the server - // (max locks exceeded, not enough memory, other internal server limits reached, etc..) - // Severity 20 - 25 Severe problems with the server, connection terminated. - public const byte MIN_ERROR_CLASS = 11; // webdata 100667: This should actually be 11 - public const byte MAX_USER_CORRECTABLE_ERROR_CLASS = 16; - public const byte FATAL_ERROR_CLASS = 20; - - // Message types - public const byte MT_SQL = 1; // SQL command batch - public const byte MT_LOGIN = 2; // Login message for pre-Sphinx (before version 7.0) - public const byte MT_RPC = 3; // Remote procedure call - public const byte MT_TOKENS = 4; // Table response data stream - public const byte MT_BINARY = 5; // Unformatted binary response data (UNUSED) - public const byte MT_ATTN = 6; // Attention (break) signal - public const byte MT_BULK = 7; // Bulk load data - public const byte MT_FEDAUTH = 8; // Authentication token for federated authentication - public const byte MT_CLOSE = 9; // Close subchannel (UNUSED) - public const byte MT_ERROR = 10; // Protocol error detected - public const byte MT_ACK = 11; // Protocol acknowledgement (UNUSED) - public const byte MT_ECHO = 12; // Echo data (UNUSED) - public const byte MT_LOGOUT = 13; // Logout message (UNUSED) - public const byte MT_TRANS = 14; // Transaction Manager Interface - public const byte MT_OLEDB = 15; // ? (UNUSED) - public const byte MT_LOGIN7 = 16; // Login message for Sphinx (version 7) or later - public const byte MT_SSPI = 17; // SSPI message - public const byte MT_PRELOGIN = 18; // Pre-login handshake - - // Message status bits - public const byte ST_EOM = 0x1; // Packet is end-of-message - public const byte ST_AACK = 0x2; // Packet acknowledges attention (server to client) - public const byte ST_IGNORE = 0x2; // Ignore this event (client to server) - public const byte ST_BATCH = 0x4; // Message is part of a batch. - public const byte ST_RESET_CONNECTION = 0x8; // Exec sp_reset_connection prior to processing message - public const byte ST_RESET_CONNECTION_PRESERVE_TRANSACTION = 0x10; // reset prior to processing, with preserving local tx - - // TDS control tokens - public const byte SQLCOLFMT = 0xa1; - public const byte SQLPROCID = 0x7c; - public const byte SQLCOLNAME = 0xa0; - public const byte SQLTABNAME = 0xa4; - public const byte SQLCOLINFO = 0xa5; - public const byte SQLALTNAME = 0xa7; - public const byte SQLALTFMT = 0xa8; - public const byte SQLERROR = 0xaa; - public const byte SQLINFO = 0xab; - public const byte SQLRETURNVALUE = 0xac; - public const byte SQLRETURNSTATUS = 0x79; - public const byte SQLRETURNTOK = 0xdb; - public const byte SQLALTCONTROL = 0xaf; - public const byte SQLROW = 0xd1; - public const byte SQLNBCROW = 0xd2; // same as ROW with null-bit-compression support - public const byte SQLALTROW = 0xd3; - public const byte SQLDONE = 0xfd; - public const byte SQLDONEPROC = 0xfe; - public const byte SQLDONEINPROC = 0xff; - public const byte SQLOFFSET = 0x78; - public const byte SQLORDER = 0xa9; - public const byte SQLDEBUG_CMD = 0x60; - public const byte SQLLOGINACK = 0xad; - public const byte SQLFEATUREEXTACK = 0xae; // TDS 7.4 - feature ack - public const byte SQLSESSIONSTATE = 0xe4; // TDS 7.4 - connection resiliency session state - public const byte SQLENVCHANGE = 0xe3; // Environment change notification - public const byte SQLSECLEVEL = 0xed; // Security level token ??? - public const byte SQLROWCRC = 0x39; // ROWCRC datastream??? - public const byte SQLCOLMETADATA = 0x81; // Column metadata including name - public const byte SQLALTMETADATA = 0x88; // Alt column metadata including name - public const byte SQLSSPI = 0xed; // SSPI data - public const byte SQLFEDAUTHINFO = 0xee; // Info for client to generate fed auth token - public const byte SQLRESCOLSRCS = 0xa2; - public const byte SQLDATACLASSIFICATION = 0xa3; - - // Environment change notification streams - // TYPE on TDS ENVCHANGE token stream (from sql\ntdbms\include\odsapi.h) - // - public const byte ENV_DATABASE = 1; // Database changed - public const byte ENV_LANG = 2; // Language changed - public const byte ENV_CHARSET = 3; // Character set changed - public const byte ENV_PACKETSIZE = 4; // Packet size changed - public const byte ENV_LOCALEID = 5; // Unicode data sorting locale id - public const byte ENV_COMPFLAGS = 6; // Unicode data sorting comparison flags - public const byte ENV_COLLATION = 7; // SQL Collation - // The following are environment change tokens valid for Yukon or later. - public const byte ENV_BEGINTRAN = 8; // Transaction began - public const byte ENV_COMMITTRAN = 9; // Transaction committed - public const byte ENV_ROLLBACKTRAN = 10; // Transaction rolled back - public const byte ENV_ENLISTDTC = 11; // Enlisted in Distributed Transaction - public const byte ENV_DEFECTDTC = 12; // Defected from Distributed Transaction - public const byte ENV_LOGSHIPNODE = 13; // Realtime Log shipping primary node - public const byte ENV_PROMOTETRANSACTION = 15; // Promote Transaction - public const byte ENV_TRANSACTIONMANAGERADDRESS = 16; // Transaction Manager Address - public const byte ENV_TRANSACTIONENDED = 17; // Transaction Ended - public const byte ENV_SPRESETCONNECTIONACK = 18; // SP_Reset_Connection ack - public const byte ENV_USERINSTANCE = 19; // User Instance - public const byte ENV_ROUTING = 20; // Routing (ROR) information - - // done status stream bit masks - public const int DONE_MORE = 0x0001; // more command results coming - public const int DONE_ERROR = 0x0002; // error in command batch - public const int DONE_INXACT = 0x0004; // transaction in progress - public const int DONE_PROC = 0x0008; // done from stored proc - public const int DONE_COUNT = 0x0010; // count in done info - public const int DONE_ATTN = 0x0020; // oob ack - public const int DONE_INPROC = 0x0040; // like DONE_PROC except proc had error - public const int DONE_RPCINBATCH = 0x0080; // Done from RPC in batch - public const int DONE_SRVERROR = 0x0100; // Severe error in which resultset should be discarded - public const int DONE_FMTSENT = 0x8000; // fmt message sent, done_inproc req'd - - // Feature Extension - public const byte FEATUREEXT_TERMINATOR = 0xFF; - public const byte FEATUREEXT_SRECOVERY = 0x01; - public const byte FEATUREEXT_FEDAUTH = 0x02; - // 0x03 is for x_eFeatureExtensionId_Rcs - public const byte FEATUREEXT_TCE = 0x04; - public const byte FEATUREEXT_GLOBALTRANSACTIONS = 0x05; - // 0x06 is for x_eFeatureExtensionId_LoginToken - // 0x07 is for x_eFeatureExtensionId_ClientSideTelemetry - public const byte FEATUREEXT_AZURESQLSUPPORT = 0x08; - public const byte FEATUREEXT_DATACLASSIFICATION = 0x09; - public const byte FEATUREEXT_UTF8SUPPORT = 0x0A; - public const byte FEATUREEXT_SQLDNSCACHING = 0x0B; - - [Flags] - public enum FeatureExtension : uint - { - None = 0, - SessionRecovery = 1 << (TdsEnums.FEATUREEXT_SRECOVERY - 1), - FedAuth = 1 << (TdsEnums.FEATUREEXT_FEDAUTH - 1), - Tce = 1 << (TdsEnums.FEATUREEXT_TCE - 1), - GlobalTransactions = 1 << (TdsEnums.FEATUREEXT_GLOBALTRANSACTIONS - 1), - AzureSQLSupport = 1 << (TdsEnums.FEATUREEXT_AZURESQLSUPPORT - 1), - DataClassification = 1 << (TdsEnums.FEATUREEXT_DATACLASSIFICATION - 1), - UTF8Support = 1 << (TdsEnums.FEATUREEXT_UTF8SUPPORT - 1), - SQLDNSCaching = 1 << (TdsEnums.FEATUREEXT_SQLDNSCACHING - 1) - } - - public const uint UTF8_IN_TDSCOLLATION = 0x4000000; - - public const byte FEDAUTHLIB_LIVEID = 0X00; - public const byte FEDAUTHLIB_SECURITYTOKEN = 0x01; - public const byte FEDAUTHLIB_MSAL = 0x02; - public const byte FEDAUTHLIB_RESERVED = 0X7F; - - public enum FedAuthLibrary : byte - { - LiveId = FEDAUTHLIB_LIVEID, - SecurityToken = FEDAUTHLIB_SECURITYTOKEN, - MSAL = FEDAUTHLIB_MSAL, - Default = FEDAUTHLIB_RESERVED - } - - public const byte MSALWORKFLOW_ACTIVEDIRECTORYPASSWORD = 0x01; - public const byte MSALWORKFLOW_ACTIVEDIRECTORYINTEGRATED = 0x02; - public const byte MSALWORKFLOW_ACTIVEDIRECTORYINTERACTIVE = 0x03; - public const byte MSALWORKFLOW_ACTIVEDIRECTORYSERVICEPRINCIPAL = 0x01; // Using the Password byte as that is the closest we have - public const byte MSALWORKFLOW_ACTIVEDIRECTORYDEVICECODEFLOW = 0x03; // Using the Interactive byte as that is the closest we have - public const byte MSALWORKFLOW_ACTIVEDIRECTORYMANAGEDIDENTITY = 0x03; // Using the Interactive byte as that's supported for Identity based authentication - public const byte MSALWORKFLOW_ACTIVEDIRECTORYDEFAULT = 0x03; // Using the Interactive byte as that is the closest we have to non-password based authentication modes - - public enum ActiveDirectoryWorkflow : byte - { - Password = MSALWORKFLOW_ACTIVEDIRECTORYPASSWORD, - Integrated = MSALWORKFLOW_ACTIVEDIRECTORYINTEGRATED, - Interactive = MSALWORKFLOW_ACTIVEDIRECTORYINTERACTIVE, - ServicePrincipal = MSALWORKFLOW_ACTIVEDIRECTORYSERVICEPRINCIPAL, - DeviceCodeFlow = MSALWORKFLOW_ACTIVEDIRECTORYDEVICECODEFLOW, - ManagedIdentity = MSALWORKFLOW_ACTIVEDIRECTORYMANAGEDIDENTITY, - Default = MSALWORKFLOW_ACTIVEDIRECTORYDEFAULT, - } - - // The string used for username in the error message when Authentication = Active Directory Integrated with FedAuth is used, if authentication fails. - public const string NTAUTHORITYANONYMOUSLOGON = @"NT Authority\Anonymous Logon"; - - // Loginrec defines - public const byte MAX_LOG_NAME = 30; // TDS 4.2 login rec max name length - public const byte MAX_PROG_NAME = 10; // max length of loginrec progran name - public const byte SEC_COMP_LEN = 8; // length of security compartments - public const byte MAX_PK_LEN = 6; // max length of TDS packet size - public const byte MAX_NIC_SIZE = 6; // The size of a MAC or client address - public const byte SQLVARIANT_SIZE = 2; // size of the fixed portion of a sql variant (type, cbPropBytes) - public const byte VERSION_SIZE = 4; // size of the tds version (4 unsigned bytes) - public const int CLIENT_PROG_VER = 0x06000000; // Client interface version - public const int YUKON_LOG_REC_FIXED_LEN = 0x5e; - // misc - public const int TEXT_TIME_STAMP_LEN = 8; - public const int COLLATION_INFO_LEN = 4; - - /* - public const byte INT4_LSB_HI = 0; // lsb is low byte (eg 68000) - // public const byte INT4_LSB_LO = 1; // lsb is low byte (eg VAX) - public const byte INT2_LSB_HI = 2; // lsb is low byte (eg 68000) - // public const byte INT2_LSB_LO = 3; // lsb is low byte (eg VAX) - public const byte FLT_IEEE_HI = 4; // lsb is low byte (eg 68000) - public const byte CHAR_ASCII = 6; // ASCII character set - public const byte TWO_I4_LSB_HI = 8; // lsb is low byte (eg 68000 - // public const byte TWO_I4_LSB_LO = 9; // lsb is low byte (eg VAX) - // public const byte FLT_IEEE_LO = 10; // lsb is low byte (eg MSDOS) - public const byte FLT4_IEEE_HI = 12; // IEEE 4-byte floating point -lsb is high byte - // public const byte FLT4_IEEE_LO = 13; // IEEE 4-byte floating point -lsb is low byte - public const byte TWO_I2_LSB_HI = 16; // lsb is high byte - // public const byte TWO_I2_LSB_LO = 17; // lsb is low byte - - public const byte LDEFSQL = 0; // server sends its default - public const byte LDEFUSER = 0; // regular old user - public const byte LINTEGRATED = 8; // integrated security login - */ - - /* Versioning scheme table: - - Client sends: - 0x70000000 -> Sphinx - 0x71000000 -> Shiloh RTM - 0x71000001 -> Shiloh SP1 - 0x72xx0002 -> Yukon RTM - - Server responds: - 0x07000000 -> Sphinx // Notice server response format is different for bwd compat - 0x07010000 -> Shiloh RTM // Notice server response format is different for bwd compat - 0x71000001 -> Shiloh SP1 - 0x72xx0002 -> Yukon RTM - */ - - // Pre Shiloh SP1 versioning scheme: - public const int SPHINXORSHILOH_MAJOR = 0x07; // The high byte (b3) is not sufficient to distinguish - public const int SPHINX_INCREMENT = 0x00; // Sphinx and Shiloh - public const int SHILOH_INCREMENT = 0x01; // So we need to look at the high-mid byte (b2) as well - public const int DEFAULT_MINOR = 0x0000; - - // Shiloh SP1 and beyond versioning scheme: - - // Majors: - public const int SHILOHSP1_MAJOR = 0x71; // For Shiloh SP1 and later the versioning schema changed and - public const int YUKON_MAJOR = 0x72; // the high-byte is sufficient to distinguish later versions - public const int KATMAI_MAJOR = 0x73; - public const int DENALI_MAJOR = 0x74; - - // Increments: - public const int SHILOHSP1_INCREMENT = 0x00; - public const int YUKON_INCREMENT = 0x09; - public const int KATMAI_INCREMENT = 0x0b; - public const int DENALI_INCREMENT = 0x00; - - // Minors: - public const int SHILOHSP1_MINOR = 0x0001; - public const int YUKON_RTM_MINOR = 0x0002; - public const int KATMAI_MINOR = 0x0003; - public const int DENALI_MINOR = 0x0004; - - public const int ORDER_68000 = 1; - public const int USE_DB_ON = 1; - public const int INIT_DB_FATAL = 1; - public const int SET_LANG_ON = 1; - public const int INIT_LANG_FATAL = 1; - public const int ODBC_ON = 1; - public const int SSPI_ON = 1; - public const int REPL_ON = 3; - - - // send the read-only intent to the server - public const int READONLY_INTENT_ON = 1; - - // Token masks - public const byte SQLLenMask = 0x30; // mask to check for length tokens - public const byte SQLFixedLen = 0x30; // Mask to check for fixed token - public const byte SQLVarLen = 0x20; // Value to check for variable length token - public const byte SQLZeroLen = 0x10; // Value to check for zero length token - public const byte SQLVarCnt = 0x00; // Value to check for variable count token - - // Token masks for COLINFO status - public const byte SQLDifferentName = 0x20; // column name different than select list name - public const byte SQLExpression = 0x4; // column was result of an expression - public const byte SQLKey = 0x8; // column is part of the key for the table - public const byte SQLHidden = 0x10; // column not part of select list but added because part of key - - // Token masks for COLMETADATA flags - // first byte - public const byte Nullable = 0x1; - public const byte Identity = 0x10; - public const byte Updatability = 0xb; // mask off bits 3 and 4 - // second byte - public const byte ClrFixedLen = 0x1; // Fixed length CLR type - public const byte IsColumnSet = 0x4; // Column is an XML representation of an aggregation of other columns - public const byte IsEncrypted = 0x8; // Column is encrypted using TCE - - // null values - public const uint VARLONGNULL = 0xffffffff; // null value for text and image types - public const int VARNULL = 0xffff; // null value for character and binary types - public const int MAXSIZE = 8000; // max size for any column - public const byte FIXEDNULL = 0; - public const UInt64 UDTNULL = 0xffffffffffffffff; - - // SQL Server Data Type Tokens. - public const int SQLVOID = 0x1f; - public const int SQLTEXT = 0x23; - public const int SQLVARBINARY = 0x25; - public const int SQLINTN = 0x26; - public const int SQLVARCHAR = 0x27; - public const int SQLBINARY = 0x2d; - public const int SQLIMAGE = 0x22; - public const int SQLCHAR = 0x2f; - public const int SQLINT1 = 0x30; - public const int SQLBIT = 0x32; - public const int SQLINT2 = 0x34; - public const int SQLINT4 = 0x38; - public const int SQLMONEY = 0x3c; - public const int SQLDATETIME = 0x3d; - public const int SQLFLT8 = 0x3e; - public const int SQLFLTN = 0x6d; - public const int SQLMONEYN = 0x6e; - public const int SQLDATETIMN = 0x6f; - public const int SQLFLT4 = 0x3b; - public const int SQLMONEY4 = 0x7a; - public const int SQLDATETIM4 = 0x3a; - public const int SQLDECIMALN = 0x6a; - public const int SQLNUMERICN = 0x6c; - public const int SQLUNIQUEID = 0x24; - public const int SQLBIGCHAR = 0xaf; - public const int SQLBIGVARCHAR = 0xa7; - public const int SQLBIGBINARY = 0xad; - public const int SQLBIGVARBINARY = 0xa5; - public const int SQLBITN = 0x68; - public const int SQLNCHAR = 0xef; - public const int SQLNVARCHAR = 0xe7; - public const int SQLNTEXT = 0x63; - public const int SQLUDT = 0xF0; - - // aggregate operator type TDS tokens, used by compute statements: - public const int AOPCNTB = 0x09; - public const int AOPSTDEV = 0x30; - public const int AOPSTDEVP = 0x31; - public const int AOPVAR = 0x32; - public const int AOPVARP = 0x33; - - public const int AOPCNT = 0x4b; - public const int AOPSUM = 0x4d; - public const int AOPAVG = 0x4f; - public const int AOPMIN = 0x51; - public const int AOPMAX = 0x52; - public const int AOPANY = 0x53; - public const int AOPNOOP = 0x56; - - // SQL Server user-defined type tokens we care about - public const int SQLTIMESTAMP = 0x50; - - public const int MAX_NUMERIC_LEN = 0x11; // 17 bytes of data for max numeric/decimal length - public const int DEFAULT_NUMERIC_PRECISION = 0x1D; // 29 is the default max numeric precision(Decimal.MaxValue) if not user set - public const int SPHINX_DEFAULT_NUMERIC_PRECISION = 0x1C; // 28 is the default max numeric precision for Sphinx(Decimal.MaxValue doesn't work for sphinx) - public const int MAX_NUMERIC_PRECISION = 0x26; // 38 is max numeric precision; - public const byte UNKNOWN_PRECISION_SCALE = 0xff; // -1 is value for unknown precision or scale - - // The following datatypes are specific to SHILOH (version 8) and later. - public const int SQLINT8 = 0x7f; - public const int SQLVARIANT = 0x62; - - // The following datatypes are specific to Yukon (version 9) or later - public const int SQLXMLTYPE = 0xf1; - public const int XMLUNICODEBOM = 0xfeff; - public static readonly byte[] XMLUNICODEBOMBYTES = { 0xff, 0xfe }; - - // The following datatypes are specific to Katmai (version 10) or later - public const int SQLTABLE = 0xf3; - public const int SQLDATE = 0x28; - public const int SQLTIME = 0x29; - public const int SQLDATETIME2 = 0x2a; - public const int SQLDATETIMEOFFSET = 0x2b; - - public const int DEFAULT_VARTIME_SCALE = 7; - - //Partially length prefixed datatypes constants. These apply to XMLTYPE, BIGVARCHRTYPE, - // NVARCHARTYPE, and BIGVARBINTYPE. Valid for Yukon or later - - public const ulong SQL_PLP_NULL = 0xffffffffffffffff; // Represents null value - public const ulong SQL_PLP_UNKNOWNLEN = 0xfffffffffffffffe; // Data coming in chunks, total length unknown - public const int SQL_PLP_CHUNK_TERMINATOR = 0x00000000; // Represents end of chunked data. - public const ushort SQL_USHORTVARMAXLEN = 0xffff; // Second ushort in TDS stream is this value if one of max types - - // TVPs require some new in-value control tokens: - public const byte TVP_ROWCOUNT_ESTIMATE = 0x12; - public const byte TVP_ROW_TOKEN = 0x01; - public const byte TVP_END_TOKEN = 0x00; - public const ushort TVP_NOMETADATA_TOKEN = 0xFFFF; - public const byte TVP_ORDER_UNIQUE_TOKEN = 0x10; - - // TvpColumnMetaData flags - public const int TVP_DEFAULT_COLUMN = 0x200; - - // TVP_ORDER_UNIQUE_TOKEN flags - public const byte TVP_ORDERASC_FLAG = 0x1; - public const byte TVP_ORDERDESC_FLAG = 0x2; - public const byte TVP_UNIQUE_FLAG = 0x4; - - public const bool Is68K = false; - public const bool TraceTDS = false; - - // RPC function names - public const string SP_EXECUTESQL = "sp_executesql"; // used against 7.0 servers - public const string SP_PREPEXEC = "sp_prepexec"; // used against 7.5 servers - - public const string SP_PREPARE = "sp_prepare"; // used against 7.0 servers - public const string SP_EXECUTE = "sp_execute"; - public const string SP_UNPREPARE = "sp_unprepare"; - public const string SP_PARAMS = "sp_procedure_params_rowset"; - public const string SP_PARAMS_MANAGED = "sp_procedure_params_managed"; - public const string SP_PARAMS_MGD10 = "sp_procedure_params_100_managed"; - - // RPC ProcID's - // NOTE: It is more efficient to call these procs using ProcID's instead of names - public const ushort RPC_PROCID_CURSOR = 1; - public const ushort RPC_PROCID_CURSOROPEN = 2; - public const ushort RPC_PROCID_CURSORPREPARE = 3; - public const ushort RPC_PROCID_CURSOREXECUTE = 4; - public const ushort RPC_PROCID_CURSORPREPEXEC = 5; - public const ushort RPC_PROCID_CURSORUNPREPARE = 6; - public const ushort RPC_PROCID_CURSORFETCH = 7; - public const ushort RPC_PROCID_CURSOROPTION = 8; - public const ushort RPC_PROCID_CURSORCLOSE = 9; - public const ushort RPC_PROCID_EXECUTESQL = 10; - public const ushort RPC_PROCID_PREPARE = 11; - public const ushort RPC_PROCID_EXECUTE = 12; - public const ushort RPC_PROCID_PREPEXEC = 13; - public const ushort RPC_PROCID_PREPEXECRPC = 14; - public const ushort RPC_PROCID_UNPREPARE = 15; - - // For Transactions - public const string TRANS_BEGIN = "BEGIN TRANSACTION"; - public const string TRANS_COMMIT = "COMMIT TRANSACTION"; - public const string TRANS_ROLLBACK = "ROLLBACK TRANSACTION"; - public const string TRANS_IF_ROLLBACK = "IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION"; - public const string TRANS_SAVE = "SAVE TRANSACTION"; - - // For Transactions - isolation levels - public const string TRANS_READ_COMMITTED = "SET TRANSACTION ISOLATION LEVEL READ COMMITTED"; - public const string TRANS_READ_UNCOMMITTED = "SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED"; - public const string TRANS_REPEATABLE_READ = "SET TRANSACTION ISOLATION LEVEL REPEATABLE READ"; - public const string TRANS_SERIALIZABLE = "SET TRANSACTION ISOLATION LEVEL SERIALIZABLE"; - public const string TRANS_SNAPSHOT = "SET TRANSACTION ISOLATION LEVEL SNAPSHOT"; - - // Batch RPC flags - public const byte SHILOH_RPCBATCHFLAG = 0x80; - public const byte YUKON_RPCBATCHFLAG = 0xFF; - - // RPC flags - public const byte RPC_RECOMPILE = 0x1; - public const byte RPC_NOMETADATA = 0x2; - - // RPC parameter class - public const byte RPC_PARAM_BYREF = 0x1; - public const byte RPC_PARAM_DEFAULT = 0x2; - public const byte RPC_PARAM_ENCRYPTED = 0x8; - - // SQL parameter list text - public const string PARAM_OUTPUT = "output"; - - // SQL Parameter constants - public const int MAX_PARAMETER_NAME_LENGTH = 128; - - // metadata options (added around an existing sql statement) - - // prefixes - public const string FMTONLY_ON = " SET FMTONLY ON;"; - public const string FMTONLY_OFF = " SET FMTONLY OFF;"; - // suffixes - public const string BROWSE_ON = " SET NO_BROWSETABLE ON;"; - public const string BROWSE_OFF = " SET NO_BROWSETABLE OFF;"; - - // generic table name - public const string TABLE = "Table"; - - public const int EXEC_THRESHOLD = 0x3; // if the number of commands we execute is > than this threshold, than do prep/exec/unprep instead - // of executesql. - - // dbnetlib error values - public const short TIMEOUT_EXPIRED = -2; - public const short ENCRYPTION_NOT_SUPPORTED = 20; - public const short CTAIP_NOT_SUPPORTED = 21; - - // CAUTION: These are not error codes returned by SNI. This is used for backward compatibility - // since netlib (now removed from sqlclient) returned these codes. - - // SQL error values (from sqlerrorcodes.h) - public const int LOGON_FAILED = 18456; - public const int PASSWORD_EXPIRED = 18488; - public const int IMPERSONATION_FAILED = 1346; - public const int P_TOKENTOOLONG = 103; - - // SQL error that indicates retry for Always Encrypted - public const int TCE_CONVERSION_ERROR_CLIENT_RETRY = 33514; - public const int TCE_ENCLAVE_INVALID_SESSION_HANDLE = 33195; - - // SNI\Win32 error values - // NOTE: these are simply windows system error codes, not SNI specific - public const uint SNI_UNINITIALIZED = unchecked((uint)-1); - public const uint SNI_SUCCESS = 0; // The operation completed successfully. - public const uint SNI_WAIT_TIMEOUT = 258; // The wait operation timed out. - public const uint SNI_SUCCESS_IO_PENDING = 997; // Overlapped I/O operation is in progress. - - // Windows Sockets Error Codes - public const short SNI_WSAECONNRESET = 10054; // An existing connection was forcibly closed by the remote host. - - // SNI flags - public const UInt32 SNI_SSL_VALIDATE_CERTIFICATE = 1; // This enables validation of server certificate - public const UInt32 SNI_SSL_USE_SCHANNEL_CACHE = 2; // This enables schannel session cache - public const UInt32 SNI_SSL_IGNORE_CHANNEL_BINDINGS = 0x10; // Used with SSL Provider, sent to SNIAddProvider in case of SQL Authentication & Encrypt. - - public const string DEFAULT_ENGLISH_CODE_PAGE_STRING = "iso_1"; - public const short DEFAULT_ENGLISH_CODE_PAGE_VALUE = 1252; - public const short CHARSET_CODE_PAGE_OFFSET = 2; - internal const int MAX_SERVERNAME = 255; - - // Sql Statement Tokens in the DONE packet - // (see ntdbms\ntinc\tokens.h) - // - internal const ushort SELECT = 0xc1; - internal const ushort INSERT = 0xc3; - internal const ushort DELETE = 0xc4; - internal const ushort UPDATE = 0xc5; - internal const ushort ABORT = 0xd2; - internal const ushort BEGINXACT = 0xd4; - internal const ushort ENDXACT = 0xd5; - internal const ushort BULKINSERT = 0xf0; - internal const ushort OPENCURSOR = 0x20; - internal const ushort MERGE = 0x117; - - - // Login data validation Rules - // - internal const ushort MAXLEN_HOSTNAME = 128; // the client machine name - internal const ushort MAXLEN_CLIENTID = 128; - internal const ushort MAXLEN_CLIENTSECRET = 128; - internal const ushort MAXLEN_APPNAME = 128; // the client application name - internal const ushort MAXLEN_SERVERNAME = 128; // the server name - internal const ushort MAXLEN_CLIENTINTERFACE = 128; // the interface library name - internal const ushort MAXLEN_LANGUAGE = 128; // the initial language - internal const ushort MAXLEN_DATABASE = 128; // the initial database - internal const ushort MAXLEN_ATTACHDBFILE = 260; // the filename for a database that is to be attached during the connection process - internal const ushort MAXLEN_NEWPASSWORD = 128; // new password for the specified login. - - - // array copied directly from tdssort.h from luxor - public static readonly UInt16[] CODE_PAGE_FROM_SORT_ID = { - 0, /* 0 */ - 0, /* 1 */ - 0, /* 2 */ - 0, /* 3 */ - 0, /* 4 */ - 0, /* 5 */ - 0, /* 6 */ - 0, /* 7 */ - 0, /* 8 */ - 0, /* 9 */ - 0, /* 10 */ - 0, /* 11 */ - 0, /* 12 */ - 0, /* 13 */ - 0, /* 14 */ - 0, /* 15 */ - 0, /* 16 */ - 0, /* 17 */ - 0, /* 18 */ - 0, /* 19 */ - 0, /* 20 */ - 0, /* 21 */ - 0, /* 22 */ - 0, /* 23 */ - 0, /* 24 */ - 0, /* 25 */ - 0, /* 26 */ - 0, /* 27 */ - 0, /* 28 */ - 0, /* 29 */ - 437, /* 30 */ - 437, /* 31 */ - 437, /* 32 */ - 437, /* 33 */ - 437, /* 34 */ - 0, /* 35 */ - 0, /* 36 */ - 0, /* 37 */ - 0, /* 38 */ - 0, /* 39 */ - 850, /* 40 */ - 850, /* 41 */ - 850, /* 42 */ - 850, /* 43 */ - 850, /* 44 */ - 0, /* 45 */ - 0, /* 46 */ - 0, /* 47 */ - 0, /* 48 */ - 850, /* 49 */ - 1252, /* 50 */ - 1252, /* 51 */ - 1252, /* 52 */ - 1252, /* 53 */ - 1252, /* 54 */ - 850, /* 55 */ - 850, /* 56 */ - 850, /* 57 */ - 850, /* 58 */ - 850, /* 59 */ - 850, /* 60 */ - 850, /* 61 */ - 0, /* 62 */ - 0, /* 63 */ - 0, /* 64 */ - 0, /* 65 */ - 0, /* 66 */ - 0, /* 67 */ - 0, /* 68 */ - 0, /* 69 */ - 0, /* 70 */ - 1252, /* 71 */ - 1252, /* 72 */ - 1252, /* 73 */ - 1252, /* 74 */ - 1252, /* 75 */ - 0, /* 76 */ - 0, /* 77 */ - 0, /* 78 */ - 0, /* 79 */ - 1250, /* 80 */ - 1250, /* 81 */ - 1250, /* 82 */ - 1250, /* 83 */ - 1250, /* 84 */ - 1250, /* 85 */ - 1250, /* 86 */ - 1250, /* 87 */ - 1250, /* 88 */ - 1250, /* 89 */ - 1250, /* 90 */ - 1250, /* 91 */ - 1250, /* 92 */ - 1250, /* 93 */ - 1250, /* 94 */ - 1250, /* 95 */ - 1250, /* 96 */ - 1250, /* 97 */ - 1250, /* 98 */ - 0, /* 99 */ - 0, /* 100 */ - 0, /* 101 */ - 0, /* 102 */ - 0, /* 103 */ - 1251, /* 104 */ - 1251, /* 105 */ - 1251, /* 106 */ - 1251, /* 107 */ - 1251, /* 108 */ - 0, /* 109 */ - 0, /* 110 */ - 0, /* 111 */ - 1253, /* 112 */ - 1253, /* 113 */ - 1253, /* 114 */ - 0, /* 115 */ - 0, /* 116 */ - 0, /* 117 */ - 0, /* 118 */ - 0, /* 119 */ - 1253, /* 120 */ - 1253, /* 121 */ - 1253, /* 122 */ - 0, /* 123 */ - 1253, /* 124 */ - 0, /* 125 */ - 0, /* 126 */ - 0, /* 127 */ - 1254, /* 128 */ - 1254, /* 129 */ - 1254, /* 130 */ - 0, /* 131 */ - 0, /* 132 */ - 0, /* 133 */ - 0, /* 134 */ - 0, /* 135 */ - 1255, /* 136 */ - 1255, /* 137 */ - 1255, /* 138 */ - 0, /* 139 */ - 0, /* 140 */ - 0, /* 141 */ - 0, /* 142 */ - 0, /* 143 */ - 1256, /* 144 */ - 1256, /* 145 */ - 1256, /* 146 */ - 0, /* 147 */ - 0, /* 148 */ - 0, /* 149 */ - 0, /* 150 */ - 0, /* 151 */ - 1257, /* 152 */ - 1257, /* 153 */ - 1257, /* 154 */ - 1257, /* 155 */ - 1257, /* 156 */ - 1257, /* 157 */ - 1257, /* 158 */ - 1257, /* 159 */ - 1257, /* 160 */ - 0, /* 161 */ - 0, /* 162 */ - 0, /* 163 */ - 0, /* 164 */ - 0, /* 165 */ - 0, /* 166 */ - 0, /* 167 */ - 0, /* 168 */ - 0, /* 169 */ - 0, /* 170 */ - 0, /* 171 */ - 0, /* 172 */ - 0, /* 173 */ - 0, /* 174 */ - 0, /* 175 */ - 0, /* 176 */ - 0, /* 177 */ - 0, /* 178 */ - 0, /* 179 */ - 0, /* 180 */ - 0, /* 181 */ - 0, /* 182 */ - 1252, /* 183 */ - 1252, /* 184 */ - 1252, /* 185 */ - 1252, /* 186 */ - 0, /* 187 */ - 0, /* 188 */ - 0, /* 189 */ - 0, /* 190 */ - 0, /* 191 */ - 932, /* 192 */ - 932, /* 193 */ - 949, /* 194 */ - 949, /* 195 */ - 950, /* 196 */ - 950, /* 197 */ - 936, /* 198 */ - 936, /* 199 */ - 932, /* 200 */ - 949, /* 201 */ - 950, /* 202 */ - 936, /* 203 */ - 874, /* 204 */ - 874, /* 205 */ - 874, /* 206 */ - 0, /* 207 */ - 0, /* 208 */ - 0, /* 209 */ - 1252, /* 210 */ - 1252, /* 211 */ - 1252, /* 212 */ - 1252, /* 213 */ - 1252, /* 214 */ - 1252, /* 215 */ - 1252, /* 216 */ - 1252, /* 217 */ - 0, /* 218 */ - 0, /* 219 */ - 0, /* 220 */ - 0, /* 221 */ - 0, /* 222 */ - 0, /* 223 */ - 0, /* 224 */ - 0, /* 225 */ - 0, /* 226 */ - 0, /* 227 */ - 0, /* 228 */ - 0, /* 229 */ - 0, /* 230 */ - 0, /* 231 */ - 0, /* 232 */ - 0, /* 233 */ - 0, /* 234 */ - 0, /* 235 */ - 0, /* 236 */ - 0, /* 237 */ - 0, /* 238 */ - 0, /* 239 */ - 0, /* 240 */ - 0, /* 241 */ - 0, /* 242 */ - 0, /* 243 */ - 0, /* 244 */ - 0, /* 245 */ - 0, /* 246 */ - 0, /* 247 */ - 0, /* 248 */ - 0, /* 249 */ - 0, /* 250 */ - 0, /* 251 */ - 0, /* 252 */ - 0, /* 253 */ - 0, /* 254 */ - 0, /* 255 */ - }; - - internal enum UDTFormatType - { - Native = 1, - UserDefined = 2 - } - - internal enum TransactionManagerRequestType - { - GetDTCAddress = 0, - Propagate = 1, - Begin = 5, - Promote = 6, - Commit = 7, - Rollback = 8, - Save = 9 - }; - - internal enum TransactionManagerIsolationLevel - { - Unspecified = 0x00, - ReadUncommitted = 0x01, - ReadCommitted = 0x02, - RepeatableRead = 0x03, - Serializable = 0x04, - Snapshot = 0x05 - } - - internal enum GenericType - { - MultiSet = 131, - }; - - // Date, Time, DateTime2, DateTimeOffset specific constants - internal static readonly Int64[] TICKS_FROM_SCALE = { - 10000000, - 1000000, - 100000, - 10000, - 1000, - 100, - 10, - 1, - }; - - internal const int MAX_TIME_SCALE = 7; // Maximum scale for time-related types - internal const int MAX_TIME_LENGTH = 5; // Maximum length for time - internal const int MAX_DATETIME2_LENGTH = 8; // Maximum length for datetime2 - internal const int WHIDBEY_DATE_LENGTH = 10; - internal static readonly int[] WHIDBEY_TIME_LENGTH = { 8, 10, 11, 12, 13, 14, 15, 16 }; - internal static readonly int[] WHIDBEY_DATETIME2_LENGTH = { 19, 21, 22, 23, 24, 25, 26, 27 }; - internal static readonly int[] WHIDBEY_DATETIMEOFFSET_LENGTH = { 26, 28, 29, 30, 31, 32, 33, 34 }; - - internal enum FedAuthInfoId : byte - { - Stsurl = 0x01, // FedAuthInfoData is token endpoint URL from which to acquire fed auth token - Spn = 0x02, // FedAuthInfoData is the SPN to use for acquiring fed auth token - } - - // Data Classification constants - internal const byte DATA_CLASSIFICATION_NOT_ENABLED = 0x00; - internal const byte DATA_CLASSIFICATION_VERSION_WITHOUT_RANK_SUPPORT = 0x01; - internal const byte DATA_CLASSIFICATION_VERSION_MAX_SUPPORTED = 0x02; - - // TCE Related constants - internal const byte MAX_SUPPORTED_TCE_VERSION = 0x03; // max version - internal const byte MIN_TCE_VERSION_WITH_ENCLAVE_SUPPORT = 0x02; // min version with enclave support - internal const ushort MAX_TCE_CIPHERINFO_SIZE = 2048; // max size of cipherinfo blob - internal const long MAX_TCE_CIPHERTEXT_SIZE = 2147483648; // max size of encrypted blob- currently 2GB. - internal const byte CustomCipherAlgorithmId = 0; // Id used for custom encryption algorithm. - - internal const int AEAD_AES_256_CBC_HMAC_SHA256 = 2; - internal const string ENCLAVE_TYPE_VBS = "VBS"; - internal const string ENCLAVE_TYPE_SGX = "SGX"; -#if ENCLAVE_SIMULATOR - internal const string ENCLAVE_TYPE_SIMULATOR = "SIMULATOR"; -#endif - // TCE Param names for exec handling - internal const string TCE_PARAM_CIPHERTEXT = "cipherText"; - internal const string TCE_PARAM_CIPHER_ALGORITHM_ID = "cipherAlgorithmId"; - internal const string TCE_PARAM_COLUMNENCRYPTION_KEY = "columnEncryptionKey"; - internal const string TCE_PARAM_ENCRYPTION_ALGORITHM = "encryptionAlgorithm"; - internal const string TCE_PARAM_ENCRYPTIONTYPE = "encryptionType"; - internal const string TCE_PARAM_ENCRYPTIONKEY = "encryptionKey"; - internal const string TCE_PARAM_MASTERKEY_PATH = "masterKeyPath"; - internal const string TCE_PARAM_ENCRYPTED_CEK = "encryptedColumnEncryptionKey"; - internal const string TCE_PARAM_CLIENT_KEYSTORE_PROVIDERS = "clientKeyStoreProviders"; - internal const string TCE_PARAM_FORCE_COLUMN_ENCRYPTION = "ForceColumnEncryption(true)"; - } - - internal enum ParsingErrorState - { - Undefined = 0, - FedAuthInfoLengthTooShortForCountOfInfoIds = 1, - FedAuthInfoLengthTooShortForData = 2, - FedAuthInfoFailedToReadCountOfInfoIds = 3, - FedAuthInfoFailedToReadTokenStream = 4, - FedAuthInfoInvalidOffset = 5, - FedAuthInfoFailedToReadData = 6, - FedAuthInfoDataNotUnicode = 7, - FedAuthInfoDoesNotContainStsurlAndSpn = 8, - FedAuthInfoNotReceived = 9, - FedAuthNotAcknowledged = 10, - FedAuthFeatureAckContainsExtraData = 11, - FedAuthFeatureAckUnknownLibraryType = 12, - UnrequestedFeatureAckReceived = 13, - UnknownFeatureAck = 14, - InvalidTdsTokenReceived = 15, - SessionStateLengthTooShort = 16, - SessionStateInvalidStatus = 17, - CorruptedTdsStream = 18, - ProcessSniPacketFailed = 19, - FedAuthRequiredPreLoginResponseInvalidValue = 20, - TceUnknownVersion = 21, - TceInvalidVersion = 22, - TceInvalidOrdinalIntoCipherInfoTable = 23, - DataClassificationInvalidVersion = 24, - DataClassificationNotExpected = 25, - DataClassificationInvalidLabelIndex = 26, - DataClassificationInvalidInformationTypeIndex = 27 - } - - internal enum SniContext - { - Undefined = 0, - Snix_Connect, - Snix_PreLoginBeforeSuccessfullWrite, - Snix_PreLogin, - Snix_LoginSspi, - Snix_ProcessSspi, - Snix_Login, - Snix_EnableMars, - Snix_AutoEnlist, - Snix_GetMarsSession, - Snix_Execute, - Snix_Read, - Snix_Close, - Snix_SendRows, - } - - /// - public enum SqlConnectionColumnEncryptionSetting - { - /// - Disabled = 0, - - /// - Enabled, - } - - /// - [Flags] - public enum SqlConnectionOverrides - { - /// - None = 0, - /// - OpenWithoutRetry = 1, - } - - /// - public enum SqlCommandColumnEncryptionSetting - { - /// - UseConnectionSetting = 0, - - /// - Enabled, - - /// - ResultSetOnly, - - /// - Disabled, - } - - /// - public enum SqlConnectionAttestationProtocol - { - /// - NotSpecified = 0, - - /// - AAS = 1, - -#if ENCLAVE_SIMULATOR - /// - SIM = 2, -#endif - - /// - HGS = 3 - } - - /// - public enum SqlConnectionIPAddressPreference - { - /// - IPv4First = 0, // default - - /// - IPv6First = 1, - - /// - UsePlatformDefault = 2 - } - - /// - public enum SqlAuthenticationMethod - { - /// - NotSpecified = 0, - - /// - SqlPassword, - - /// - ActiveDirectoryPassword, - - /// - ActiveDirectoryIntegrated, - - /// - ActiveDirectoryInteractive, - - /// - ActiveDirectoryServicePrincipal, - - /// - ActiveDirectoryDeviceCodeFlow, - - /// - ActiveDirectoryManagedIdentity, - - /// - ActiveDirectoryMSI, - - /// - ActiveDirectoryDefault, -#if ADONET_CERT_AUTH - SqlCertificate -#endif - } - // This enum indicates the state of TransparentNetworkIPResolution - // The first attempt when TNIR is on should be sequential. If the first attempt failes next attempts should be parallel. - internal enum TransparentNetworkResolutionState - { - DisabledMode = 0, - SequentialMode, - ParallelMode - }; - - internal class ActiveDirectoryAuthentication - { - internal const string AdoClientId = "2fd908ad-0664-4344-b9be-cd3e8b574c38"; - internal const string MSALGetAccessTokenFunctionName = "AcquireToken"; - } - - // Fields in the first resultset of "sp_describe_parameter_encryption". - // We expect the server to return the fields in the resultset in the same order as mentioned below. - // If the server changes the below order, then transparent parameter encryption will break. - internal enum DescribeParameterEncryptionResultSet1 - { - KeyOrdinal = 0, - DbId, - KeyId, - KeyVersion, - KeyMdVersion, - EncryptedKey, - ProviderName, - KeyPath, - KeyEncryptionAlgorithm, - IsRequestedByEnclave, - KeySignature, - } - - // Fields in the second resultset of "sp_describe_parameter_encryption" - // We expect the server to return the fields in the resultset in the same order as mentioned below. - // If the server changes the below order, then transparent parameter encryption will break. - internal enum DescribeParameterEncryptionResultSet2 - { - ParameterOrdinal = 0, - ParameterName, - ColumnEncryptionAlgorithm, - ColumnEncryptionType, - ColumnEncryptionKeyOrdinal, - NormalizationRuleVersion, - } - - // Fields in the third resultset of "sp_describe_parameter_encryption". - // We expect the server to return the fields in the resultset in the same order as mentioned below. - // If the server changes the below order, then transparent parameter encryption will break. - internal enum DescribeParameterEncryptionResultSet3 - { - AttestationInfo = 0, - } -} diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsEnums.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsEnums.cs similarity index 100% rename from src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsEnums.cs rename to src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsEnums.cs From 321b8abd705c3b522abe7b3bbc0b3178c953f681 Mon Sep 17 00:00:00 2001 From: Lawrence LCI Date: Thu, 21 Oct 2021 08:47:50 -0700 Subject: [PATCH 03/13] Fix compiler error due to updated relative path to the documentation and fix netfx build due to typo in enum --- .../src/Microsoft/Data/SqlClient/TdsParser.cs | 2 +- .../src/Microsoft/Data/SqlClient/TdsEnums.cs | 62 +++++++++---------- 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs index 56ff3c94c6..233aec019d 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs @@ -644,7 +644,7 @@ internal void Connect(ServerInfo serverInfo, serverInfo.ResolvedServerName : serverInfo.PreRoutingServerName); } _state = TdsParserState.OpenNotLoggedIn; - _physicalStateObj.SniContext = SniContext.Snix_PreLoginBeforeSuccessfullWrite; // SQL BU DT 376766 + _physicalStateObj.SniContext = SniContext.Snix_PreLoginBeforeSuccessfulWrite; // SQL BU DT 376766 _physicalStateObj.TimeoutTime = timerExpire; bool marsCapable = false; diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsEnums.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsEnums.cs index 9ea9fa2d38..fca1a6caf2 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsEnums.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsEnums.cs @@ -1101,105 +1101,105 @@ internal enum ParsingErrorState DataClassificationInvalidInformationTypeIndex = 27 } - /// + /// public enum SqlConnectionAttestationProtocol { - /// + /// NotSpecified = 0, - /// + /// AAS = 1, #if ENCLAVE_SIMULATOR - /// + /// SIM = 2, #endif - /// + /// HGS = 3 } - /// + /// public enum SqlConnectionIPAddressPreference { - /// + /// IPv4First = 0, // default - /// + /// IPv6First = 1, - /// + /// UsePlatformDefault = 2 } - /// + /// public enum SqlConnectionColumnEncryptionSetting { - /// + /// Disabled = 0, - /// + /// Enabled, } - /// + /// [Flags] public enum SqlConnectionOverrides { - /// + /// None = 0, - /// + /// OpenWithoutRetry = 1, } - /// + /// public enum SqlCommandColumnEncryptionSetting { - /// + /// UseConnectionSetting = 0, - /// + /// Enabled, - /// + /// ResultSetOnly, - /// + /// Disabled, } - /// + /// public enum SqlAuthenticationMethod { - /// + /// NotSpecified = 0, - /// + /// SqlPassword, - /// + /// ActiveDirectoryPassword, - /// + /// ActiveDirectoryIntegrated, - /// + /// ActiveDirectoryInteractive, - /// + /// ActiveDirectoryServicePrincipal, - /// + /// ActiveDirectoryDeviceCodeFlow, - /// + /// ActiveDirectoryManagedIdentity, - /// + /// ActiveDirectoryMSI, - /// + /// ActiveDirectoryDefault, #if ADONET_CERT_AUTH && NETFRAMEWORK SqlCertificate From c03f6fdc7d0331f11b7c9f972e2c2160a5e7da86 Mon Sep 17 00:00:00 2001 From: Lawrence LCI Date: Thu, 21 Oct 2021 08:50:34 -0700 Subject: [PATCH 04/13] Update file to conform to coding style cleaning up IDE0090 --- .../src/Microsoft/Data/SqlClient/TdsEnums.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsEnums.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsEnums.cs index fca1a6caf2..0ee8e617f3 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsEnums.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsEnums.cs @@ -17,8 +17,8 @@ internal static class TdsEnums public const string SQL_PROVIDER_NAME = Common.DbConnectionStringDefaults.ApplicationName; - public static readonly decimal SQL_SMALL_MONEY_MIN = new decimal(-214748.3648); - public static readonly decimal SQL_SMALL_MONEY_MAX = new decimal(214748.3647); + public static readonly decimal SQL_SMALL_MONEY_MIN = new(-214748.3648); + public static readonly decimal SQL_SMALL_MONEY_MAX = new(214748.3647); #if NETFRAMEWORK // sql debugging constants, sdci is the structure passed in From b1d37209c76254d795518c6e9053b202197bb25d Mon Sep 17 00:00:00 2001 From: Lawrence LCI Date: Mon, 25 Oct 2021 11:21:38 -0700 Subject: [PATCH 05/13] Add test coverage to SqlCollation for FirstSupportedCollationVersion and to verify out of range for LocaleId --- .../tests/FunctionalTests/SqlParameterTest.cs | 63 +++++++++++++++++-- 1 file changed, 59 insertions(+), 4 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlParameterTest.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlParameterTest.cs index 344a578b4a..e35a34f939 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlParameterTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlParameterTest.cs @@ -659,13 +659,68 @@ public void InferType_DateTimeOffset() Assert.Equal(DbType.DateTimeOffset, param.DbType); } + [Theory] + [InlineData(15)] + [InlineData(1044)] + [InlineData(1047)] + [InlineData(1056)] + [InlineData(1065)] + [InlineData(1068)] + [InlineData(1070)] + [InlineData(1071)] + [InlineData(1081)] + [InlineData(1082)] + [InlineData(1083)] + [InlineData(1087)] + [InlineData(1090)] + [InlineData(1091)] + [InlineData(1092)] + [InlineData(1093)] + [InlineData(1101)] + [InlineData(1105)] + [InlineData(1106)] + [InlineData(1107)] + [InlineData(1108)] + [InlineData(1114)] + [InlineData(1121)] + [InlineData(1122)] + [InlineData(1123)] + [InlineData(1125)] + [InlineData(1133)] + [InlineData(1146)] + [InlineData(1148)] + [InlineData(1150)] + [InlineData(1152)] + [InlineData(1153)] + [InlineData(1155)] + [InlineData(1157)] + [InlineData(1164)] + [InlineData(2074)] + [InlineData(2092)] + [InlineData(2107)] + [InlineData(2143)] + [InlineData(3076)] + [InlineData(3098)] + [InlineData(5124)] + [InlineData(5146)] + [InlineData(8218)] + public void LocaleId(int lcid) + { + // To verify all the cases in SqlCollation.FirstSupportedCollationVersion + SqlParameter parameter = new SqlParameter(); + Assert.Equal(0, parameter.LocaleId); + parameter.LocaleId = lcid; + Assert.Equal(parameter.LocaleId, lcid); + } + [Fact] - public void LocaleId() + public void LocaleIdOutOfRange_Throws() { SqlParameter parameter = new SqlParameter(); - Assert.Equal(0, parameter.LocaleId); - parameter.LocaleId = 15; - Assert.Equal(15, parameter.LocaleId); + ArgumentOutOfRangeException ex = Assert.Throws(() => { parameter.LocaleId = -1; }); + Assert.NotNull(ex); + Assert.NotNull(ex.ParamName); + Assert.Contains("LocaleId", ex.ParamName, StringComparison.OrdinalIgnoreCase); } [Fact] From 02a65c67c21db9297c4f66ea9939173a4f5826a8 Mon Sep 17 00:00:00 2001 From: Lawrence LCI Date: Mon, 25 Oct 2021 20:20:21 -0700 Subject: [PATCH 06/13] Add tests to SqlConnectionStringBuilder to all properties that throws an exception --- .../SqlConnectionStringBuilderTest.cs | 190 ++++++++++++++++++ 1 file changed, 190 insertions(+) diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionStringBuilderTest.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionStringBuilderTest.cs index bf08250e83..1252cdf3f0 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionStringBuilderTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionStringBuilderTest.cs @@ -101,6 +101,196 @@ public void ConnectionStringTestsNetFx(string connectionString) ExecuteConnectionStringTests(connectionString); } + [Fact] + public void SetInvalidApplicationIntent_Throws() + { + SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(); + + ApplicationIntent invalid = (ApplicationIntent)Enum.GetValues(typeof(ApplicationIntent)).Length + 1; + ArgumentOutOfRangeException ex = Assert.Throws(() => builder.ApplicationIntent = invalid); + Assert.NotNull(ex); + Assert.NotEmpty(ex.Message); + Assert.Contains("ApplicationIntent", ex.Message, StringComparison.OrdinalIgnoreCase); + } + + [Fact] + public void SetInvalidAttestationProtocol_Throws() + { + SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(); + + SqlConnectionAttestationProtocol invalid = (SqlConnectionAttestationProtocol)Enum.GetValues(typeof(SqlConnectionAttestationProtocol)).Length + 1; + ArgumentOutOfRangeException ex = Assert.Throws(() => builder.AttestationProtocol = invalid); + Assert.NotNull(ex); + Assert.NotEmpty(ex.Message); + Assert.Contains("SqlConnectionAttestationProtocol", ex.Message, StringComparison.OrdinalIgnoreCase); + } + + [Fact] + public void SetInvalidAuthentication_Throws() + { + SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(); + + SqlAuthenticationMethod invalid = (SqlAuthenticationMethod)Enum.GetValues(typeof(SqlAuthenticationMethod)).Length + 1; + ArgumentOutOfRangeException ex = Assert.Throws(() => builder.Authentication = invalid); + Assert.NotNull(ex); + Assert.NotEmpty(ex.Message); + Assert.Contains("SqlAuthenticationMethod", ex.Message, StringComparison.OrdinalIgnoreCase); + } + + [Fact] + public void SetInvalidColumnEncryptionSetting_Throws() + { + SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(); + + SqlConnectionColumnEncryptionSetting invalid = (SqlConnectionColumnEncryptionSetting)Enum.GetValues(typeof(SqlConnectionColumnEncryptionSetting)).Length + 1; + ArgumentOutOfRangeException ex = Assert.Throws(() => builder.ColumnEncryptionSetting = invalid); + Assert.NotNull(ex); + Assert.NotEmpty(ex.Message); + Assert.Contains("SqlConnectionColumnEncryptionSetting", ex.Message, StringComparison.OrdinalIgnoreCase); + } + + [Fact] + public void SetInvalidConnectTimeout_Throws() + { + SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(); + + ArgumentException ex = Assert.Throws(() => builder.ConnectTimeout = -1); + Assert.NotNull(ex); + Assert.NotEmpty(ex.Message); + Assert.Contains("connect timeout", ex.Message, StringComparison.OrdinalIgnoreCase); + } + + [Fact] + public void SetInvalidCommandTimeout_Throws() + { + SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(); + + ArgumentException ex = Assert.Throws(() => builder.CommandTimeout = -1); + Assert.NotNull(ex); + Assert.NotEmpty(ex.Message); + Assert.Contains("command timeout", ex.Message, StringComparison.OrdinalIgnoreCase); + } + + [Theory] + [InlineData(-1)] + [InlineData(256)] + public void SetInvalidConnectRetryCount_Throws(int invalid) + { + SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(); + + ArgumentException ex = Assert.Throws(() => builder.ConnectRetryCount = invalid); + Assert.NotNull(ex); + Assert.NotEmpty(ex.Message); + Assert.Contains("connect retry count", ex.Message, StringComparison.OrdinalIgnoreCase); + } + + [Theory] + [InlineData(-1)] + [InlineData(256)] + public void SetInvalidConnectRetryInterval_Throws(int invalid) + { + SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(); + + ArgumentException ex = Assert.Throws(() => builder.ConnectRetryInterval = invalid); + Assert.NotNull(ex); + Assert.NotEmpty(ex.Message); + Assert.Contains("connect retry interval", ex.Message, StringComparison.OrdinalIgnoreCase); + } + + [Fact] + public void SetInvalidIPAddressPreference_Throws() + { + SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(); + + SqlConnectionIPAddressPreference invalid = (SqlConnectionIPAddressPreference)Enum.GetValues(typeof(SqlConnectionIPAddressPreference)).Length + 1; + ArgumentOutOfRangeException ex = Assert.Throws(() => builder.IPAddressPreference = invalid); + Assert.NotNull(ex); + Assert.NotEmpty(ex.Message); + Assert.Contains("SqlConnectionIPAddressPreference", ex.Message, StringComparison.OrdinalIgnoreCase); + } + + [Fact] + public void SetInvalidPoolBlockingPeriod_Throws() + { + SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(); + + PoolBlockingPeriod invalid = (PoolBlockingPeriod)Enum.GetValues(typeof(PoolBlockingPeriod)).Length + 1; + ArgumentOutOfRangeException ex = Assert.Throws(() => builder.PoolBlockingPeriod = invalid); + Assert.NotNull(ex); + Assert.NotEmpty(ex.Message); + Assert.Contains("PoolBlockingPeriod", ex.Message, StringComparison.OrdinalIgnoreCase); + } + + [Fact] + public void SetInvalidLoadBalanceTimeout_Throws() + { + SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(); + + ArgumentException ex = Assert.Throws(() => builder.LoadBalanceTimeout = -1); + Assert.NotNull(ex); + Assert.NotEmpty(ex.Message); + Assert.Contains("load balance timeout", ex.Message, StringComparison.OrdinalIgnoreCase); + } + + [Fact] + public void SetInvalidMaxPoolSize_Throws() + { + SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(); + + ArgumentException ex = Assert.Throws(() => builder.MaxPoolSize = 0); + Assert.NotNull(ex); + Assert.NotEmpty(ex.Message); + Assert.Contains("max pool size", ex.Message, StringComparison.OrdinalIgnoreCase); + } + + [Fact] + public void SetInvalidMinPoolSize_Throws() + { + SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(); + + ArgumentException ex = Assert.Throws(() => builder.MinPoolSize = -1); + Assert.NotNull(ex); + Assert.NotEmpty(ex.Message); + Assert.Contains("min pool size", ex.Message, StringComparison.OrdinalIgnoreCase); + } + + [Theory] + [InlineData(0)] + [InlineData(511)] + [InlineData(32769)] + [InlineData(int.MaxValue)] + public void SetInvalidPacketSize_Throws(int invalid) + { + SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(); + + ArgumentException ex = Assert.Throws(() => builder.PacketSize = invalid); + Assert.NotNull(ex); + Assert.NotEmpty(ex.Message); + Assert.Contains("packet size", ex.Message, StringComparison.OrdinalIgnoreCase); + } + + [Theory] + [InlineData("AttachDBFilename","somefile.db")] + public void SetKeyword(string keyword, string value) + { + SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(); + builder[keyword] = value; + Assert.Equal(builder[keyword], value); + } + + [Fact] + public void SetNotSupportedKeyword_Throws() + { + // We may want to remove the unreachable code path for default in the GetIndex(keyword) method already throws UnsupportedKeyword + // so default: throw UnsupportedKeyword(keyword) is never reached unless it's a supported keyword, but it's not handled in the switch case. + + SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(); + ArgumentException ex = Assert.Throws(() => builder["NotSupported"] = "not important"); + Assert.NotNull(ex); + Assert.NotEmpty(ex.Message); + Assert.Contains("not supported", ex.Message, StringComparison.OrdinalIgnoreCase); + } + [Fact] public void UnexpectedKeywordRetrieval() { From 16c0a64070549d91b2069ed475aa3132e03176f9 Mon Sep 17 00:00:00 2001 From: Lawrence LCI Date: Tue, 26 Oct 2021 13:20:13 -0700 Subject: [PATCH 07/13] Add a test cases for SqlClientLogger for code coverage --- .../Microsoft.Data.SqlClient.Tests.csproj | 1 + .../FunctionalTests/SqlClientLoggerTest.cs | 40 +++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlClientLoggerTest.cs diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.Tests.csproj b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.Tests.csproj index 15032653d6..49ae675022 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.Tests.csproj +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.Tests.csproj @@ -28,6 +28,7 @@ + diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlClientLoggerTest.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlClientLoggerTest.cs new file mode 100644 index 0000000000..3617882b42 --- /dev/null +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlClientLoggerTest.cs @@ -0,0 +1,40 @@ +// 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 Xunit; + +namespace Microsoft.Data.SqlClient.Tests +{ + public class SqlClientLoggerTest + { + [Fact] + public void LogWarning() + { + // There is not much to test here but to add the code coverage. + SqlClientLogger logger = new(); + logger.LogWarning("test type", "test method", "test message"); + } + + [Fact] + public void LogAssert() + { + SqlClientLogger logger = new(); + logger.LogAssert(true, "test type", "test method", "test message"); + } + + [Fact] + public void LogError() + { + SqlClientLogger logger = new(); + logger.LogError("test type", "test method", "test message"); + } + + [Fact] + public void LogInfo() + { + SqlClientLogger logger = new(); + logger.LogInfo("test type", "test method", "test message"); + } + } +} From 60172e485db3b72abd9cc1d401bf4202c32caf0a Mon Sep 17 00:00:00 2001 From: Lawrence LCI Date: Tue, 26 Oct 2021 16:44:22 -0700 Subject: [PATCH 08/13] Add code coverage for SqlClientFactory covering CreateDataSourceEnumerator and GetService for netfx and CreateCommandBuilder for both --- .../FunctionalTests/SqlClientFactoryTest.cs | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlClientFactoryTest.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlClientFactoryTest.cs index 15b7222df9..f0e8d39173 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlClientFactoryTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlClientFactoryTest.cs @@ -3,6 +3,8 @@ // See the LICENSE file in the project root for more information. using System; +using System.Data.Sql; +using System.Reflection; using Xunit; namespace Microsoft.Data.SqlClient.Tests @@ -20,6 +22,7 @@ public void InstanceTest() public static readonly object[][] FactoryMethodTestData = { new object[] { new Func(SqlClientFactory.Instance.CreateCommand), typeof(SqlCommand) }, + new object[] { new Func(SqlClientFactory.Instance.CreateCommandBuilder), typeof(SqlCommandBuilder) }, new object[] { new Func(SqlClientFactory.Instance.CreateConnection), typeof(SqlConnection) }, new object[] { new Func(SqlClientFactory.Instance.CreateConnectionStringBuilder), typeof(SqlConnectionStringBuilder) }, new object[] { new Func(SqlClientFactory.Instance.CreateDataAdapter), typeof(SqlDataAdapter) }, @@ -40,5 +43,26 @@ public void FactoryMethodTest(Func factory, Type expectedType) Assert.NotSame(value1, value2); } + +#if NETFRAMEWORK + [Fact] + public void FactoryCreateDataSourceEnumerator() + { + // Unable to cover the in the FactoryMethodTest because the SqlDataSourceEnumerator is a singleton so, it's always the same. + object instance = SqlClientFactory.Instance.CreateDataSourceEnumerator(); + // SqlDataSourceEnumerator is not available for .NET core 3.1 and above, so the type check is only for .NET Framework. + Assert.IsType(instance); + Assert.NotNull(instance); + } + + [Fact] + public void FactoryGetService() + { + Type type = typeof(SqlClientFactory); + MethodInfo method = type.GetMethod("System.IServiceProvider.GetService", BindingFlags.NonPublic | BindingFlags.Instance); + object res = method.Invoke(SqlClientFactory.Instance, new object[] { null }); + Assert.Null(res); + } +#endif } } From 296049b2e14b19cb29f668b3235c204f5e3e2399 Mon Sep 17 00:00:00 2001 From: Lawrence LCI Date: Wed, 27 Oct 2021 11:00:21 -0700 Subject: [PATCH 09/13] Add tests to SqlParameterCollection for code coverage --- .../Microsoft.Data.SqlClient.Tests.csproj | 1 + .../SqlParameterCollectionTest.cs | 118 ++++++++++++++++++ 2 files changed, 119 insertions(+) create mode 100644 src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlParameterCollectionTest.cs diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.Tests.csproj b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.Tests.csproj index 49ae675022..fa4b67aab3 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.Tests.csproj +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.Tests.csproj @@ -48,6 +48,7 @@ + diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlParameterCollectionTest.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlParameterCollectionTest.cs new file mode 100644 index 0000000000..a67e642704 --- /dev/null +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlParameterCollectionTest.cs @@ -0,0 +1,118 @@ +// 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; +using Xunit; + +namespace Microsoft.Data.SqlClient.Tests +{ + public class SqlParameterCollectionTest + { + [Fact] + public void CollectionAddInvalidRange_Throws() + { + SqlCommand command = new SqlCommand(); + SqlParameterCollection collection = command.Parameters; + + Array invalid = null; + ArgumentNullException ex = Assert.Throws(() => collection.AddRange(invalid)); + Assert.NotNull(ex); + } + + [Fact] + public void CollectionAddRange() + { + SqlCommand command = new SqlCommand(); + SqlParameterCollection collection = command.Parameters; + Array sqlParameters = new SqlParameter[] { new("Test1", 1), new("Test2", 2) }; + + collection.AddRange(sqlParameters); + + Assert.Equal(2, collection.Count); + Assert.Equal((SqlParameter)sqlParameters.GetValue(0), collection[0]); + Assert.Equal((SqlParameter)sqlParameters.GetValue(1), collection[1]); + } + + [Fact] + public void CollectionCheckNameInvalid_Throws() + { + SqlCommand command = new SqlCommand(); + SqlParameterCollection collection = command.Parameters; + collection.Add(new SqlParameter("Test1", 1)); + collection.Add(new SqlParameter("Test2", 2)); + + IndexOutOfRangeException ex = Assert.Throws(() => collection.RemoveAt("DoesNotExist")); + Assert.NotNull(ex); + Assert.NotEmpty(ex.Message); + Assert.Contains("DoesNotExist", ex.Message, StringComparison.OrdinalIgnoreCase); + } + + [Fact] + public void ConnectionCopyTo() + { + SqlCommand command = new SqlCommand(); + SqlParameterCollection collection = command.Parameters; + collection.Add(new SqlParameter("Test1", 1)); + collection.Add(new SqlParameter("Test2", 2)); + + SqlParameter[] copied = new SqlParameter[2]; + collection.CopyTo(copied, 0); + + Assert.Equal(collection[0], copied[0]); + Assert.Equal(collection[1], copied[1]); + } + + [Fact] + public void CollectionIndexOfCaseInsensitive() + { + SqlCommand command = new SqlCommand(); + SqlParameterCollection collection = command.Parameters; + collection.Add(new SqlParameter("TEST1", 1)); + collection.Add(new SqlParameter("Test2", 2)); + collection.Add(new SqlParameter("Test3", 3)); + + int index = collection.IndexOf("test1"); + Assert.Equal(0, index); + } + + [Fact] + public void CollectionRemove() + { + SqlCommand command = new SqlCommand(); + SqlParameterCollection collection = command.Parameters; + SqlParameter parameter1 = new SqlParameter("Test1", 1); + collection.Add(parameter1); + collection.Add(new SqlParameter("Test2", 2)); + collection.Add(new SqlParameter("Test3", 3)); + + collection.Remove(parameter1); + Assert.Equal(2, collection.Count); + Assert.Equal("Test2", collection[0].ParameterName); + } + + [Fact] + public void CollectionSetParameter() + { + SqlCommand command = new SqlCommand(); + SqlParameterCollection collection = command.Parameters; + collection.Add(new SqlParameter("TestOne", 0)); + collection.Add(new SqlParameter("Test2", 2)); + collection.Add(new SqlParameter("Test3", 3)); + + collection[0] = new SqlParameter("Test1", 1); + Assert.Equal("Test1", collection[0].ParameterName); + Assert.Equal(1, (int)collection[0].Value); + } + + [Fact] + public void CollectionValiateNull_Throws() + { + SqlCommand command = new SqlCommand(); + SqlParameterCollection collection = command.Parameters; + + ArgumentNullException ex = Assert.Throws(() => collection.Add(null)); + Assert.NotNull(ex); + } + } +} From 2d57ffe9e3214b3e2fef6282c31fb8fd903500eb Mon Sep 17 00:00:00 2001 From: Lawrence LCI Date: Fri, 29 Oct 2021 16:33:18 -0700 Subject: [PATCH 10/13] Add missing code coverage to SqlCommandSet --- .../Microsoft.Data.SqlClient.Tests.csproj | 1 + .../FunctionalTests/SqlCommandSetTest.cs | 184 ++++++++++++++++++ 2 files changed, 185 insertions(+) create mode 100644 src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlCommandSetTest.cs diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.Tests.csproj b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.Tests.csproj index fa4b67aab3..97336390d6 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.Tests.csproj +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.Tests.csproj @@ -29,6 +29,7 @@ + diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlCommandSetTest.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlCommandSetTest.cs new file mode 100644 index 0000000000..b0c357e19b --- /dev/null +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlCommandSetTest.cs @@ -0,0 +1,184 @@ +using System; +using System.Data; +using System.Reflection; +using Xunit; + +namespace Microsoft.Data.SqlClient.Tests +{ + public class SqlCommandSetTest + { + private static Assembly mds = Assembly.GetAssembly(typeof(SqlConnection)); + + [Theory] + [InlineData("BatchCommand")] + [InlineData("CommandList")] + public void GetDisposedProperty_Throws(string propertyName) + { + var cmdSet = CreateInstance(); + CallMethod(cmdSet, "Dispose"); + Exception ex = GetProperty_Throws(cmdSet, propertyName); + VerifyException(ex, "disposed"); + } + + [Fact] + public void AppendCommandWithEmptyString_Throws() + { + var cmdSet = CreateInstance(); + SqlCommand cmd = new SqlCommand(""); + Exception ex = CallMethod_Throws(cmdSet, "Append", cmd); + VerifyException(ex, "CommandText property has not been initialized"); + } + + [Theory] + [InlineData(CommandType.TableDirect)] + [InlineData((CommandType)5)] + public void AppendBadCommandType_Throws(CommandType commandType) + { + var cmdSet = CreateInstance(); + SqlCommand cmd = GenerateBadCommand(commandType); + Exception ex = CallMethod_Throws(cmdSet, "Append", cmd); + VerifyException(ex, "CommandType"); + } + + [Fact] + public void AppendBadParameterName_Throws() + { + var cmdSet = CreateInstance(); + SqlCommand cmd = new SqlCommand("Test"); + cmd.CommandType = CommandType.Text; + cmd.Parameters.Add(new SqlParameter("Test1;=", "1")); + Exception ex = CallMethod_Throws(cmdSet, "Append", cmd); + VerifyException(ex, "not valid"); + } + + [Theory] + [InlineData(new byte[] { 1, 2, 3 })] + [InlineData(new char[] { '1', '2', '3' })] + public void AppendParameterArrayWithSize(object array) + { + var cmdSet = CreateInstance(); + SqlCommand cmd = new SqlCommand("Test"); + cmd.CommandType = CommandType.StoredProcedure; + SqlParameter parameter = new SqlParameter("@array", array); + parameter.Size = 2; + cmd.Parameters.Add(parameter); + CallMethod(cmdSet, "Append", cmd); + object p = CallMethod(cmdSet, "GetParameter", 0, 0); + SqlParameter result = p as SqlParameter; + Assert.NotNull(result); + Assert.Equal("@array", result.ParameterName); + Assert.Equal(2, result.Size); + } + + [Fact] + public void GetParameter() + { + var cmdSet = CreateInstance(); + SqlCommand cmd = new SqlCommand("Test"); + cmd.CommandType = CommandType.Text; + cmd.Parameters.Add(new SqlParameter("@text", "value")); + CallMethod(cmdSet, "Append", cmd); + object p = CallMethod(cmdSet, "GetParameter", 0, 0); + SqlParameter result = p as SqlParameter; + Assert.NotNull(result); + Assert.Equal("@text", result.ParameterName); + Assert.Equal("value", (string)result.Value); + } + + [Fact] + public void GetParameterCount() + { + var commandSetType = mds.GetType("Microsoft.Data.SqlClient.SqlCommandSet"); + var cmdSet = Activator.CreateInstance(commandSetType, true); + SqlCommand cmd = new SqlCommand("Test"); + cmd.CommandType = CommandType.Text; + cmd.Parameters.Add(new SqlParameter("@abc", "1")); + cmd.Parameters.Add(new SqlParameter("@test", "2")); + commandSetType.GetMethod("Append", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).Invoke(cmdSet, new object[] { cmd }); + int index = 0; + int count = (int)commandSetType.GetMethod("GetParameterCount", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).Invoke(cmdSet, new object[] { index }); + Assert.Equal(2, count); + } + + [Fact] + public void InvalidCommandBehaviorValidateCommandBehavior_Throws() + { + var cmdSet = CreateInstance(); + Exception ex = CallMethod_Throws(cmdSet, "ValidateCommandBehavior", "ExecuteNonQuery", (CommandBehavior)64); + VerifyException(ex, "CommandBehavior"); + } + + [Fact] + public void NotSupportedCommandBehaviorValidateCommandBehavior_Throws() + { + var cmdSet = CreateInstance(); + Exception ex = CallMethod_Throws(cmdSet, "ValidateCommandBehavior", "ExecuteNonQuery", CommandBehavior.KeyInfo); + VerifyException(ex, "not supported"); + } + + #region private methods + + private object CallMethod(object instance, string methodName, params object[] values) + { + var commandSetType = mds.GetType("Microsoft.Data.SqlClient.SqlCommandSet"); + object returnValue = commandSetType.GetMethod(methodName, System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).Invoke(instance, values); + return returnValue; + } + + private object CallMethod(object instance, string methodName) + { + var commandSetType = mds.GetType("Microsoft.Data.SqlClient.SqlCommandSet"); + object returnValue = commandSetType.GetMethod(methodName, System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).Invoke(instance, new object[] { }); + return returnValue; + } + + private Exception CallMethod_Throws(object instance, string methodName, params object[] values) + { + var commandSetType = mds.GetType("Microsoft.Data.SqlClient.SqlCommandSet"); + Exception ex = Assert.ThrowsAny(() => + { + commandSetType.GetMethod(methodName, System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).Invoke(instance, values); + }); + return ex; + } + + private object CreateInstance() + { + var commandSetType = mds.GetType("Microsoft.Data.SqlClient.SqlCommandSet"); + object cmdSet = Activator.CreateInstance(commandSetType, true); + return cmdSet; + } + + private Exception GetProperty_Throws(object instance, string propertyName) + { + var commandSetType = mds.GetType("Microsoft.Data.SqlClient.SqlCommandSet"); + var cmdSet = instance; + Exception ex = Assert.ThrowsAny(() => + { + commandSetType.GetProperty(propertyName, System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).GetGetMethod(true).Invoke(cmdSet, new object[] { }); + }); + + return ex; + } + + private SqlCommand GenerateBadCommand(CommandType cType) + { + SqlCommand cmd = new SqlCommand("Test"); + Type sqlCommandType = cmd.GetType(); + // There's validation done on the CommandType property, but we need to create one that avoids the check for the test case. + sqlCommandType.GetField("_commandType", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(cmd, cType); + + return cmd; + } + + private void VerifyException(Exception ex, string contains) + { + Assert.NotNull(ex); + Assert.IsType(ex.InnerException); + Assert.NotNull(ex.InnerException); + Assert.NotEmpty(ex.InnerException.Message); + Assert.Contains(contains, ex.InnerException.Message, StringComparison.OrdinalIgnoreCase); + } + #endregion + } +} From 8b5ee2132d20021334467c8e43fcb131420675a1 Mon Sep 17 00:00:00 2001 From: Johnny Pham Date: Wed, 17 Nov 2021 12:44:09 -0800 Subject: [PATCH 11/13] remove unnecessary asserts --- .../netfx/src/Microsoft.Data.SqlClient.csproj | 1 + .../FunctionalTests/SqlCommandSetTest.cs | 2 -- .../SqlConnectionStringBuilderTest.cs | 30 ------------------- .../SqlParameterCollectionTest.cs | 8 ++--- .../tests/FunctionalTests/SqlParameterTest.cs | 1 - 5 files changed, 3 insertions(+), 39 deletions(-) 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 df8e73b2d3..d6f95e6910 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj @@ -338,6 +338,7 @@ Microsoft\Data\SqlClient\SqlCommandBuilder.cs + Component Microsoft\Data\SqlClient\SqlCommandSet.cs diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlCommandSetTest.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlCommandSetTest.cs index b0c357e19b..1428bcc3e8 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlCommandSetTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlCommandSetTest.cs @@ -175,8 +175,6 @@ private void VerifyException(Exception ex, string contains) { Assert.NotNull(ex); Assert.IsType(ex.InnerException); - Assert.NotNull(ex.InnerException); - Assert.NotEmpty(ex.InnerException.Message); Assert.Contains(contains, ex.InnerException.Message, StringComparison.OrdinalIgnoreCase); } #endregion diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionStringBuilderTest.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionStringBuilderTest.cs index 1252cdf3f0..d80875af80 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionStringBuilderTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionStringBuilderTest.cs @@ -108,8 +108,6 @@ public void SetInvalidApplicationIntent_Throws() ApplicationIntent invalid = (ApplicationIntent)Enum.GetValues(typeof(ApplicationIntent)).Length + 1; ArgumentOutOfRangeException ex = Assert.Throws(() => builder.ApplicationIntent = invalid); - Assert.NotNull(ex); - Assert.NotEmpty(ex.Message); Assert.Contains("ApplicationIntent", ex.Message, StringComparison.OrdinalIgnoreCase); } @@ -120,8 +118,6 @@ public void SetInvalidAttestationProtocol_Throws() SqlConnectionAttestationProtocol invalid = (SqlConnectionAttestationProtocol)Enum.GetValues(typeof(SqlConnectionAttestationProtocol)).Length + 1; ArgumentOutOfRangeException ex = Assert.Throws(() => builder.AttestationProtocol = invalid); - Assert.NotNull(ex); - Assert.NotEmpty(ex.Message); Assert.Contains("SqlConnectionAttestationProtocol", ex.Message, StringComparison.OrdinalIgnoreCase); } @@ -132,8 +128,6 @@ public void SetInvalidAuthentication_Throws() SqlAuthenticationMethod invalid = (SqlAuthenticationMethod)Enum.GetValues(typeof(SqlAuthenticationMethod)).Length + 1; ArgumentOutOfRangeException ex = Assert.Throws(() => builder.Authentication = invalid); - Assert.NotNull(ex); - Assert.NotEmpty(ex.Message); Assert.Contains("SqlAuthenticationMethod", ex.Message, StringComparison.OrdinalIgnoreCase); } @@ -144,8 +138,6 @@ public void SetInvalidColumnEncryptionSetting_Throws() SqlConnectionColumnEncryptionSetting invalid = (SqlConnectionColumnEncryptionSetting)Enum.GetValues(typeof(SqlConnectionColumnEncryptionSetting)).Length + 1; ArgumentOutOfRangeException ex = Assert.Throws(() => builder.ColumnEncryptionSetting = invalid); - Assert.NotNull(ex); - Assert.NotEmpty(ex.Message); Assert.Contains("SqlConnectionColumnEncryptionSetting", ex.Message, StringComparison.OrdinalIgnoreCase); } @@ -155,8 +147,6 @@ public void SetInvalidConnectTimeout_Throws() SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(); ArgumentException ex = Assert.Throws(() => builder.ConnectTimeout = -1); - Assert.NotNull(ex); - Assert.NotEmpty(ex.Message); Assert.Contains("connect timeout", ex.Message, StringComparison.OrdinalIgnoreCase); } @@ -166,8 +156,6 @@ public void SetInvalidCommandTimeout_Throws() SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(); ArgumentException ex = Assert.Throws(() => builder.CommandTimeout = -1); - Assert.NotNull(ex); - Assert.NotEmpty(ex.Message); Assert.Contains("command timeout", ex.Message, StringComparison.OrdinalIgnoreCase); } @@ -179,8 +167,6 @@ public void SetInvalidConnectRetryCount_Throws(int invalid) SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(); ArgumentException ex = Assert.Throws(() => builder.ConnectRetryCount = invalid); - Assert.NotNull(ex); - Assert.NotEmpty(ex.Message); Assert.Contains("connect retry count", ex.Message, StringComparison.OrdinalIgnoreCase); } @@ -192,8 +178,6 @@ public void SetInvalidConnectRetryInterval_Throws(int invalid) SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(); ArgumentException ex = Assert.Throws(() => builder.ConnectRetryInterval = invalid); - Assert.NotNull(ex); - Assert.NotEmpty(ex.Message); Assert.Contains("connect retry interval", ex.Message, StringComparison.OrdinalIgnoreCase); } @@ -204,8 +188,6 @@ public void SetInvalidIPAddressPreference_Throws() SqlConnectionIPAddressPreference invalid = (SqlConnectionIPAddressPreference)Enum.GetValues(typeof(SqlConnectionIPAddressPreference)).Length + 1; ArgumentOutOfRangeException ex = Assert.Throws(() => builder.IPAddressPreference = invalid); - Assert.NotNull(ex); - Assert.NotEmpty(ex.Message); Assert.Contains("SqlConnectionIPAddressPreference", ex.Message, StringComparison.OrdinalIgnoreCase); } @@ -216,8 +198,6 @@ public void SetInvalidPoolBlockingPeriod_Throws() PoolBlockingPeriod invalid = (PoolBlockingPeriod)Enum.GetValues(typeof(PoolBlockingPeriod)).Length + 1; ArgumentOutOfRangeException ex = Assert.Throws(() => builder.PoolBlockingPeriod = invalid); - Assert.NotNull(ex); - Assert.NotEmpty(ex.Message); Assert.Contains("PoolBlockingPeriod", ex.Message, StringComparison.OrdinalIgnoreCase); } @@ -227,8 +207,6 @@ public void SetInvalidLoadBalanceTimeout_Throws() SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(); ArgumentException ex = Assert.Throws(() => builder.LoadBalanceTimeout = -1); - Assert.NotNull(ex); - Assert.NotEmpty(ex.Message); Assert.Contains("load balance timeout", ex.Message, StringComparison.OrdinalIgnoreCase); } @@ -238,8 +216,6 @@ public void SetInvalidMaxPoolSize_Throws() SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(); ArgumentException ex = Assert.Throws(() => builder.MaxPoolSize = 0); - Assert.NotNull(ex); - Assert.NotEmpty(ex.Message); Assert.Contains("max pool size", ex.Message, StringComparison.OrdinalIgnoreCase); } @@ -249,8 +225,6 @@ public void SetInvalidMinPoolSize_Throws() SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(); ArgumentException ex = Assert.Throws(() => builder.MinPoolSize = -1); - Assert.NotNull(ex); - Assert.NotEmpty(ex.Message); Assert.Contains("min pool size", ex.Message, StringComparison.OrdinalIgnoreCase); } @@ -264,8 +238,6 @@ public void SetInvalidPacketSize_Throws(int invalid) SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(); ArgumentException ex = Assert.Throws(() => builder.PacketSize = invalid); - Assert.NotNull(ex); - Assert.NotEmpty(ex.Message); Assert.Contains("packet size", ex.Message, StringComparison.OrdinalIgnoreCase); } @@ -286,8 +258,6 @@ public void SetNotSupportedKeyword_Throws() SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(); ArgumentException ex = Assert.Throws(() => builder["NotSupported"] = "not important"); - Assert.NotNull(ex); - Assert.NotEmpty(ex.Message); Assert.Contains("not supported", ex.Message, StringComparison.OrdinalIgnoreCase); } diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlParameterCollectionTest.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlParameterCollectionTest.cs index a67e642704..e93dbcc196 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlParameterCollectionTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlParameterCollectionTest.cs @@ -16,8 +16,7 @@ public void CollectionAddInvalidRange_Throws() SqlParameterCollection collection = command.Parameters; Array invalid = null; - ArgumentNullException ex = Assert.Throws(() => collection.AddRange(invalid)); - Assert.NotNull(ex); + Assert.Throws(() => collection.AddRange(invalid)); } [Fact] @@ -43,8 +42,6 @@ public void CollectionCheckNameInvalid_Throws() collection.Add(new SqlParameter("Test2", 2)); IndexOutOfRangeException ex = Assert.Throws(() => collection.RemoveAt("DoesNotExist")); - Assert.NotNull(ex); - Assert.NotEmpty(ex.Message); Assert.Contains("DoesNotExist", ex.Message, StringComparison.OrdinalIgnoreCase); } @@ -111,8 +108,7 @@ public void CollectionValiateNull_Throws() SqlCommand command = new SqlCommand(); SqlParameterCollection collection = command.Parameters; - ArgumentNullException ex = Assert.Throws(() => collection.Add(null)); - Assert.NotNull(ex); + Assert.Throws(() => collection.Add(null)); } } } diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlParameterTest.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlParameterTest.cs index e35a34f939..2f29b1bd15 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlParameterTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlParameterTest.cs @@ -718,7 +718,6 @@ public void LocaleIdOutOfRange_Throws() { SqlParameter parameter = new SqlParameter(); ArgumentOutOfRangeException ex = Assert.Throws(() => { parameter.LocaleId = -1; }); - Assert.NotNull(ex); Assert.NotNull(ex.ParamName); Assert.Contains("LocaleId", ex.ParamName, StringComparison.OrdinalIgnoreCase); } From b0ba491c3deed57809682483fadb9cdb81f79cb4 Mon Sep 17 00:00:00 2001 From: Johnny Pham Date: Wed, 17 Nov 2021 12:44:41 -0800 Subject: [PATCH 12/13] Update Microsoft.Data.SqlClient.csproj --- .../netfx/src/Microsoft.Data.SqlClient.csproj | 1 - 1 file changed, 1 deletion(-) 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 d6f95e6910..df8e73b2d3 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj @@ -338,7 +338,6 @@ Microsoft\Data\SqlClient\SqlCommandBuilder.cs - Component Microsoft\Data\SqlClient\SqlCommandSet.cs From c379b998aa2bef8de3f4753f625bbb4858c942f8 Mon Sep 17 00:00:00 2001 From: Johnny Pham Date: Thu, 20 Jan 2022 11:59:02 -0800 Subject: [PATCH 13/13] Revert "Merge remote-tracking branch 'upstream/main' into pr/1369" This reverts commit d0fac74431cf7fcf7f37190ad5bb1dde64afb465, reversing changes made to 431f1b7392a3cf019c2feb581a6c742d8ed2ed58. --- BUILDGUIDE.md | 133 +- CHANGELOG.md | 23 - build.proj | 52 +- doc/samples/AzureKeyVaultProviderExample.cs | 4 +- .../AzureKeyVaultProviderExample_2_0.cs | 4 +- .../AzureKeyVaultProviderLegacyExample_2_0.cs | 4 +- ...VaultProviderWithEnclaveProviderExample.cs | 4 +- ...tProviderWithEnclaveProviderExample_2_0.cs | 4 +- .../ActiveDirectoryAuthenticationProvider.xml | 5 +- .../Microsoft.Data.SqlClient/SqlBulkCopy.xml | 6 +- .../SqlConnectionStringBuilder.xml | 9 +- .../SqlDataReader.xml | 2 +- release-notes/4.0/4.0.0.md | 196 --- release-notes/4.0/4.0.1.md | 83 -- release-notes/4.0/4.0.md | 7 - release-notes/4.0/README.md | 7 - release-notes/README.md | 2 +- .../netcore/ref/Microsoft.Data.SqlClient.cs | 16 - .../netcore/src/.editorconfig | 12 - .../Interop.NetSecurityNative.cs | 37 +- .../src/Microsoft.Data.SqlClient.csproj | 14 +- .../Data/SqlClient/LocalDBAPI.Windows.cs | 5 +- .../Microsoft/Data/SqlClient/LocalDBAPI.cs | 34 +- .../Microsoft/Data/SqlClient/SNI/SNIProxy.cs | 11 +- .../Data/SqlClient/Server/MetadataUtilsSmi.cs | 16 +- .../Microsoft/Data/SqlClient/Server/SqlSer.cs | 59 +- .../SimulatorEnclaveProvider.NetCoreApp.cs} | 27 +- .../src/Microsoft/Data/SqlClient/SqlBuffer.cs | 29 +- .../Microsoft/Data/SqlClient/SqlBulkCopy.cs | 4 +- .../Microsoft/Data/SqlClient/SqlCommand.cs | 46 +- .../Microsoft/Data/SqlClient/SqlConnection.cs | 6 +- .../Microsoft/Data/SqlClient/SqlDataReader.cs | 58 +- .../src/Microsoft/Data/SqlClient/SqlError.cs | 72 + .../Data/SqlClient/SqlInternalConnection.cs | 14 +- .../SqlClient/SqlInternalConnectionTds.cs | 18 +- .../Data/SqlClient/SqlInternalTransaction.cs | 6 +- .../Microsoft/Data/SqlClient/SqlParameter.cs | 2 +- .../Data/SqlClient/SqlTransaction.cs | 18 +- .../src/Microsoft/Data/SqlClient/SqlUtil.cs | 2 +- .../src/Microsoft/Data/SqlClient/TdsParser.cs | 154 +-- .../Data/SqlClient/TdsParserHelperClasses.cs | 2 +- .../Data/SqlClient/TdsParserStateObject.cs | 12 +- .../netfx/ref/Microsoft.Data.SqlClient.cs | 2 - .../netfx/src/.editorconfig | 9 - .../netfx/src/Microsoft.Data.SqlClient.csproj | 16 +- .../Microsoft/Data/SqlClient/LocalDBAPI.cs | 39 +- .../Data/SqlClient/Server/MetadataUtilsSmi.cs | 26 +- .../SqlClient/Server/SmiContextFactory.cs | 8 +- .../Data/SqlClient/Server/TriggerAction.cs | 154 +-- .../Microsoft/Data/SqlClient/Server/sqlser.cs | 295 ++++ .../SqlClient/SimulatorEnclaveProvider.cs | 114 ++ .../src/Microsoft/Data/SqlClient/SqlBuffer.cs | 127 +- .../Microsoft/Data/SqlClient/SqlBulkCopy.cs | 16 +- .../Data/SqlClient/SqlClientPermission.cs | 28 +- ...olumnEncryptionCertificateStoreProvider.cs | 12 +- .../SqlColumnEncryptionCngProvider.cs | 12 +- .../SqlColumnEncryptionCspProvider.cs | 12 +- .../Microsoft/Data/SqlClient/SqlCommand.cs | 106 +- .../Microsoft/Data/SqlClient/SqlConnection.cs | 114 +- .../Data/SqlClient/SqlConnectionHelper.cs | 14 +- .../Microsoft/Data/SqlClient/SqlDataReader.cs | 311 ++--- .../Data/SqlClient/SqlDataReaderSmi.cs | 12 +- .../src/Microsoft/Data/SqlClient/SqlError.cs | 113 ++ .../Data/SqlClient/SqlInternalConnection.cs | 24 +- .../SqlClient/SqlInternalConnectionSmi.cs | 12 +- .../SqlClient/SqlInternalConnectionTds.cs | 38 +- .../Microsoft/Data/SqlClient/SqlParameter.cs | 12 +- .../Data/SqlClient/SqlTransaction.cs | 38 +- .../src/Microsoft/Data/SqlClient/SqlUtil.cs | 4 +- .../src/Microsoft/Data/SqlClient/TdsParser.cs | 306 ++--- .../Data/SqlClient/TdsParserHelperClasses.cs | 4 +- .../Data/SqlClient/TdsParserStateObject.cs | 14 +- .../Data/SqlClient/sqlinternaltransaction.cs | 16 +- .../netfx/src/Resources/Strings.es.resx | 2 +- .../netfx/src/Resources/Strings.ko.resx | 2 +- .../netfx/src/Resources/Strings.zh-Hans.resx | 2 +- .../AzureAttestationBasedEnclaveProvider.cs | 2 +- .../Data/SqlClient/EnclaveDelegate.Crypto.cs | 6 +- .../Data/SqlClient/EnclaveProviderBase.cs | 2 +- .../Data/SqlClient/LocalAppContextSwitches.cs | 20 +- .../SqlClient/Server/SqlDataRecord.netfx.cs | 12 +- .../Data/SqlClient/Server/SqlMetaData.cs | 5 +- .../Server/SqlUserDefinedTypeAttribute.cs | 2 +- .../Data/SqlClient/Server/ValueUtilsSmi.cs | 30 +- .../SqlClient/Server/ValueUtilsSmi.netfx.cs | 4 +- .../Microsoft/Data/SqlClient/SqlCollation.cs | 2 +- .../Data/SqlClient/SqlCommandBuilder.cs | 2 +- .../Data/SqlClient/SqlDependencyListener.cs | 48 +- .../SqlEnclaveAttestationParameters.Crypto.cs | 10 +- .../src/Microsoft/Data/SqlClient/SqlEnums.cs | 6 +- .../src/Microsoft/Data/SqlClient/SqlError.cs | 91 -- .../Data/SqlClient/SqlMetadataFactory.cs | 4 +- .../Data/SqlClient/SqlSecurityUtility.cs | 7 +- .../src/Microsoft/Data/SqlClient/TdsEnums.cs | 42 +- .../VirtualSecureModeEnclaveProviderBase.cs | 4 +- .../ExceptionRegisterKeyStoreProvider.cs | 25 +- .../ExceptionsAlgorithmErrors.cs | 74 +- ...ncryptionCertificateStoreProviderShould.cs | 97 +- .../AlwaysEncryptedTests/Utility.cs | 12 +- .../Microsoft.Data.SqlClient.Tests.csproj | 5 - .../FunctionalTests/SqlClientFactoryTest.cs | 24 - .../FunctionalTests/SqlClientLoggerTest.cs | 40 - .../FunctionalTests/SqlCommandBuilderTest.cs | 36 - .../FunctionalTests/SqlCommandSetTest.cs | 182 --- .../SqlConnectionStringBuilderTest.cs | 160 --- .../tests/FunctionalTests/SqlErrorTest.cs | 71 - .../tests/FunctionalTests/SqlMetaDataTest.cs | 972 -------------- .../SqlNotificationRequestTest.cs | 42 - .../SqlParameterCollectionTest.cs | 114 -- .../tests/FunctionalTests/SqlParameterTest.cs | 62 +- .../AlwaysEncrypted/ExceptionTestAKVStore.cs | 2 +- .../TestFixtures/DatabaseHelper.cs | 4 +- .../Setup/CertificateUtilityWin.cs | 2 +- .../TestFixtures/Setup/ColumnEncryptionKey.cs | 4 +- ....Data.SqlClient.ManualTesting.Tests.csproj | 259 ++-- .../ProviderAgnostic/ReaderTest/ReaderTest.cs | 91 -- .../SQL/AdapterTest/AdapterTest.cs | 42 - .../ConnectionPoolTest/ConnectionPoolTest.cs | 6 +- .../TcpDefaultForAzureTest.cs | 16 +- .../SQL/DataStreamTest/DataStreamTest.cs | 10 +- .../SQL/LocalDBTest/LocalDBTest.cs | 46 +- .../SQL/ParameterTest/DateTimeVariantTest.cs | 1189 ++++++++++------- .../SQL/ParameterTest/OutputParameter.cs | 28 +- .../SQL/ParameterTest/ParametersTest.cs | 729 +++++----- .../ParameterTest/SqlAdapterUpdateBatch.cs | 46 +- .../SQL/ParameterTest/SqlVariantParam.cs | 241 ++-- .../SQL/ParameterTest/SteAttribute.cs | 30 +- .../ManualTests/SQL/ParameterTest/SteParam.cs | 3 +- .../SQL/ParameterTest/StePermutationSet.cs | 33 +- .../SQL/ParameterTest/SteTypeBoundaries.cs | 386 +++--- .../SQL/ParameterTest/StreamInputParam.cs | 711 +++++----- .../ManualTests/SQL/ParameterTest/TvpTest.cs | 573 ++++---- .../SQL/RandomStressTest/RandomStressTest.cs | 8 +- .../SqlDependencyTest/SqlDependencyTest.cs | 149 --- .../TracingTests/EventCounterTest.cs | 22 +- .../config.default.json | 1 - .../tools/TDS/TDS.Servers/GenericTDSServer.cs | 7 +- .../TDS/Login7/TDSLogin7FedAuthOptionToken.cs | 7 +- .../tests/tools/TDS/TDS/TDSVersion.cs | 15 +- tools/props/Versions.props | 7 +- tools/specs/Microsoft.Data.SqlClient.nuspec | 8 +- 141 files changed, 4076 insertions(+), 6047 deletions(-) delete mode 100644 release-notes/4.0/4.0.0.md delete mode 100644 release-notes/4.0/4.0.1.md delete mode 100644 src/Microsoft.Data.SqlClient/netcore/src/.editorconfig rename src/Microsoft.Data.SqlClient/{ => netcore}/src/Microsoft/Data/SqlClient/Server/SqlSer.cs (89%) rename src/Microsoft.Data.SqlClient/{src/Microsoft/Data/SqlClient/NoneAttestationEnclaveProvider.cs => netcore/src/Microsoft/Data/SqlClient/SimulatorEnclaveProvider.NetCoreApp.cs} (86%) create mode 100644 src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlError.cs delete mode 100644 src/Microsoft.Data.SqlClient/netfx/src/.editorconfig create mode 100644 src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/Server/sqlser.cs create mode 100644 src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SimulatorEnclaveProvider.cs create mode 100644 src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlError.cs delete mode 100644 src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlError.cs delete mode 100644 src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlClientLoggerTest.cs delete mode 100644 src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlCommandSetTest.cs delete mode 100644 src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlErrorTest.cs delete mode 100644 src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlNotificationRequestTest.cs delete mode 100644 src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlParameterCollectionTest.cs diff --git a/BUILDGUIDE.md b/BUILDGUIDE.md index dcb2257745..a4e0b16e00 100644 --- a/BUILDGUIDE.md +++ b/BUILDGUIDE.md @@ -5,7 +5,6 @@ This document provides all the necessary details to build the driver and run tes ## Visual Studio Pre-Requisites This project should be built with Visual Studio 2019+ for the best compatibility. The required set of components are provided in the below file: - - **Visual Studio 2019** with imported components: [VS19Components](/tools/vsconfig/VS19Components.vsconfig) Once the environment is setup properly, execute the desired set of commands below from the _root_ folder to perform the respective operations: @@ -20,11 +19,6 @@ msbuild # Both .NET Framework (NetFx) and .NET Core drivers are built by default (as supported by Client OS). ``` -```bash -msbuild -t:clean -# Cleans all build directories. -``` - ```bash msbuild -p:Configuration=Release # Builds the driver in 'Release' Configuration for `AnyCPU` platform. @@ -35,6 +29,11 @@ msbuild -p:Platform=Win32 # Builds the .NET Framework (NetFx) driver for Win32 (x86) platform on Windows in 'Debug' Configuration. ``` +```bash +msbuild -t:clean +# Cleans all build directories. +``` + ```bash msbuild -t:restore # Restores Nuget Packages. @@ -73,63 +72,14 @@ msbuild -t:BuildTestsNetFx # Build the tests for the .NET Framework (NetFx) driver in 'Debug' Configuration. Default .NET Framework version is 4.6.1. ``` -```bash -msbuild -t:BuildTestsNetCore -p:TestSet=1 -# Build a subset of the manual tests. Valid values: '1', '2', '3', 'AE'. Omit to build all tests. -``` - -## Running Tests - -There are 2 ways to run tests, using MsBuild or Dotnet SDK. - -### Running from Build.proj - -```bash -msbuild -t:RunFunctionalTests -# Run all functional tests for *default* target framework (.NET Core 3.1). -``` - -```bash -msbuild -t:RunManualTests -# Run all manual tests for *default* target framework (.NET Core 3.1). -``` - -```bash -msbuild -t:RunTests -p:configuration=Release -# Run both functional and manual tests for *default* target framework (.NET Core 3.1). -``` - -To specify custom target framework, use `TF` property: - -```bash -msbuild -t:RunTests -p:configuration=Release -p:TF=net5.0 -msbuild -t:RunTests -p:configuration=Release -p:TF=net48 -# Runs tests for specified target framework. -# TargetNetCoreVersion and TargetNetFxVersion are not to be used with TF property, they will take precedence over TF if provided. -``` - -To capture test and code coverage results in a custom directory: - -```bash -msbuild -t:RunTests -p:ResultsDirectory=MyDirectory -# Runs tests with test and code coverage results placed in provided results directory. -# Default results directory is "TestResults". -``` - -Other properties can be set alongside as needed. - -### Running using Dotnet SDK (traditional) - -#### Run Functional Tests +## Run Functional Tests - Windows (`netfx x86`): - ```bash dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" -p:Platform="Win32" -p:Configuration="Release" -p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" ``` - Windows (`netfx x64`): - ```bash dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" -p:Platform="x64" -p:Configuration="Release" -p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" ``` @@ -137,26 +87,22 @@ dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.S - AnyCPU: Windows (`netcoreapp`): - ```bash dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" -p:Platform="AnyCPU" -p:Configuration="Release" -p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" ``` Unix (`netcoreapp`): - ```bash dotnet test "src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.Tests.csproj" -p:Platform="AnyCPU" -p:Configuration="Release" -p:TestTargetOS="Unixnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonlinuxtests&category!=nonuaptests" ``` -#### Run Manual Tests - -### Pre-Requisites for running Manual tests +## Run Manual Tests +### Pre-Requisites for running Manual tests: Manual Tests require the below setup to run: - -- SQL Server with enabled Shared Memory, TCP and Named Pipes Protocols and access to the Client OS. -- Databases "NORTHWIND" and "UdtTestDb" present in SQL Server, created using SQL scripts [createNorthwindDb.sql](tools/testsql/createNorthwindDb.sql) and [createUdtTestDb.sql](tools/testsql/createUdtTestDb.sql). To setup an Azure Database with "NORTHWIND" tables, use SQL Script: [createNorthwindAzureDb.sql](tools/testsql/createNorthwindAzureDb.sql). -- Make a copy of the configuration file [config.default.json](src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.TestUtilities/config.default.json) and rename it to `config.json`. Update the values in `config.json`: +* SQL Server with enabled Shared Memory, TCP and Named Pipes Protocols and access to the Client OS. +* Databases "NORTHWIND" and "UdtTestDb" present in SQL Server, created using SQL scripts [createNorthwindDb.sql](tools/testsql/createNorthwindDb.sql) and [createUdtTestDb.sql](tools/testsql/createUdtTestDb.sql). To setup an Azure Database with "NORTHWIND" tables, use SQL Script: [createNorthwindAzureDb.sql](tools/testsql/createNorthwindAzureDb.sql). +* Make a copy of the configuration file [config.default.json](src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.TestUtilities/config.default.json) and rename it to `config.json`. Update the values in `config.json`: |Property|Description|Value| |------|--------|-------------------| @@ -179,40 +125,36 @@ Manual Tests require the below setup to run: |IsAzureSynpase | (Optional) When set to 'true', test suite runs compatible tests for Azure Synapse/Parallel Data Warehouse. | `true` OR `false`| |MakecertPath | The full path to makecert.exe. This is not required if the path is present in the PATH environment variable. | `D:\\escaped\\absolute\\path\\to\\makecert.exe` | -### Commands to run Manual Tests - -- Windows (`netfx x86`): +### Commands to run Manual Tests: + - Windows (`netfx x86`): ```bash dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" -p:Platform="Win32" -p:Configuration="Release" -p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" ``` -- Windows (`netfx x64`): - + - Windows (`netfx x64`): ```bash dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" -p:Platform="x64" -p:Configuration="Release" -p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" ``` -- Windows (`netfx`): + - AnyCPU: + Windows (`netfx`): ```bash dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" -p:Platform="AnyCPU" -p:Configuration="Release" -p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" ``` -- Windows (`netcoreapp`): - + Windows (`netcoreapp`): ```bash dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" -p:Platform="AnyCPU" -p:Configuration="Release" -p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" ``` -- Unix (`netcoreapp`): - + Unix (`netcoreapp`): ```bash dotnet test "src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" -p:Platform="AnyCPU" -p:Configuration="Release" -p:TestTargetOS="Unixnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonlinuxtests&category!=nonuaptests" ``` ## Run A Single Test - ```bash dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" -p:Platform="AnyCPU" -p:Configuration="Release" -p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "FullyQualifiedName=Microsoft.Data.SqlClient.ManualTesting.Tests.AlwaysEncrypted.CspProviderExt.TestKeysFromCertificatesCreatedWithMultipleCryptoProviders" ``` @@ -228,12 +170,11 @@ Tests can be built and run with custom "Reference Type" property that enables di > ************** IMPORTANT NOTE BEFORE PROCEEDING WITH "PACKAGE" AND "NETSTANDARDPACKAGE" REFERENCE TYPES *************** > CREATE A NUGET PACKAGE WITH BELOW COMMAND AND ADD TO LOCAL FOLDER + UPDATE NUGET CONFIG FILE TO READ FROM THAT LOCATION -> -> ```bash +> ``` > msbuild -p:configuration=Release > ``` -### Building Tests with Reference Type +### Building Tests: For .NET Core, all 4 reference types are supported: @@ -257,19 +198,18 @@ msbuild -t:BuildTestsNetFx -p:ReferenceType=Project msbuild -t:BuildTestsNetFx -p:ReferenceType=Package ``` -### Running Tests with Reference Type +### Running Tests: Provide property to `dotnet test` commands for testing desired reference type. - -```bash +``` dotnet test -p:ReferenceType=Project ... ``` -## Testing with Custom TargetFramework (traditional) +## Testing with Custom TargetFramework Tests can be built and run with custom Target Frameworks. See the below examples. -### Building Tests with custom target framework +### Building Tests: ```bash msbuild -t:BuildTestsNetFx -p:TargetNetFxVersion=net462 @@ -283,7 +223,7 @@ msbuild -t:BuildTestsNetCore -p:TargetNetCoreVersion=netcoreapp3.1 # Applicable values: netcoreapp3.1 | net5.0 | net6.0 ``` -### Running Tests with custom target framework (traditional) +### Running Tests: ```bash dotnet test -p:TargetNetFxVersion=net462 ... @@ -299,31 +239,25 @@ dotnet test -p:TargetNetCoreVersion=netcoreapp3.1 ... Managed SNI can be enabled on Windows by enabling the below AppContext switch: -`Switch.Microsoft.Data.SqlClient.UseManagedNetworkingOnWindows` +**"Switch.Microsoft.Data.SqlClient.UseManagedNetworkingOnWindows"** ## Set truncation on for scaled decimal parameters Scaled decimal parameter truncation can be enabled by enabling the below AppContext switch: -`Switch.Microsoft.Data.SqlClient.TruncateScaledDecimal` +**"Switch.Microsoft.Data.SqlClient.TruncateScaledDecimal"** ## Enabling row version null behavior `SqlDataReader` returns a `DBNull` value instead of an empty `byte[]`. To enable the legacy behavior, you must enable the following AppContext switch on application startup: -`Switch.Microsoft.Data.SqlClient.LegacyRowVersionNullBehavior` +**"Switch.Microsoft.Data.SqlClient.LegacyRowVersionNullBehavior"** ## Enabling OS secure protocols preference TLS 1.3 has been excluded due to the fact that the driver lacks full support. To enable OS preferences as before, enable the following AppContext switch on application startup: -`Switch.Microsoft.Data.SqlClient.EnableSecureProtocolsByOS` - -## Suppressing TLS security warning - -When connecting to a server, if a protocol lower than TLS 1.2 is negotiated, a security warning is output to the console. This warning can be suppressed on SQL connections with `Encrypt = false` by enabling the following AppContext switch on application startup: - -`Switch.Microsoft.Data.SqlClient.SuppressInsecureTLSWarning` +**"Switch.Microsoft.Data.SqlClient.EnableSecureProtocolsByOS"** ## Debugging SqlClient on Linux from Windows @@ -332,17 +266,14 @@ For enhanced developer experience, we support debugging SqlClient on Linux from This project is also included in `docker-compose.yml` to demonstrate connectivity with SQL Server docker image. To run the same: - 1. Build the Solution in Visual Studio 2. Set `docker-compose` as Startup Project 3. Run "Docker-Compose" launch configuration. 4. You will see similar message in Debug window: - ```log Connected to SQL Server v15.00.4023 from Unix 4.19.76.0 The program 'dotnet' has exited with code 0 (0x0). ``` - 5. Now you can write code in [Program.cs](/src/Microsoft.Data.SqlClient/tests/DockerLinuxTest/Program.cs) to debug SqlClient on Linux! ### Troubleshooting Docker issues @@ -352,7 +283,6 @@ There may be times where connection cannot be made to SQL Server, we found below - Clear Docker images to create clean image from time-to-time, and clear docker cache if needed by running `docker system prune` in Command Prompt. - If you face `Microsoft.Data.SqlClient.SNI.dll not found` errors when debugging, try updating the below properties in the netcore\Microsoft.Data.SqlClient.csproj file and try again: - ```xml Unix false @@ -375,14 +305,13 @@ dotnet test --collect:"XPlat Code Coverage" ## Run Performance Tests -### Running Performance test project directly +### Running Performance test project directly: Project location from Root: `src\Microsoft.Data.SqlClient\tests\PerformanceTests\Microsoft.Data.SqlClient.PerformanceTests.csproj` Configure `runnerconfig.json` file with connection string and preferred settings to run Benchmark Jobs. -```bash +``` cd src\Microsoft.Data.SqlClient\tests\PerformanceTests dotnet run -c Release -f netcoreapp3.1|net5.0 ``` - _Only "**Release** Configuration" applies to Performance Tests_ diff --git a/CHANGELOG.md b/CHANGELOG.md index f6bc177c49..900703d501 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,29 +3,6 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) -## [Stable release 4.0.1] - 2022-01-17 - -### Added - -Added AppContext switch `SuppressInsecureTLSWarning` to allow suppression of TLS security warning when using `Encrypt=false` in the connection string. [#1457](https://github.com/dotnet/SqlClient/pull/1457) - -### Fixed - -- Fixed Kerberos authentication failure when using .NET 6. [#1411](https://github.com/dotnet/SqlClient/pull/1411) -- Fixed connection failure when using `SqlLocalDB` instance pipe name. [#1433](https://github.com/dotnet/SqlClient/pull/1433) -- Fixed a failure when executing concurrent queries requiring enclaves. [#1451](https://github.com/dotnet/SqlClient/pull/1451) -- Updated obsolete API calls targeting .NET 6. [#1401](https://github.com/dotnet/SqlClient/pull/1401) - -## [Stable Release 4.0.0] - 2021-11-18 - -### Added - -- Added missing `SqlClientLogger` class to .NET Core refs and missing `SqlClientLogger.LogWarning` method in .NET Framework refs [#1392](https://github.com/dotnet/SqlClient/pull/1392) - -### Changed - -- Avoid throwing unnecessary exception when an invalid `SqlNotificationInfo` value is received from SQL Server [#1378](https://github.com/dotnet/SqlClient/pull/1378) -- Updated `Microsoft.Data.SqlClient.SNI` (.NET Framework dependency) and `Microsoft.Data.SqlClient.SNI.runtime` (.NET Core/Standard dependency) version to `v4.0.0` [#1391](https://github.com/dotnet/SqlClient/pull/1391) ## [Preview Release 4.0.0-preview3.21293.2] - 2021-10-20 diff --git a/build.proj b/build.proj index 2aa4ee019b..790ef246b4 100644 --- a/build.proj +++ b/build.proj @@ -16,17 +16,9 @@ false Windows Unix - netcoreapp3.1 - netfx - netcore - netfx - netcoreapp - $(TF) - $(TF) true Configuration=$(Configuration);AssemblyFileVersion=$(AssemblyFileVersion);TargetsWindows=$(TargetsWindows);TargetsUnix=$(TargetsUnix); - BuildProjectReferences=false;$(ProjectProperties);BuildForRelease=false;TargetNetCoreVersion=$(TargetNetCoreVersion);TargetNetFxVersion=$(TargetNetFxVersion) - TestResults + BuildProjectReferences=false;$(ProjectProperties);BuildForRelease=false; @@ -49,7 +41,6 @@ - @@ -61,33 +52,31 @@ - - - - + + - - + + - + - - - + + + @@ -123,30 +112,14 @@ - + - + - - - - - - - - - - - - - - - - @@ -180,10 +153,11 @@ - + + diff --git a/doc/samples/AzureKeyVaultProviderExample.cs b/doc/samples/AzureKeyVaultProviderExample.cs index e16a9a63a7..84c9ffb2da 100644 --- a/doc/samples/AzureKeyVaultProviderExample.cs +++ b/doc/samples/AzureKeyVaultProviderExample.cs @@ -130,8 +130,8 @@ WITH VALUES ( private static string GetEncryptedValue(SqlColumnEncryptionAzureKeyVaultProvider sqlColumnEncryptionAzureKeyVaultProvider) { byte[] plainTextColumnEncryptionKey = new byte[32]; - RandomNumberGenerator rng = RandomNumberGenerator.Create(); - rng.GetBytes(plainTextColumnEncryptionKey); + RNGCryptoServiceProvider rngCsp = new RNGCryptoServiceProvider(); + rngCsp.GetBytes(plainTextColumnEncryptionKey); byte[] encryptedColumnEncryptionKey = sqlColumnEncryptionAzureKeyVaultProvider.EncryptColumnEncryptionKey(s_akvUrl, s_algorithm, plainTextColumnEncryptionKey); string EncryptedValue = string.Concat("0x", BitConverter.ToString(encryptedColumnEncryptionKey).Replace("-", string.Empty)); diff --git a/doc/samples/AzureKeyVaultProviderExample_2_0.cs b/doc/samples/AzureKeyVaultProviderExample_2_0.cs index d4c64f9684..f241966458 100644 --- a/doc/samples/AzureKeyVaultProviderExample_2_0.cs +++ b/doc/samples/AzureKeyVaultProviderExample_2_0.cs @@ -118,8 +118,8 @@ WITH VALUES ( private static string GetEncryptedValue(SqlColumnEncryptionAzureKeyVaultProvider sqlColumnEncryptionAzureKeyVaultProvider) { byte[] plainTextColumnEncryptionKey = new byte[32]; - RandomNumberGenerator rng = RandomNumberGenerator.Create(); - rng.GetBytes(plainTextColumnEncryptionKey); + RNGCryptoServiceProvider rngCsp = new RNGCryptoServiceProvider(); + rngCsp.GetBytes(plainTextColumnEncryptionKey); byte[] encryptedColumnEncryptionKey = sqlColumnEncryptionAzureKeyVaultProvider.EncryptColumnEncryptionKey(s_akvUrl, s_algorithm, plainTextColumnEncryptionKey); string EncryptedValue = string.Concat("0x", BitConverter.ToString(encryptedColumnEncryptionKey).Replace("-", string.Empty)); diff --git a/doc/samples/AzureKeyVaultProviderLegacyExample_2_0.cs b/doc/samples/AzureKeyVaultProviderLegacyExample_2_0.cs index d691455f06..e55e1f18c7 100644 --- a/doc/samples/AzureKeyVaultProviderLegacyExample_2_0.cs +++ b/doc/samples/AzureKeyVaultProviderLegacyExample_2_0.cs @@ -116,8 +116,8 @@ WITH VALUES ( private static string GetEncryptedValue(SqlColumnEncryptionAzureKeyVaultProvider sqlColumnEncryptionAzureKeyVaultProvider) { byte[] plainTextColumnEncryptionKey = new byte[32]; - RandomNumberGenerator rng = RandomNumberGenerator.Create(); - rng.GetBytes(plainTextColumnEncryptionKey); + RNGCryptoServiceProvider rngCsp = new RNGCryptoServiceProvider(); + rngCsp.GetBytes(plainTextColumnEncryptionKey); byte[] encryptedColumnEncryptionKey = sqlColumnEncryptionAzureKeyVaultProvider.EncryptColumnEncryptionKey(s_akvUrl, s_algorithm, plainTextColumnEncryptionKey); string EncryptedValue = string.Concat("0x", BitConverter.ToString(encryptedColumnEncryptionKey).Replace("-", string.Empty)); diff --git a/doc/samples/AzureKeyVaultProviderWithEnclaveProviderExample.cs b/doc/samples/AzureKeyVaultProviderWithEnclaveProviderExample.cs index 2091dab322..628a2e663b 100644 --- a/doc/samples/AzureKeyVaultProviderWithEnclaveProviderExample.cs +++ b/doc/samples/AzureKeyVaultProviderWithEnclaveProviderExample.cs @@ -136,8 +136,8 @@ WITH VALUES ( private static string GetEncryptedValue(SqlColumnEncryptionAzureKeyVaultProvider sqlColumnEncryptionAzureKeyVaultProvider) { byte[] plainTextColumnEncryptionKey = new byte[32]; - RandomNumberGenerator rng = RandomNumberGenerator.Create(); - rng.GetBytes(plainTextColumnEncryptionKey); + RNGCryptoServiceProvider rngCsp = new RNGCryptoServiceProvider(); + rngCsp.GetBytes(plainTextColumnEncryptionKey); byte[] encryptedColumnEncryptionKey = sqlColumnEncryptionAzureKeyVaultProvider.EncryptColumnEncryptionKey(s_akvUrl, s_algorithm, plainTextColumnEncryptionKey); string EncryptedValue = string.Concat("0x", BitConverter.ToString(encryptedColumnEncryptionKey).Replace("-", string.Empty)); diff --git a/doc/samples/AzureKeyVaultProviderWithEnclaveProviderExample_2_0.cs b/doc/samples/AzureKeyVaultProviderWithEnclaveProviderExample_2_0.cs index 27f97dac38..4328be2958 100644 --- a/doc/samples/AzureKeyVaultProviderWithEnclaveProviderExample_2_0.cs +++ b/doc/samples/AzureKeyVaultProviderWithEnclaveProviderExample_2_0.cs @@ -123,8 +123,8 @@ WITH VALUES ( private static string GetEncryptedValue(SqlColumnEncryptionAzureKeyVaultProvider sqlColumnEncryptionAzureKeyVaultProvider) { byte[] plainTextColumnEncryptionKey = new byte[32]; - RandomNumberGenerator rng = RandomNumberGenerator.Create(); - rng.GetBytes(plainTextColumnEncryptionKey); + RNGCryptoServiceProvider rngCsp = new RNGCryptoServiceProvider(); + rngCsp.GetBytes(plainTextColumnEncryptionKey); byte[] encryptedColumnEncryptionKey = sqlColumnEncryptionAzureKeyVaultProvider.EncryptColumnEncryptionKey(s_akvUrl, s_algorithm, plainTextColumnEncryptionKey); string EncryptedValue = string.Concat("0x", BitConverter.ToString(encryptedColumnEncryptionKey).Replace("-", string.Empty)); diff --git a/doc/snippets/Microsoft.Data.SqlClient/ActiveDirectoryAuthenticationProvider.xml b/doc/snippets/Microsoft.Data.SqlClient/ActiveDirectoryAuthenticationProvider.xml index 5a69be7478..081e22dcd6 100644 --- a/doc/snippets/Microsoft.Data.SqlClient/ActiveDirectoryAuthenticationProvider.xml +++ b/doc/snippets/Microsoft.Data.SqlClient/ActiveDirectoryAuthenticationProvider.xml @@ -95,16 +95,13 @@ The following example demonstrates providing a custom device flow callback to Sq are: + The supported authentication modes with are: - Active Directory Password - Active Directory Integrated - Active Directory Interactive - Active Directory Service Principal - Active Directory Device Code Flow -- Active Directory Managed Identity -- Active Directory MSI -- Active Directory Default ]]> diff --git a/doc/snippets/Microsoft.Data.SqlClient/SqlBulkCopy.xml b/doc/snippets/Microsoft.Data.SqlClient/SqlBulkCopy.xml index 44a5fbab63..4388f98172 100644 --- a/doc/snippets/Microsoft.Data.SqlClient/SqlBulkCopy.xml +++ b/doc/snippets/Microsoft.Data.SqlClient/SqlBulkCopy.xml @@ -8,11 +8,11 @@ class lets you write managed code solutions that provide similar functionality. There are other ways to load data into a SQL Server table (INSERT statements, for example), but offers a significant performance advantage over them. The class can be used to write data only to SQL Server tables. However, the data source is not limited to SQL Server; any data source can be used, as long as the data can be loaded to a instance or read with a instance. will fail when bulk loading a column of type into a SQL Server column whose type is one of the date/time types added in SQL Server 2008. +Microsoft SQL Server includes a popular command-prompt utility named **bcp** for moving data from one table to another, whether on a single server or between servers. The class lets you write managed code solutions that provide similar functionality. There are other ways to load data into a SQL Server table (INSERT statements, for example), but offers a significant performance advantage over them. The class can be used to write data only to SQL Server tables. However, the data source is not limited to SQL Server; any data source can be used, as long as the data can be loaded to a instance or read with a instance. will fail when bulk loading a column of type into a SQL Server column whose type is one of the date/time types added in SQL Server 2008. ## Examples -The following console application demonstrates how to load data using the class. -In this example, a is used to copy data from the **Production.Product** table in the SQL Server **AdventureWorks** database to a similar table in the same database. +The following console application demonstrates how to load data using the class. +In this example, a is used to copy data from the **Production.Product** table in the SQL Server **AdventureWorks** database to a similar table in the same database. > [!IMPORTANT] > This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/sql/connect/ado-net/sql/bulk-copy-example-setup). diff --git a/doc/snippets/Microsoft.Data.SqlClient/SqlConnectionStringBuilder.xml b/doc/snippets/Microsoft.Data.SqlClient/SqlConnectionStringBuilder.xml index 5b360dfb97..d0cebe8712 100644 --- a/doc/snippets/Microsoft.Data.SqlClient/SqlConnectionStringBuilder.xml +++ b/doc/snippets/Microsoft.Data.SqlClient/SqlConnectionStringBuilder.xml @@ -177,7 +177,7 @@ Modified: Data Source=(local);Initial Catalog=AdventureWorks;Integrated Security @@ -408,17 +408,14 @@ If the value of the **Network** key is specified, the prefixes "tcp:" and "np:" Gets or sets a Boolean value that indicates whether SQL Server uses SSL encryption for all data sent between the client and server if the server has a certificate installed. - The value of the property, or if none has been supplied. + The value of the property, or if none has been supplied. [!NOTE] -> Starting from **version 4.0**, the default value of the property `Encrypt` is set to `true`. +When `TrustServerCertificate` is false and `Encrypt` is true, the server name (or IP address) in a SQL Server SSL certificate must exactly match the server name (or IP address) specified in the connection string. Otherwise, the connection attempt will fail. For information about support for certificates whose subject starts with a wildcard character (*), see [Enable encrypted connections to the Database Engine](sql/database-engine/configure-windows/enable-encrypted-connections-to-the-database-engine#certificate-requirements).| ]]> diff --git a/doc/snippets/Microsoft.Data.SqlClient/SqlDataReader.xml b/doc/snippets/Microsoft.Data.SqlClient/SqlDataReader.xml index 8a789962d3..3d1ad11722 100644 --- a/doc/snippets/Microsoft.Data.SqlClient/SqlDataReader.xml +++ b/doc/snippets/Microsoft.Data.SqlClient/SqlDataReader.xml @@ -532,7 +532,7 @@ method returns the following metadata about each column: + For the method returns metadata about each column in the following order: |DataReader column|Description| |-----------------------|-----------------| diff --git a/release-notes/4.0/4.0.0.md b/release-notes/4.0/4.0.0.md deleted file mode 100644 index 6059c27983..0000000000 --- a/release-notes/4.0/4.0.0.md +++ /dev/null @@ -1,196 +0,0 @@ -# Release Notes - -## Microsoft.Data.SqlClient 4.0.0 released 18 November 2021 - -This update brings the below changes over the previous preview release: - -### Added - -- Added missing `SqlClientLogger` class to .NET Core refs and missing `SqlClientLogger.LogWarning` method in .NET Framework refs [#1392](https://github.com/dotnet/SqlClient/pull/1392) - -### Changed - -- Avoid throwing unnecessary exception when an invalid `SqlNotificationInfo` value is received from SQL Server [#1378](https://github.com/dotnet/SqlClient/pull/1378) -- Updated `Microsoft.Data.SqlClient.SNI` (.NET Framework dependency) and `Microsoft.Data.SqlClient.SNI.runtime` (.NET Core/Standard dependency) version to `v4.0.0` [#1391](https://github.com/dotnet/SqlClient/pull/1391) - -## Summary of changes in 4.0 - -All changes in Microsoft.Data.SqlClient v4.0 over v3.0: - -### New Additions - -- Added `SqlCommand.EnableOptimizedParameterBinding` property that when enabled increases performance for commands with very large numbers of parameters. [#1041](https://github.com/dotnet/SqlClient/pull/1041) [Read more](#enable-optimized-parameter-binding) -- Included `42108` and `42109` error codes to retriable transient errors list. [#1215](https://github.com/dotnet/SqlClient/pull/1215) -- Added new App Context switch to use OS enabled client protocols only. [#1168](https://github.com/dotnet/SqlClient/pull/1168). [Read more](#app-context-switch-for-using-system-default-protocols) -- Added `PoolBlockingPeriod` connection property support in .NET Standard. [#1181](https://github.com/dotnet/SqlClient/pull/1181) -- Added support for `SqlDataReader.GetColumnSchema()` in .NET Standard. [#1181](https://github.com/dotnet/SqlClient/pull/1181) -- Added PropertyGrid support with component model annotations to `SqlConnectionStringBuilder` properties for .NET Core. [#1152](https://github.com/dotnet/SqlClient/pull/1152) -- Added support for `SqlFileStream` on Windows using .NET Standard 2.0 and above. [#1240](https://github.com/dotnet/SqlClient/pull/1240) -- Added support for **localdb** `shared instance` using managed SNI. [#1237](https://github.com/dotnet/SqlClient/pull/1237). [Read more](#sqllocaldb-shared-instance-support) -- Added `GetFieldValueAsync` and `GetFieldValue` support for `XmlReader`, `TextReader`, `Stream` [#1019](https://github.com/dotnet/SqlClient/pull/1019). [Read more](#getfieldvalueasynct-and-getfieldvaluet-support-for-xmlreader-textreader-stream-types) -- Added missing `SqlClientLogger` class to .NET Core refs and missing 'SqlClientLogger.LogWarning' method in .NET Framework refs [#1392](https://github.com/dotnet/SqlClient/pull/1392) - -### Bug Fixes - -- Fixed issue with connectivity when TLS 1.3 is enabled on client and server. [#1168](https://github.com/dotnet/SqlClient/pull/1168) -- Fixed issue with connection encryption to ensure connections fail when encryption is required. [#1210](https://github.com/dotnet/SqlClient/pull/1210) [Read more](#ensure-connections-fail-when-encryption-is-required) -- Fixed issue where connection goes to unusable state. [#1128](https://github.com/dotnet/SqlClient/pull/1128) -- Fixed recursive calls to `RetryLogicProvider` when calling `SqlCommand.ExecuteScalarAsync`. [#1220](https://github.com/dotnet/SqlClient/pull/1220) -- Fixed async deadlock scenarios in web contexts with configurable retry logic provider. [#1220](https://github.com/dotnet/SqlClient/pull/1220) -- Fixed `EntryPointNotFoundException` in `InOutOfProcHelper` constructor. [#1120](https://github.com/dotnet/SqlClient/pull/1120) -- Fixed async thread blocking issues on `SqlConnection.Open()` for active directory authentication modes. [#1213](https://github.com/dotnet/SqlClient/pull/1213) -- Fixed driver behavior for Always Encrypted with secure enclaves to not fail when no user parameters have been provided. [#1115](https://github.com/dotnet/SqlClient/pull/1115) -- Fixed bug with `LegacyRowVersionNullBehavior` App Context switch. [#1182](https://github.com/dotnet/SqlClient/pull/1182) -- Fixed issues in Strings.resx file containing error messages. [#1136](https://github.com/dotnet/SqlClient/pull/1136) [#1178](https://github.com/dotnet/SqlClient/pull/1178) -- Fixed `.NET decimal` conversion from `SqlDecimal`. [#1179](https://github.com/dotnet/SqlClient/pull/1179) -- Fixed `Event Source` changes on **TryBeginExecuteEvent** and **WriteEndExecuteEvent** to address the failure on other MS products such as OpenTelemetry and Application Insight. [#1258](https://github.com/dotnet/SqlClient/pull/1258) -- Fixed deadlock in transaction using .NET Framework. [#1242](https://github.com/dotnet/SqlClient/pull/1242) -- Fixed unknown transaction state issues when prompting delegated transaction. [1216](https://github.com/dotnet/SqlClient/pull/1216) -- Fixed `FormatException` when opening a connection with event tracing enabled [#1291](https://github.com/dotnet/SqlClient/pull/1291) -- Fixed improper initialization of `ActiveDirectoryAuthenticationProvider` [#1328](https://github.com/dotnet/SqlClient/pull/1328) -- Fixed `MissingMethodException` when accessing `SqlAuthenticationParameters.ConnectionTimeout` [#1336](https://github.com/dotnet/SqlClient/pull/1336) -- Fixed bug where environment variables are ignored when using `Active Directory Default` authentication [#1360](https://github.com/dotnet/SqlClient/pull/1360) - -### Improvements and Changes - -- Updated error code to match with Windows when certificate validation fails in non-Windows client environments. [#1130](https://github.com/dotnet/SqlClient/pull/1130) -- Removed designer attributes from `SqlCommand` and `SqlDataAdapter`. [#1132](https://github.com/dotnet/SqlClient/pull/1132) -- Updated configurable retry logic default retriable error list. [#1125](https://github.com/dotnet/SqlClient/pull/1125) -- Improved performance by changing `SqlParameter` bool fields to flags. [#1064](https://github.com/dotnet/SqlClient/pull/1064) -- Improved performance by implementing static delegates. [#1060](https://github.com/dotnet/SqlClient/pull/1060) -- Optimized async method allocations in .NET Framework by porting changes from .NET Core. [#1084](https://github.com/dotnet/SqlClient/pull/1084) -- Various code improvements [#902](https://github.com/dotnet/SqlClient/pull/902) [#925](https://github.com/dotnet/SqlClient/pull/925) [#933](https://github.com/dotnet/SqlClient/pull/933) [#934](https://github.com/dotnet/SqlClient/pull/934) [#1024](https://github.com/dotnet/SqlClient/pull/1024) [#1057](https://github.com/dotnet/SqlClient/pull/1057) [#1122](https://github.com/dotnet/SqlClient/pull/1122) [#1133](https://github.com/dotnet/SqlClient/pull/1133) [#1134](https://github.com/dotnet/SqlClient/pull/1134) [#1141](https://github.com/dotnet/SqlClient/pull/1141) [#1155](https://github.com/dotnet/SqlClient/pull/1155) [#1187](https://github.com/dotnet/SqlClient/pull/1187) [#1188](https://github.com/dotnet/SqlClient/pull/1188) [#1223](https://github.com/dotnet/SqlClient/pull/1223) [#1225](https://github.com/dotnet/SqlClient/pull/1225) [#1226](https://github.com/dotnet/SqlClient/pull/1226) [#1236](https://github.com/dotnet/SqlClient/pull/1236) [#1251](https://github.com/dotnet/SqlClient/pull/1251) [#1266](https://github.com/dotnet/SqlClient/pull/1266) -- Removed attributes for classes used in Microsoft.VSDesigner due to lack of support for Microsoft.Data.SqlClient [#1296](https://github.com/dotnet/SqlClient/pull/1296) -- Disable encryption when connecting to SQL LocalDB [#1312](https://github.com/dotnet/SqlClient/pull/1312) -- Avoid throwing unnecessary exception when an invalid SqlNotificationInfo value is received from SQL Server [#1378](https://github.com/dotnet/SqlClient/pull/1378) -- Updated `Microsoft.Data.SqlClient.SNI` (.NET Framework dependency) and `Microsoft.Data.SqlClient.SNI.runtime` (.NET Core/Standard dependency) version to `v4.0.0` [#1391](https://github.com/dotnet/SqlClient/pull/1391) -- Various code health and performance improvements. See [milestone](https://github.com/dotnet/SqlClient/milestone/31?closed=1) for more info. - -### Breaking Changes -- Changed `Encrypt` connection string property to be `true` by default. [#1210](https://github.com/dotnet/SqlClient/pull/1210) [Read more](#encrypt-default-value-set-to-true) -- The driver now throws `SqlException` replacing `AggregateException` for active directory authentication modes. [#1213](https://github.com/dotnet/SqlClient/pull/1213) -- Dropped obsolete `Asynchronous Processing` connection property from .NET Framework. [#1148](https://github.com/dotnet/SqlClient/pull/1148) -- Removed `Configurable Retry Logic` safety switch. [#1254](https://github.com/dotnet/SqlClient/pull/1254) [Read more](#remove-configurable-retry-logic-safety-switch) -- Dropped support for .NET Core 2.1 [#1272](https://github.com/dotnet/SqlClient/pull/1272) -- [.NET Framework] Exception will not be thrown if a User ID is provided in the connection string when using `Active Directory Integrated` authentication [#1359](https://github.com/dotnet/SqlClient/pull/1359) - -### Encrypt default value set to true -The default value of the `Encrypt` connection setting has been changed from `false` to `true`. With the growing use of cloud databases and the need to ensure those connections are secure, it's time for this backwards-compatibility-breaking change. - -### Ensure connections fail when encryption is required -In scenarios where client encryption libraries were disabled or unavailable, it was possible for unencrypted connections to be made when Encrypt was set to true or the server required encryption. - -### App Context Switch for using System default protocols -TLS 1.3 is not supported by the driver; therefore, it has been removed from the supported protocols list by default. Users can switch back to forcing use of the Operating System's client protocols, by enabling the App Context switch below: - - `Switch.Microsoft.Data.SqlClient.UseSystemDefaultSecureProtocols` - -### Enable optimized parameter binding -Microsoft.Data.SqlClient introduces a new `SqlCommand` API, `EnableOptimizedParameterBinding` to improve performance of queries with a large number of parameters. This property is disabled by default. When set to `true`, parameter names will not be sent to the SQL server when the command is executed. - -```cs -public class SqlCommand -{ - public bool EnableOptimizedParameterBinding { get; set; } -} -``` - -### Remove configurable retry logic safety switch - -The App Context switch "Switch.Microsoft.Data.SqlClient.EnableRetryLogic" will no longer be required to use the configurable retry logic feature. The feature is now supported in production. The default behavior of the feature will continue to be a non-retry policy, which will need to be overridden by client applications to enable retries. - -### SqlLocalDb shared instance support - -SqlLocalDb shared instances are now supported when using Managed SNI. - -- Possible scenarios: - - `(localdb)\.` (connects to default instance of SqlLocalDb) - - `(localdb)\` - - `(localdb)\.\` (*newly added support) - -### `GetFieldValueAsync` and `GetFieldValue` support for `XmlReader`, `TextReader`, `Stream` types - -`XmlReader`, `TextReader`, `Stream` types are now supported when using `GetFieldValueAsync` and `GetFieldValue`. - -Example usage: - -```cs -using (SqlConnection connection = new SqlConnection(connectionString)) -{ - using (SqlCommand command = new SqlCommand(query, connection)) - { - connection.Open(); - using (SqlDataReader reader = await command.ExecuteReaderAsync()) - { - if (await reader.ReadAsync()) - { - using (Stream stream = await reader.GetFieldValueAsync(1)) - { - // Continue to read from stream - } - } - } - } -} -``` - -## Target Platform Support - -- .NET Framework 4.6.1+ (Windows x86, Windows x64) -- .NET Core 3.1+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS) -- .NET Standard 2.0+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS) - -### Dependencies - -#### .NET Framework - -- Microsoft.Data.SqlClient.SNI 4.0.0 -- Azure.Identity 1.3.0 -- Microsoft.Identity.Client 4.22.0 -- Microsoft.IdentityModel.JsonWebTokens 6.8.0 -- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0 -- System.Buffers 4.5.1 -- System.Configuration.ConfigurationManager 5.0.0 -- System.IO 4.3.0 -- System.Runtime.InteropServices.RuntimeInformation 4.3.0 -- System.Security.Cryptography.Algorithms 4.3.1 -- System.Security.Cryptography.Primitives 4.3.0 -- System.Text.Encodings.Web 4.7.2 - -#### .NET Core - -- Microsoft.Data.SqlClient.SNI.runtime 4.0.0 -- Azure.Identity 1.3.0 -- Microsoft.Identity.Client 4.22.0 -- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0 -- Microsoft.IdentityModel.JsonWebTokens 6.8.0 -- Microsoft.Win32.Registry 5.0.0 -- System.Buffers 4.5.1 -- System.Configuration.ConfigurationManager 5.0.0 -- System.Diagnostics.DiagnosticSource 5.0.0 -- System.IO 4.3.0 -- System.Runtime.Caching 5.0.0 -- System.Text.Encoding.CodePages 5.0.0 -- System.Text.Encodings.Web 4.7.2 -- System.Resources.ResourceManager 4.3.0 -- System.Security.Cryptography.Cng 5.0.0 -- System.Security.Principal.Windows 5.0.0 - -#### .NET Standard - -- Microsoft.Data.SqlClient.SNI.runtime 4.0.0 -- Azure.Identity 1.3.0 -- Microsoft.Identity.Client 4.22.0 -- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0 -- Microsoft.IdentityModel.JsonWebTokens 6.8.0 -- Microsoft.Win32.Registry 5.0.0 -- System.Buffers 4.5.1 -- System.Configuration.ConfigurationManager 5.0.0 -- System.IO 4.3.0 -- System.Runtime.Caching 5.0.0 -- System.Text.Encoding.CodePages 5.0.0 -- System.Text.Encodings.Web 4.7.2 -- System.Resources.ResourceManager 4.3.0 -- System.Runtime.Loader 4.3.0 -- System.Security.Cryptography.Cng 5.0.0 -- System.Security.Principal.Windows 5.0.0 diff --git a/release-notes/4.0/4.0.1.md b/release-notes/4.0/4.0.1.md deleted file mode 100644 index 7e43a9bcc8..0000000000 --- a/release-notes/4.0/4.0.1.md +++ /dev/null @@ -1,83 +0,0 @@ -# Release Notes - -## Microsoft.Data.SqlClient 4.0.1 released 17 January 2022 - -This update brings the below changes over the previous preview release: - -### Added - -- Added AppContext switch `SuppressInsecureTLSWarning` to allow suppression of TLS security warning when using `Encrypt=false` in the connection string. [#1457](https://github.com/dotnet/SqlClient/pull/1457) [Read more](#suppress-tls-security-warnings) - -### Fixed - -- Fixed Kerberos authentication failure when using .NET 6. [#1411](https://github.com/dotnet/SqlClient/pull/1411) -- Fixed connection failure when using `SqlLocalDB` instance pipe name. [#1433](https://github.com/dotnet/SqlClient/pull/1433) -- Fixed a failure when executing concurrent queries requiring enclaves. [#1451](https://github.com/dotnet/SqlClient/pull/1451) -- Updated obsolete API calls targeting .NET 6. [#1401](https://github.com/dotnet/SqlClient/pull/1401) - -### Suppress TLS security warnings - -When connecting to a SQL Server, if a protocol lower than TLS 1.2 is negotiated, a security warning is printed out to the console. This warning can be suppressed by enabling the following `AppContext` switch on the application startup while `Encrypt` is set to `false` on connection string. - -`Switch.Microsoft.Data.SqlClient.SuppressInsecureTLSWarning` - -## Target Platform Support - -- .NET Framework 4.6.1+ (Windows x86, Windows x64) -- .NET Core 3.1+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS) -- .NET Standard 2.0+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS) - -### Dependencies - -#### .NET Framework - -- Microsoft.Data.SqlClient.SNI 4.0.0 -- Azure.Identity 1.3.0 -- Microsoft.Identity.Client 4.22.0 -- Microsoft.IdentityModel.JsonWebTokens 6.8.0 -- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0 -- System.Buffers 4.5.1 -- System.Configuration.ConfigurationManager 5.0.0 -- System.IO 4.3.0 -- System.Runtime.InteropServices.RuntimeInformation 4.3.0 -- System.Security.Cryptography.Algorithms 4.3.1 -- System.Security.Cryptography.Primitives 4.3.0 -- System.Text.Encodings.Web 4.7.2 - -#### .NET Core - -- Microsoft.Data.SqlClient.SNI.runtime 4.0.0 -- Azure.Identity 1.3.0 -- Microsoft.Identity.Client 4.22.0 -- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0 -- Microsoft.IdentityModel.JsonWebTokens 6.8.0 -- Microsoft.Win32.Registry 5.0.0 -- System.Buffers 4.5.1 -- System.Configuration.ConfigurationManager 5.0.0 -- System.Diagnostics.DiagnosticSource 5.0.0 -- System.IO 4.3.0 -- System.Runtime.Caching 5.0.0 -- System.Text.Encoding.CodePages 5.0.0 -- System.Text.Encodings.Web 4.7.2 -- System.Resources.ResourceManager 4.3.0 -- System.Security.Cryptography.Cng 5.0.0 -- System.Security.Principal.Windows 5.0.0 - -#### .NET Standard - -- Microsoft.Data.SqlClient.SNI.runtime 4.0.0 -- Azure.Identity 1.3.0 -- Microsoft.Identity.Client 4.22.0 -- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0 -- Microsoft.IdentityModel.JsonWebTokens 6.8.0 -- Microsoft.Win32.Registry 5.0.0 -- System.Buffers 4.5.1 -- System.Configuration.ConfigurationManager 5.0.0 -- System.IO 4.3.0 -- System.Runtime.Caching 5.0.0 -- System.Text.Encoding.CodePages 5.0.0 -- System.Text.Encodings.Web 4.7.2 -- System.Resources.ResourceManager 4.3.0 -- System.Runtime.Loader 4.3.0 -- System.Security.Cryptography.Cng 5.0.0 -- System.Security.Principal.Windows 5.0.0 \ No newline at end of file diff --git a/release-notes/4.0/4.0.md b/release-notes/4.0/4.0.md index c6a93a0724..d9f8ceac96 100644 --- a/release-notes/4.0/4.0.md +++ b/release-notes/4.0/4.0.md @@ -1,12 +1,5 @@ # Microsoft.Data.SqlClient 4.0 Releases -The following Microsoft.Data.SqlClient 4.0 stable releases have been shipped: - -| Release Date | Version | Notes | -| :-- | :-- | :--: | -| 2022/01/17 | 4.0.1 | [release notes](4.0.1.md) | -| 2021/11/18 | 4.0.0 | [release notes](4.0.0.md) | - The following Microsoft.Data.SqlClient 4.0 preview releases have been shipped: | Release Date | Version | Notes | diff --git a/release-notes/4.0/README.md b/release-notes/4.0/README.md index c6a93a0724..d9f8ceac96 100644 --- a/release-notes/4.0/README.md +++ b/release-notes/4.0/README.md @@ -1,12 +1,5 @@ # Microsoft.Data.SqlClient 4.0 Releases -The following Microsoft.Data.SqlClient 4.0 stable releases have been shipped: - -| Release Date | Version | Notes | -| :-- | :-- | :--: | -| 2022/01/17 | 4.0.1 | [release notes](4.0.1.md) | -| 2021/11/18 | 4.0.0 | [release notes](4.0.0.md) | - The following Microsoft.Data.SqlClient 4.0 preview releases have been shipped: | Release Date | Version | Notes | diff --git a/release-notes/README.md b/release-notes/README.md index ae992b42c4..4340d7838e 100644 --- a/release-notes/README.md +++ b/release-notes/README.md @@ -1,6 +1,6 @@ # Microsoft.Data.SqlClient Release Notes -The latest stable release is [Microsoft.Data.SqlClient 4.0](4.0). +The latest stable release is [Microsoft.Data.SqlClient 3.0](3.0). ## Release Information diff --git a/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.cs b/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.cs index 22cbb29f6e..97c1347b10 100644 --- a/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.cs +++ b/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.cs @@ -414,22 +414,6 @@ internal SqlClientFactory() { } /// public override System.Data.Common.DbParameter CreateParameter() { throw null; } } - /// - public partial class SqlClientLogger - { - /// - public SqlClientLogger() { } - /// - public bool IsLoggingEnabled { get { throw null; } } - /// - public void LogWarning(string type, string method, string message) { } - /// - public bool LogAssert(bool value, string type, string method, string message) { throw null; } - /// - public void LogError(string type, string method, string message) { } - /// - public void LogInfo(string type, string method, string message) { } - } /// public static partial class SqlClientMetaDataCollectionNames { diff --git a/src/Microsoft.Data.SqlClient/netcore/src/.editorconfig b/src/Microsoft.Data.SqlClient/netcore/src/.editorconfig deleted file mode 100644 index ecc808aa66..0000000000 --- a/src/Microsoft.Data.SqlClient/netcore/src/.editorconfig +++ /dev/null @@ -1,12 +0,0 @@ -# editorconfig.org - -# top-most EditorConfig file -root = false - -[*.cs] - -# IDE0090: Use 'new(...)' -csharp_style_implicit_object_creation_when_type_is_apparent = false - -# IDE0063: Use simple 'using' statement -csharp_prefer_simple_using_statement = false diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Unix/System.Net.Security.Native/Interop.NetSecurityNative.cs b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Unix/System.Net.Security.Native/Interop.NetSecurityNative.cs index 489d1cf8a9..ab8338e796 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Unix/System.Net.Security.Native/Interop.NetSecurityNative.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Unix/System.Net.Security.Native/Interop.NetSecurityNative.cs @@ -11,52 +11,49 @@ internal static partial class Interop { internal static partial class NetSecurityNative { - [DllImport(Libraries.NetSecurityNative, EntryPoint = "NetSecurityNative_ReleaseGssBuffer")] + [DllImport(Libraries.NetSecurityNative, EntryPoint="NetSecurityNative_ReleaseGssBuffer")] internal static extern void ReleaseGssBuffer( IntPtr bufferPtr, ulong length); - [DllImport(Interop.Libraries.NetSecurityNative, EntryPoint = "NetSecurityNative_EnsureGssInitialized")] - private static extern int EnsureGssInitialized(); - - [DllImport(Libraries.NetSecurityNative, EntryPoint = "NetSecurityNative_DisplayMinorStatus")] + [DllImport(Libraries.NetSecurityNative, EntryPoint="NetSecurityNative_DisplayMinorStatus")] internal static extern Status DisplayMinorStatus( out Status minorStatus, Status statusValue, ref GssBuffer buffer); - [DllImport(Libraries.NetSecurityNative, EntryPoint = "NetSecurityNative_DisplayMajorStatus")] + [DllImport(Libraries.NetSecurityNative, EntryPoint="NetSecurityNative_DisplayMajorStatus")] internal static extern Status DisplayMajorStatus( out Status minorStatus, Status statusValue, ref GssBuffer buffer); - [DllImport(Libraries.NetSecurityNative, EntryPoint = "NetSecurityNative_ImportUserName")] + [DllImport(Libraries.NetSecurityNative, EntryPoint="NetSecurityNative_ImportUserName")] internal static extern Status ImportUserName( out Status minorStatus, string inputName, int inputNameByteCount, out SafeGssNameHandle outputName); - [DllImport(Libraries.NetSecurityNative, EntryPoint = "NetSecurityNative_ImportPrincipalName")] + [DllImport(Libraries.NetSecurityNative, EntryPoint="NetSecurityNative_ImportPrincipalName")] internal static extern Status ImportPrincipalName( out Status minorStatus, string inputName, int inputNameByteCount, out SafeGssNameHandle outputName); - [DllImport(Libraries.NetSecurityNative, EntryPoint = "NetSecurityNative_ReleaseName")] + [DllImport(Libraries.NetSecurityNative, EntryPoint="NetSecurityNative_ReleaseName")] internal static extern Status ReleaseName( out Status minorStatus, ref IntPtr inputName); - [DllImport(Libraries.NetSecurityNative, EntryPoint = "NetSecurityNative_InitiateCredSpNego")] + [DllImport(Libraries.NetSecurityNative, EntryPoint="NetSecurityNative_InitiateCredSpNego")] internal static extern Status InitiateCredSpNego( out Status minorStatus, SafeGssNameHandle desiredName, out SafeGssCredHandle outputCredHandle); - [DllImport(Libraries.NetSecurityNative, EntryPoint = "NetSecurityNative_InitiateCredWithPassword")] + [DllImport(Libraries.NetSecurityNative, EntryPoint="NetSecurityNative_InitiateCredWithPassword")] internal static extern Status InitiateCredWithPassword( out Status minorStatus, bool isNtlm, @@ -65,12 +62,12 @@ internal static extern Status InitiateCredWithPassword( int passwordLen, out SafeGssCredHandle outputCredHandle); - [DllImport(Libraries.NetSecurityNative, EntryPoint = "NetSecurityNative_ReleaseCred")] + [DllImport(Libraries.NetSecurityNative, EntryPoint="NetSecurityNative_ReleaseCred")] internal static extern Status ReleaseCred( out Status minorStatus, ref IntPtr credHandle); - [DllImport(Libraries.NetSecurityNative, EntryPoint = "NetSecurityNative_InitSecContext")] + [DllImport(Libraries.NetSecurityNative, EntryPoint="NetSecurityNative_InitSecContext")] internal static extern Status InitSecContext( out Status minorStatus, SafeGssCredHandle initiatorCredHandle, @@ -84,7 +81,7 @@ internal static extern Status InitSecContext( out uint retFlags, out int isNtlmUsed); - [DllImport(Libraries.NetSecurityNative, EntryPoint = "NetSecurityNative_DeleteSecContext")] + [DllImport(Libraries.NetSecurityNative, EntryPoint="NetSecurityNative_DeleteSecContext")] internal static extern Status DeleteSecContext( out Status minorStatus, ref IntPtr contextHandle); @@ -112,17 +109,5 @@ internal enum GssFlags : uint GSS_C_EXTENDED_ERROR_FLAG = 0x4000, GSS_C_DELEG_POLICY_FLAG = 0x8000 } - - // This constructor is added to address the issue with net6 regarding - // Shim gss api on Linux to delay loading libgssapi_krb5.so - // issue https://github.com/dotnet/SqlClient/issues/1390 - // dotnet runtime issue https://github.com/dotnet/runtime/pull/55037 - static NetSecurityNative() - { - if (Environment.Version.Major >= 6) - { - EnsureGssInitialized(); - } - } } } 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 c538312ee9..3bf596e22c 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj @@ -283,9 +283,6 @@ Microsoft\Data\SqlClient\SqlEnums.cs - - Microsoft\Data\SqlClient\SqlError.cs - Microsoft\Data\SqlClient\SqlErrorCollection.cs @@ -367,9 +364,6 @@ Microsoft\Data\SqlClient\Server\ValueUtilsSmi.cs - - Microsoft\Data\SqlClient\Server\SqlSer.cs - Microsoft\Data\SqlClient\SignatureVerificationCache.cs @@ -497,9 +491,6 @@ Microsoft\Data\SqlClient\VirtualSecureModeEnclaveProvider.cs - - Microsoft\Data\SqlClient\NoneAttestationEnclaveProvider.cs - Microsoft\Data\SqlClient\VirtualSecureModeEnclaveProviderBase.cs @@ -519,6 +510,9 @@ + + + Resources\StringsHelper.NetCore.cs @@ -568,6 +562,7 @@ + @@ -584,6 +579,7 @@ + Microsoft\Data\SqlClient\SqlEnclaveSession.cs diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/LocalDBAPI.Windows.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/LocalDBAPI.Windows.cs index 1b4679bfe4..6ec654e3bf 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/LocalDBAPI.Windows.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/LocalDBAPI.Windows.cs @@ -22,13 +22,14 @@ private static IntPtr UserInstanceDLLHandle if (s_userInstanceDLLHandle == IntPtr.Zero) { SNINativeMethodWrapper.SNIQueryInfo(SNINativeMethodWrapper.QTypes.SNI_QUERY_LOCALDB_HMODULE, ref s_userInstanceDLLHandle); - if (s_userInstanceDLLHandle != IntPtr.Zero) + if(s_userInstanceDLLHandle != IntPtr.Zero) { SqlClientEventSource.Log.TryTraceEvent("LocalDBAPI.UserInstanceDLLHandle | LocalDB - handle obtained"); } else { - SNINativeMethodWrapper.SNIGetLastError(out SNINativeMethodWrapper.SNI_Error sniError); + SNINativeMethodWrapper.SNI_Error sniError; + SNINativeMethodWrapper.SNIGetLastError(out sniError); throw CreateLocalDBException(errorMessage: StringsHelper.GetString("LocalDB_FailedGetDLLHandle"), sniError: (int)sniError.sniError); } } diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/LocalDBAPI.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/LocalDBAPI.cs index ba2371c232..4f3fd13dce 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/LocalDBAPI.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/LocalDBAPI.cs @@ -10,37 +10,25 @@ namespace Microsoft.Data { internal static partial class LocalDBAPI { - private const string LocalDbPrefix = @"(localdb)\"; - private const string LocalDbPrefix_NP = @"np:\\.\pipe\LOCALDB#"; + private const string const_localDbPrefix = @"(localdb)\"; [UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Unicode)] private delegate int LocalDBFormatMessageDelegate(int hrLocalDB, uint dwFlags, uint dwLanguageId, StringBuilder buffer, ref uint buflen); // check if name is in format (localdb)\ and return instance name if it is - // localDB can also have a format of np:\\.\pipe\LOCALDB#\tsql\query internal static string GetLocalDbInstanceNameFromServerName(string serverName) { - if (serverName is not null) - { - // it can start with spaces if specified in quotes - // Memory allocation is reduced by using ReadOnlySpan - ReadOnlySpan input = serverName.AsSpan().Trim(); - if (input.StartsWith(LocalDbPrefix.AsSpan(), StringComparison.OrdinalIgnoreCase)) - { - input = input.Slice(LocalDbPrefix.Length); - if (!input.IsEmpty) - { - return input.ToString(); - } - } - else if (input.StartsWith(LocalDbPrefix_NP.AsSpan(), StringComparison.OrdinalIgnoreCase)) - { - return input.ToString(); - } - - } - return null; + if (serverName == null) + return null; + serverName = serverName.TrimStart(); // it can start with spaces if specified in quotes + if (!serverName.StartsWith(const_localDbPrefix, StringComparison.OrdinalIgnoreCase)) + return null; + string instanceName = serverName.Substring(const_localDbPrefix.Length).Trim(); + if (instanceName.Length == 0) + return null; + else + return instanceName; } } } diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIProxy.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIProxy.cs index 501a68e401..0af8441333 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIProxy.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIProxy.cs @@ -342,7 +342,8 @@ internal SNIError GetLastError() private static string GetLocalDBDataSource(string fullServerName, out bool error) { string localDBConnectionString = null; - string localDBInstance = DataSource.GetLocalDBInstance(fullServerName, out bool isBadLocalDBDataSource); + bool isBadLocalDBDataSource; + string localDBInstance = DataSource.GetLocalDBInstance(fullServerName, out isBadLocalDBDataSource); if (isBadLocalDBDataSource) { @@ -380,7 +381,6 @@ internal class DataSource private const string Slash = @"/"; private const string PipeToken = "pipe"; private const string LocalDbHost = "(localdb)"; - private const string LocalDbHost_NP = @"np:\\.\pipe\LOCALDB#"; private const string NamedPipeInstanceNameHeader = "mssql$"; private const string DefaultPipeName = "sql\\query"; @@ -482,9 +482,11 @@ private void PopulateProtocol() internal static string GetLocalDBInstance(string dataSource, out bool error) { string instanceName = null; + // ReadOnlySpan is not supported in netstandard 2.0, but installing System.Memory solves the issue ReadOnlySpan input = dataSource.AsSpan().TrimStart(); error = false; + // NetStandard 2.0 does not support passing a string to ReadOnlySpan if (input.StartsWith(LocalDbHost.AsSpan().Trim(), StringComparison.InvariantCultureIgnoreCase)) { @@ -505,11 +507,6 @@ internal static string GetLocalDBInstance(string dataSource, out bool error) error = true; } } - else if (input.StartsWith(LocalDbHost_NP.AsSpan().Trim(), StringComparison.InvariantCultureIgnoreCase)) - { - instanceName = input.Trim().ToString(); - } - return instanceName; } diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/Server/MetadataUtilsSmi.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/Server/MetadataUtilsSmi.cs index 85abc33550..3b42dbc6f7 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/Server/MetadataUtilsSmi.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/Server/MetadataUtilsSmi.cs @@ -391,8 +391,8 @@ internal static SqlDbType InferSqlDbTypeFromTypeCode(ExtendedClrTypeCode typeCod return s_extendedTypeCodeToSqlDbTypeMap[(int)typeCode + 1]; } - // Infer SqlDbType from Type in the general case. 2008-only (or later) features that need to - // infer types should use InferSqlDbTypeFromType_2008. + // Infer SqlDbType from Type in the general case. Katmai-only (or later) features that need to + // infer types should use InferSqlDbTypeFromType_Katmai. internal static SqlDbType InferSqlDbTypeFromType(Type type) { ExtendedClrTypeCode typeCode = DetermineExtendedTypeCodeFromType(type); @@ -409,12 +409,12 @@ internal static SqlDbType InferSqlDbTypeFromType(Type type) return returnType; } - // Inference rules changed for 2008-or-later-only cases. Only features that are guaranteed to be - // running against 2008 and don't have backward compat issues should call this code path. - // example: TVP's are a new 2008 feature (no back compat issues) so can infer DATETIME2 + // Inference rules changed for Katmai-or-later-only cases. Only features that are guaranteed to be + // running against Katmai and don't have backward compat issues should call this code path. + // example: TVP's are a new Katmai feature (no back compat issues) so can infer DATETIME2 // when mapping System.DateTime from DateTable or DbDataReader. DATETIME2 is better because // of greater range that can handle all DateTime values. - internal static SqlDbType InferSqlDbTypeFromType_2008(Type type) + internal static SqlDbType InferSqlDbTypeFromType_Katmai(Type type) { SqlDbType returnType = InferSqlDbTypeFromType(type); if (SqlDbType.DateTime == returnType) @@ -533,7 +533,7 @@ internal static bool IsCompatible(SmiMetaData firstMd, SqlMetaData secondMd) // Extract metadata for a single DataColumn internal static SmiExtendedMetaData SmiMetaDataFromDataColumn(DataColumn column, DataTable parent) { - SqlDbType dbType = InferSqlDbTypeFromType_2008(column.DataType); + SqlDbType dbType = InferSqlDbTypeFromType_Katmai(column.DataType); if (InvalidSqlDbType == dbType) { throw SQL.UnsupportedColumnTypeForSqlProvider(column.ColumnName, column.DataType.Name); @@ -733,7 +733,7 @@ internal static SmiExtendedMetaData SmiMetaDataFromSchemaTableRow(DataRow schema } Type colType = (Type)temp; - SqlDbType colDbType = InferSqlDbTypeFromType_2008(colType); + SqlDbType colDbType = InferSqlDbTypeFromType_Katmai(colType); if (InvalidSqlDbType == colDbType) { // Unknown through standard mapping, use VarBinary for columns that are Object typed, otherwise error diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Server/SqlSer.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/Server/SqlSer.cs similarity index 89% rename from src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Server/SqlSer.cs rename to src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/Server/SqlSer.cs index cf510834b6..c9f1536f50 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Server/SqlSer.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/Server/SqlSer.cs @@ -3,7 +3,7 @@ // See the LICENSE file in the project root for more information. using System; -using System.Collections.Concurrent; +using System.Collections; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; @@ -11,7 +11,7 @@ namespace Microsoft.Data.SqlClient.Server { - internal sealed class SerializationHelperSql9 + internal class SerializationHelperSql9 { // Don't let anyone create an instance of this class. private SerializationHelperSql9() { } @@ -28,8 +28,7 @@ private SerializationHelperSql9() { } internal static int SizeInBytes(object instance) { Type t = instance.GetType(); - - _ = GetFormat(t); + Format k = GetFormat(t); DummyStream stream = new DummyStream(); Serializer ser = GetSerializer(instance.GetType()); ser.Serialize(stream, instance); @@ -51,22 +50,20 @@ internal static void Serialize(Stream s, object instance) // // Use a per-thread cache, so that there are no synchronization // issues when accessing cache entries from multiple threads. - private static ConcurrentDictionary s_types2Serializers; + [ThreadStatic] + private static Hashtable s_types2Serializers; private static Serializer GetSerializer(Type t) { if (s_types2Serializers == null) - { - s_types2Serializers = new ConcurrentDictionary(); - } + s_types2Serializers = new Hashtable(); - Serializer s; - if (!s_types2Serializers.TryGetValue(t, out s)) + Serializer s = (Serializer)s_types2Serializers[t]; + if (s == null) { s = GetNewSerializer(t); s_types2Serializers[t] = s; } - return s; } @@ -140,8 +137,9 @@ private static object[] GetCustomAttributes(Type t) internal static SqlUserDefinedTypeAttribute GetUdtAttribute(Type t) { - SqlUserDefinedTypeAttribute udtAttr; + SqlUserDefinedTypeAttribute udtAttr = null; object[] attr = GetCustomAttributes(t); + if (attr != null && attr.Length == 1) { udtAttr = (SqlUserDefinedTypeAttribute)attr[0]; @@ -157,8 +155,9 @@ internal static SqlUserDefinedTypeAttribute GetUdtAttribute(Type t) private static Serializer GetNewSerializer(Type t) { SqlUserDefinedTypeAttribute udtAttr = GetUdtAttribute(t); - - switch (udtAttr.Format) + Format k = GetFormat(t); + + switch (k) { case Format.Native: return new NormalizedSerializer(t); @@ -166,7 +165,7 @@ private static Serializer GetNewSerializer(Type t) return new BinarySerializeSerializer(t); case Format.Unknown: // should never happen, but fall through default: - throw ADP.InvalidUserDefinedTypeSerializationFormat(udtAttr.Format); + throw ADP.InvalidUserDefinedTypeSerializationFormat(k); } } } @@ -184,12 +183,16 @@ internal abstract class Serializer internal sealed class NormalizedSerializer : Serializer { - private readonly BinaryOrderedUdtNormalizer _normalizer; - + private BinaryOrderedUdtNormalizer _normalizer; + private bool _isFixedSize; + private int _maxSize; + internal NormalizedSerializer(Type t) : base(t) { - _ = SerializationHelperSql9.GetUdtAttribute(t); + SqlUserDefinedTypeAttribute udtAttr = SerializationHelperSql9.GetUdtAttribute(t); _normalizer = new BinaryOrderedUdtNormalizer(t, true); + _isFixedSize = udtAttr.IsFixedLength; + _maxSize = _normalizer.Size; } public override void Serialize(Stream s, object o) => _normalizer.NormalizeTopObject(o, s); @@ -206,16 +209,7 @@ internal BinarySerializeSerializer(Type t) : base(t) public override void Serialize(Stream s, object o) { BinaryWriter w = new BinaryWriter(s); - -#if NETFRAMEWORK - if (o is SqlServer.Server.IBinarySerialize bs) - { - (bs).Write(w); - return; - } -#endif ((IBinarySerialize)o).Write(w); - } // Prevent inlining so that reflection calls are not moved @@ -226,17 +220,8 @@ public override object Deserialize(Stream s) { object instance = Activator.CreateInstance(_type); BinaryReader r = new BinaryReader(s); - -#if NETFRAMEWORK - if (instance is SqlServer.Server.IBinarySerialize bs) - { - bs.Read(r); - return instance; - } -#endif - ((IBinarySerialize)instance).Read(r); + ((IBinarySerialize)instance).Read(r); return instance; - } } diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/NoneAttestationEnclaveProvider.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SimulatorEnclaveProvider.NetCoreApp.cs similarity index 86% rename from src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/NoneAttestationEnclaveProvider.cs rename to src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SimulatorEnclaveProvider.NetCoreApp.cs index ff36d1604c..fdf6d67d54 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/NoneAttestationEnclaveProvider.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SimulatorEnclaveProvider.NetCoreApp.cs @@ -3,17 +3,21 @@ // See the LICENSE file in the project root for more information. using System; +using System.Collections.Generic; using System.Diagnostics; +using System.Linq; +using System.Runtime.Caching; using System.Security.Cryptography; +using System.Text; using System.Threading; +using System.Threading.Tasks; +using System.Collections.Concurrent; namespace Microsoft.Data.SqlClient { - internal class NoneAttestationEnclaveProvider : EnclaveProviderBase + internal class SimulatorEnclaveProvider : EnclaveProviderBase { private static readonly int EnclaveSessionHandleSize = 8; - private const int DiffieHellmanKeySize = 384; - private const int NoneAttestationProtocolId = 2; // When overridden in a derived class, looks up an existing enclave session information in the enclave session cache. // If the enclave provider doesn't implement enclave session caching, this method is expected to return null in the sqlEnclaveSession parameter. @@ -25,15 +29,18 @@ internal override void GetEnclaveSession(EnclaveSessionParameters enclaveSession // Gets the information that SqlClient subsequently uses to initiate the process of attesting the enclave and to establish a secure session with the enclave. internal override SqlEnclaveAttestationParameters GetAttestationParameters(string attestationUrl, byte[] customData, int customDataLength) { - ECDiffieHellman clientDHKey = KeyConverter.CreateECDiffieHellman(DiffieHellmanKeySize); - return new SqlEnclaveAttestationParameters(NoneAttestationProtocolId, Array.Empty(), clientDHKey); + // The key derivation function and hash algorithm name are specified when key derivation is performed + ECDiffieHellman clientDHKey = ECDiffieHellman.Create(); + clientDHKey.KeySize = 384; + + return new SqlEnclaveAttestationParameters(2, new byte[] { }, clientDHKey); } - // When overridden in a derived class, performs enclave attestation, generates a symmetric key for the session, creates an enclave session and stores the session information in the cache. + // When overridden in a derived class, performs enclave attestation, generates a symmetric key for the session, creates a an enclave session and stores the session information in the cache. internal override void CreateEnclaveSession(byte[] attestationInfo, ECDiffieHellman clientDHKey, EnclaveSessionParameters enclaveSessionParameters, byte[] customData, int customDataLength, out SqlEnclaveSession sqlEnclaveSession, out long counter) { - // for None attestation: enclave does not send public key, and sends an empty attestation info - // The only non-trivial content it sends is the session setup info (DH pubkey of enclave) + ////for simulator: enclave does not send public key, and sends an empty attestation info + //// The only non-trivial content it sends is the session setup info (DH pubkey of enclave) sqlEnclaveSession = null; counter = 0; @@ -46,14 +53,14 @@ internal override void CreateEnclaveSession(byte[] attestationInfo, ECDiffieHell { if (!string.IsNullOrEmpty(enclaveSessionParameters.AttestationUrl)) { - // Read AttestationInfo + ////Read AttestationInfo int attestationInfoOffset = 0; uint sizeOfTrustedModuleAttestationInfoBuffer = BitConverter.ToUInt32(attestationInfo, attestationInfoOffset); attestationInfoOffset += sizeof(UInt32); int sizeOfTrustedModuleAttestationInfoBufferInt = checked((int)sizeOfTrustedModuleAttestationInfoBuffer); Debug.Assert(sizeOfTrustedModuleAttestationInfoBuffer == 0); - // read secure session info + ////read secure session info uint sizeOfSecureSessionInfoResponse = BitConverter.ToUInt32(attestationInfo, attestationInfoOffset); attestationInfoOffset += sizeof(UInt32); diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlBuffer.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlBuffer.cs index 77c954b88f..725a59fb8d 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlBuffer.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlBuffer.cs @@ -126,7 +126,7 @@ private SqlBuffer(SqlBuffer value) _object = value._object; } - internal bool IsEmpty => _type == StorageType.Empty; + internal bool IsEmpty => (StorageType.Empty == _type); internal bool IsNull => _isNull; @@ -386,6 +386,7 @@ internal Guid Guid return ((SqlGuid)_object).Value; } return (Guid)Value; + } set { @@ -499,7 +500,7 @@ internal string String } // use static list of format strings indexed by scale for perf - private static readonly string[] s_sql2008DateTimeOffsetFormatByScale = new string[] { + private static readonly string[] s_katmaiDateTimeOffsetFormatByScale = new string[] { "yyyy-MM-dd HH:mm:ss zzz", "yyyy-MM-dd HH:mm:ss.f zzz", "yyyy-MM-dd HH:mm:ss.ff zzz", @@ -510,7 +511,7 @@ internal string String "yyyy-MM-dd HH:mm:ss.fffffff zzz", }; - private static readonly string[] s_sql2008DateTime2FormatByScale = new string[] { + private static readonly string[] s_katmaiDateTime2FormatByScale = new string[] { "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm:ss.f", "yyyy-MM-dd HH:mm:ss.ff", @@ -521,7 +522,7 @@ internal string String "yyyy-MM-dd HH:mm:ss.fffffff", }; - private static readonly string[] s_sql2008TimeFormatByScale = new string[] { + private static readonly string[] s_katmaiTimeFormatByScale = new string[] { "HH:mm:ss", "HH:mm:ss.f", "HH:mm:ss.ff", @@ -532,7 +533,7 @@ internal string String "HH:mm:ss.fffffff", }; - internal string Sql2008DateTimeString + internal string KatmaiDateTimeString { get { @@ -545,24 +546,24 @@ internal string Sql2008DateTimeString if (StorageType.Time == _type) { byte scale = _value._timeInfo._scale; - return new DateTime(_value._timeInfo._ticks).ToString(s_sql2008TimeFormatByScale[scale], DateTimeFormatInfo.InvariantInfo); + return new DateTime(_value._timeInfo._ticks).ToString(s_katmaiTimeFormatByScale[scale], DateTimeFormatInfo.InvariantInfo); } if (StorageType.DateTime2 == _type) { byte scale = _value._dateTime2Info._timeInfo._scale; - return DateTime.ToString(s_sql2008DateTime2FormatByScale[scale], DateTimeFormatInfo.InvariantInfo); + return DateTime.ToString(s_katmaiDateTime2FormatByScale[scale], DateTimeFormatInfo.InvariantInfo); } if (StorageType.DateTimeOffset == _type) { DateTimeOffset dto = DateTimeOffset; byte scale = _value._dateTimeOffsetInfo._dateTime2Info._timeInfo._scale; - return dto.ToString(s_sql2008DateTimeOffsetFormatByScale[scale], DateTimeFormatInfo.InvariantInfo); + return dto.ToString(s_katmaiDateTimeOffsetFormatByScale[scale], DateTimeFormatInfo.InvariantInfo); } return (string)Value; // anything else we haven't thought of goes through boxing. } } - internal SqlString Sql2008DateTimeSqlString + internal SqlString KatmaiDateTimeSqlString { get { @@ -575,7 +576,7 @@ internal SqlString Sql2008DateTimeSqlString { return SqlString.Null; } - return new SqlString(Sql2008DateTimeString); + return new SqlString(KatmaiDateTimeString); } return (SqlString)SqlValue; // anything else we haven't thought of goes through boxing. } @@ -1335,13 +1336,13 @@ private void ThrowIfNull() // where typeof(T) == typeof(field) // 1) RyuJIT will recognize the pattern of (T)(object)T as being redundant and eliminate // the T and object casts leaving T, so while this looks like it will put every value type instance in a box the - // generated assembly will be short and direct + // enerated assembly will be short and direct // 2) another jit may not recognize the pattern and should emit the code as seen. this will box and then unbox the // value type which is no worse than the mechanism that this code replaces // where typeof(T) != typeof(field) // the jit will emit all the cast operations as written. this will put the value into a box and then attempt to - // cast it, because it is an object no conversions are used and this will generate the desired InvalidCastException - // for example users cannot widen a short to an int preserving external expectations + // cast it, because it is an object even no conversions are use and this will generate the desired InvalidCastException + // so users cannot widen a short to an int preserving external expectations internal T ByteAs() { @@ -1385,4 +1386,4 @@ internal T SingleAs() return (T)(object)_value._single; } } -} +}// namespace diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlBulkCopy.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlBulkCopy.cs index d469427274..8d01563b37 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlBulkCopy.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlBulkCopy.cs @@ -422,7 +422,7 @@ private string CreateInitialQuery() TDSCommand = "select @@trancount; SET FMTONLY ON select * from " + ADP.BuildMultiPartName(parts) + " SET FMTONLY OFF "; string TableCollationsStoredProc; - if (_connection.Is2008OrNewer) + if (_connection.IsKatmaiOrNewer) { TableCollationsStoredProc = "sp_tablecollations_100"; } @@ -2184,7 +2184,7 @@ private Task ReadWriteColumnValueAsync(int col) // Target type shouldn't be encrypted Debug.Assert(!metadata.isEncrypted, "Can't encrypt SQL Variant type"); SqlBuffer.StorageType variantInternalType = SqlBuffer.StorageType.Empty; - if ((_sqlDataReaderRowSource != null) && (_connection.Is2008OrNewer)) + if ((_sqlDataReaderRowSource != null) && (_connection.IsKatmaiOrNewer)) { variantInternalType = _sqlDataReaderRowSource.GetVariantInternalStorageType(_sortedColumnMappings[col]._sourceColumnOrdinal); } 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 aef1ab92b6..85fe6156ab 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 @@ -2969,8 +2969,8 @@ private enum ProcParamsColIndex { ParameterName = 0, ParameterType, - DataType, // obsolete in 2008, use ManagedDataType instead - ManagedDataType, // new in 2008 + DataType, // obsolete in katmai, use ManagedDataType instead + ManagedDataType, // new in katmai CharacterMaximumLength, NumericPrecision, NumericScale, @@ -2980,16 +2980,16 @@ private enum ProcParamsColIndex XmlSchemaCollectionCatalogName, XmlSchemaCollectionSchemaName, XmlSchemaCollectionName, - UdtTypeName, // obsolete in 2008. Holds the actual typename if UDT, since TypeName didn't back then. - DateTimeScale // new in 2008 + UdtTypeName, // obsolete in Katmai. Holds the actual typename if UDT, since TypeName didn't back then. + DateTimeScale // new in Katmai }; - // 2005- column ordinals (this array indexed by ProcParamsColIndex - internal static readonly string[] PreSql2008ProcParamsNames = new string[] { + // Yukon- column ordinals (this array indexed by ProcParamsColIndex + internal static readonly string[] PreKatmaiProcParamsNames = new string[] { "PARAMETER_NAME", // ParameterName, "PARAMETER_TYPE", // ParameterType, "DATA_TYPE", // DataType - null, // ManagedDataType, introduced in 2008 + null, // ManagedDataType, introduced in Katmai "CHARACTER_MAXIMUM_LENGTH", // CharacterMaximumLength, "NUMERIC_PRECISION", // NumericPrecision, "NUMERIC_SCALE", // NumericScale, @@ -3000,14 +3000,14 @@ private enum ProcParamsColIndex "XML_SCHEMANAME", // XmlSchemaCollectionSchemaName, "XML_SCHEMACOLLECTIONNAME", // XmlSchemaCollectionName "UDT_NAME", // UdtTypeName - null, // Scale for datetime types with scale, introduced in 2008 + null, // Scale for datetime types with scale, introduced in Katmai }; - // 2008+ column ordinals (this array indexed by ProcParamsColIndex - internal static readonly string[] Sql2008ProcParamsNames = new string[] { + // Katmai+ column ordinals (this array indexed by ProcParamsColIndex + internal static readonly string[] KatmaiProcParamsNames = new string[] { "PARAMETER_NAME", // ParameterName, "PARAMETER_TYPE", // ParameterType, - null, // DataType, removed from 2008+ + null, // DataType, removed from Katmai+ "MANAGED_DATA_TYPE", // ManagedDataType, "CHARACTER_MAXIMUM_LENGTH", // CharacterMaximumLength, "NUMERIC_PRECISION", // NumericPrecision, @@ -3018,7 +3018,7 @@ private enum ProcParamsColIndex "XML_CATALOGNAME", // XmlSchemaCollectionCatalogName, "XML_SCHEMANAME", // XmlSchemaCollectionSchemaName, "XML_SCHEMACOLLECTIONNAME", // XmlSchemaCollectionName - null, // UdtTypeName, removed from 2008+ + null, // UdtTypeName, removed from Katmai+ "SS_DATETIME_PRECISION", // Scale for datetime types with scale }; @@ -3053,7 +3053,7 @@ internal void DeriveParameters() StringBuilder cmdText = new StringBuilder(); // Build call for sp_procedure_params_rowset built of unquoted values from user: - // [user server, if provided].[user catalog, else current database].[sys if 2005, else blank].[sp_procedure_params_rowset] + // [user server, if provided].[user catalog, else current database].[sys if Yukon, else blank].[sp_procedure_params_rowset] // Server - pass only if user provided. if (!string.IsNullOrEmpty(parsedSProc[0])) @@ -3070,16 +3070,16 @@ internal void DeriveParameters() SqlCommandSet.BuildStoredProcedureName(cmdText, parsedSProc[1]); cmdText.Append("."); - // Schema - only if 2005, and then only pass sys. Also - pass managed version of sproc - // for 2005, else older sproc. + // Schema - only if Yukon, and then only pass sys. Also - pass managed version of sproc + // for Yukon, else older sproc. string[] colNames; bool useManagedDataType; - if (Connection.Is2008OrNewer) + if (Connection.IsKatmaiOrNewer) { // Procedure - [sp_procedure_params_managed] cmdText.Append("[sys].[").Append(TdsEnums.SP_PARAMS_MGD10).Append("]"); - colNames = Sql2008ProcParamsNames; + colNames = KatmaiProcParamsNames; useManagedDataType = true; } else @@ -3087,7 +3087,7 @@ internal void DeriveParameters() // Procedure - [sp_procedure_params_managed] cmdText.Append("[sys].[").Append(TdsEnums.SP_PARAMS_MANAGED).Append("]"); - colNames = PreSql2008ProcParamsNames; + colNames = PreKatmaiProcParamsNames; useManagedDataType = false; } @@ -3143,7 +3143,7 @@ internal void DeriveParameters() { p.SqlDbType = (SqlDbType)(short)r[colNames[(int)ProcParamsColIndex.ManagedDataType]]; - // 2005 didn't have as accurate of information as we're getting for 2008, so re-map a couple of + // Yukon didn't have as accurate of information as we're getting for Katmai, so re-map a couple of // types for backward compatability. switch (p.SqlDbType) { @@ -3177,9 +3177,9 @@ internal void DeriveParameters() { int size = (int)a; - // Map MAX sizes correctly. The 2008 server-side proc sends 0 for these instead of -1. - // Should be fixed on the 2008 side, but would likely hold up the RI, and is safer to fix here. - // If we can get the server-side fixed before shipping 2008, we can remove this mapping. + // Map MAX sizes correctly. The Katmai server-side proc sends 0 for these instead of -1. + // Should be fixed on the Katmai side, but would likely hold up the RI, and is safer to fix here. + // If we can get the server-side fixed before shipping Katmai, we can remove this mapping. if (0 == size && (p.SqlDbType == SqlDbType.NVarChar || p.SqlDbType == SqlDbType.VarBinary || @@ -3221,7 +3221,7 @@ internal void DeriveParameters() // type name for Structured types (same as for Udt's except assign p.TypeName instead of p.UdtTypeName if (SqlDbType.Structured == p.SqlDbType) { - Debug.Assert(_activeConnection.Is2008OrNewer, "Invalid datatype token received from pre-2008 server"); + Debug.Assert(_activeConnection.IsKatmaiOrNewer, "Invalid datatype token received from pre-katmai server"); //read the type name p.TypeName = r[colNames[(int)ProcParamsColIndex.TypeCatalogName]] + "." + 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 bcb9378643..3946a09f33 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 @@ -1899,15 +1899,15 @@ internal bool HasLocalTransactionFromAPI } - internal bool Is2008OrNewer + internal bool IsKatmaiOrNewer { get { if (_currentReconnectionTask != null) { // holds true even if task is completed - return true; // if CR is enabled, connection, if established, will be 2008+ + return true; // if CR is enabled, connection, if established, will be Katmai+ } - return GetOpenTdsConnection().Is2008OrNewer; + return GetOpenTdsConnection().IsKatmaiOrNewer; } } diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlDataReader.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlDataReader.cs index a801697d8f..f691da0e7a 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlDataReader.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlDataReader.cs @@ -87,9 +87,14 @@ internal class SharedState private Task _currentTask; private Snapshot _snapshot; + private CancellationTokenSource _cancelAsyncOnCloseTokenSource; private CancellationToken _cancelAsyncOnCloseToken; + // Used for checking if the Type parameter provided to GetValue is an INullable + internal static readonly Type _typeofINullable = typeof(INullable); + private static readonly Type s_typeofSqlString = typeof(SqlString); + private SqlSequentialStream _currentStream; private SqlSequentialTextReader _currentTextReader; @@ -552,7 +557,7 @@ internal DataTable BuildSchemaTable() schemaRow[nonVersionedProviderType] = (int)(col.cipherMD != null ? col.baseTI.type : col.type); // SqlDbType enum value - does not change with TypeSystem. schemaRow[dataTypeName] = GetDataTypeNameInternal(col); - if (_typeSystem <= SqlConnectionString.TypeSystem.SQLServer2005 && col.Is2008DateTimeType) + if (_typeSystem <= SqlConnectionString.TypeSystem.SQLServer2005 && col.IsNewKatmaiDateTimeType) { schemaRow[providerType] = SqlDbType.NVarChar; switch (col.type) @@ -595,12 +600,12 @@ internal DataTable BuildSchemaTable() if (col.type == SqlDbType.Udt) { // Additional metadata for UDTs. - Debug.Assert(Connection.Is2008OrNewer, "Invalid Column type received from the server"); + Debug.Assert(Connection.IsKatmaiOrNewer, "Invalid Column type received from the server"); schemaRow[udtAssemblyQualifiedName] = col.udt?.AssemblyQualifiedName; } else if (col.type == SqlDbType.Xml) { // Additional metadata for Xml. - Debug.Assert(Connection.Is2008OrNewer, "Invalid DataType (Xml) for the column"); + Debug.Assert(Connection.IsKatmaiOrNewer, "Invalid DataType (Xml) for the column"); schemaRow[xmlSchemaCollectionDatabase] = col.xmlSchemaCollection?.Database; schemaRow[xmlSchemaCollectionOwningSchema] = col.xmlSchemaCollection?.OwningSchema; schemaRow[xmlSchemaCollectionName] = col.xmlSchemaCollection?.Name; @@ -635,7 +640,7 @@ internal DataTable BuildSchemaTable() schemaRow[precision] = col.metaType.Precision; } - if (_typeSystem <= SqlConnectionString.TypeSystem.SQLServer2005 && col.Is2008DateTimeType) + if (_typeSystem <= SqlConnectionString.TypeSystem.SQLServer2005 && col.IsNewKatmaiDateTimeType) { schemaRow[scale] = MetaType.MetaNVarChar.Scale; } @@ -1170,7 +1175,7 @@ private string GetDataTypeNameInternal(_SqlMetaData metaData) { string dataTypeName = null; - if (_typeSystem <= SqlConnectionString.TypeSystem.SQLServer2005 && metaData.Is2008DateTimeType) + if (_typeSystem <= SqlConnectionString.TypeSystem.SQLServer2005 && metaData.IsNewKatmaiDateTimeType) { dataTypeName = MetaType.MetaNVarChar.TypeName; } @@ -1252,9 +1257,9 @@ private Type GetFieldTypeInternal(_SqlMetaData metaData) { Type fieldType = null; - if (_typeSystem <= SqlConnectionString.TypeSystem.SQLServer2005 && metaData.Is2008DateTimeType) + if (_typeSystem <= SqlConnectionString.TypeSystem.SQLServer2005 && metaData.IsNewKatmaiDateTimeType) { - // Return 2008 types as string + // Return katmai types as string fieldType = MetaType.MetaNVarChar.ClassType; } else if (_typeSystem <= SqlConnectionString.TypeSystem.SQLServer2005 && metaData.IsLargeUdt) @@ -1360,7 +1365,7 @@ private Type GetProviderSpecificFieldTypeInternal(_SqlMetaData metaData) { Type providerSpecificFieldType = null; - if (_typeSystem <= SqlConnectionString.TypeSystem.SQLServer2005 && metaData.Is2008DateTimeType) + if (_typeSystem <= SqlConnectionString.TypeSystem.SQLServer2005 && metaData.IsNewKatmaiDateTimeType) { providerSpecificFieldType = MetaType.MetaNVarChar.SqlType; } @@ -2284,7 +2289,7 @@ override public DateTime GetDateTime(int i) DateTime dt = _data[i].DateTime; // This accessor can be called for regular DateTime column. In this case we should not throw - if (_typeSystem <= SqlConnectionString.TypeSystem.SQLServer2005 && _metaData[i].Is2008DateTimeType) + if (_typeSystem <= SqlConnectionString.TypeSystem.SQLServer2005 && _metaData[i].IsNewKatmaiDateTimeType) { // TypeSystem.SQLServer2005 or less @@ -2382,10 +2387,10 @@ virtual public SqlChars GetSqlChars(int i) { ReadColumn(i); SqlString data; - // Convert 2008 types to string - if (_typeSystem <= SqlConnectionString.TypeSystem.SQLServer2005 && _metaData[i].Is2008DateTimeType) + // Convert Katmai types to string + if (_typeSystem <= SqlConnectionString.TypeSystem.SQLServer2005 && _metaData[i].IsNewKatmaiDateTimeType) { - data = _data[i].Sql2008DateTimeSqlString; + data = _data[i].KatmaiDateTimeSqlString; } else { @@ -2462,9 +2467,9 @@ virtual public SqlString GetSqlString(int i) { ReadColumn(i); - if (_typeSystem <= SqlConnectionString.TypeSystem.SQLServer2005 && _metaData[i].Is2008DateTimeType) + if (_typeSystem <= SqlConnectionString.TypeSystem.SQLServer2005 && _metaData[i].IsNewKatmaiDateTimeType) { - return _data[i].Sql2008DateTimeSqlString; + return _data[i].KatmaiDateTimeSqlString; } return _data[i].SqlString; @@ -2541,10 +2546,10 @@ private object GetSqlValueFromSqlBufferInternal(SqlBuffer data, _SqlMetaData met { Debug.Assert(!data.IsEmpty || data.IsNull || metaData.type == SqlDbType.Timestamp, "Data has been read, but the buffer is empty"); - // Convert 2008 types to string - if (_typeSystem <= SqlConnectionString.TypeSystem.SQLServer2005 && metaData.Is2008DateTimeType) + // Convert Katmai types to string + if (_typeSystem <= SqlConnectionString.TypeSystem.SQLServer2005 && metaData.IsNewKatmaiDateTimeType) { - return data.Sql2008DateTimeSqlString; + return data.KatmaiDateTimeSqlString; } else if (_typeSystem <= SqlConnectionString.TypeSystem.SQLServer2005 && metaData.IsLargeUdt) { @@ -2621,10 +2626,10 @@ override public string GetString(int i) { ReadColumn(i); - // Convert 2008 value to string if type system knob is 2005 or earlier - if (_typeSystem <= SqlConnectionString.TypeSystem.SQLServer2005 && _metaData[i].Is2008DateTimeType) + // Convert katmai value to string if type system knob is 2005 or earlier + if (_typeSystem <= SqlConnectionString.TypeSystem.SQLServer2005 && _metaData[i].IsNewKatmaiDateTimeType) { - return _data[i].Sql2008DateTimeString; + return _data[i].KatmaiDateTimeString; } return _data[i].String; @@ -2731,7 +2736,7 @@ private object GetValueFromSqlBufferInternal(SqlBuffer data, _SqlMetaData metaDa { Debug.Assert(!data.IsEmpty || data.IsNull || metaData.type == SqlDbType.Timestamp, "Data has been read, but the buffer is empty"); - if (_typeSystem <= SqlConnectionString.TypeSystem.SQLServer2005 && metaData.Is2008DateTimeType) + if (_typeSystem <= SqlConnectionString.TypeSystem.SQLServer2005 && metaData.IsNewKatmaiDateTimeType) { if (data.IsNull) { @@ -2739,7 +2744,7 @@ private object GetValueFromSqlBufferInternal(SqlBuffer data, _SqlMetaData metaDa } else { - return data.Sql2008DateTimeString; + return data.KatmaiDateTimeString; } } else if (_typeSystem <= SqlConnectionString.TypeSystem.SQLServer2005 && metaData.IsLargeUdt) @@ -2835,11 +2840,11 @@ private T GetFieldValueFromSqlBufferInternal(SqlBuffer data, _SqlMetaData met { return (T)(object)data.Decimal; } - else if (typeof(T) == typeof(DateTimeOffset) && dataType == typeof(DateTimeOffset) && _typeSystem > SqlConnectionString.TypeSystem.SQLServer2005 && metaData.Is2008DateTimeType) + else if (typeof(T) == typeof(DateTimeOffset) && dataType == typeof(DateTimeOffset) && _typeSystem > SqlConnectionString.TypeSystem.SQLServer2005 && metaData.IsNewKatmaiDateTimeType) { return (T)(object)data.DateTimeOffset; } - else if (typeof(T) == typeof(DateTime) && dataType == typeof(DateTime) && _typeSystem > SqlConnectionString.TypeSystem.SQLServer2005 && metaData.Is2008DateTimeType) + else if (typeof(T) == typeof(DateTime) && dataType == typeof(DateTime) && _typeSystem > SqlConnectionString.TypeSystem.SQLServer2005 && metaData.IsNewKatmaiDateTimeType) { return (T)(object)data.DateTime; } @@ -2950,7 +2955,7 @@ private T GetFieldValueFromSqlBufferInternal(SqlBuffer data, _SqlMetaData met { // If its a SQL Type or Nullable UDT object rawValue = GetSqlValueFromSqlBufferInternal(data, metaData); - if (typeof(T) == typeof(SqlString)) + if (typeof(T) == s_typeofSqlString) { // Special case: User wants SqlString, but we have a SqlXml // SqlXml can not be typecast into a SqlString, but we need to support SqlString on XML Types - so do a manual conversion @@ -2981,7 +2986,6 @@ private T GetFieldValueFromSqlBufferInternal(SqlBuffer data, _SqlMetaData met } catch (InvalidCastException) when (data.IsNull) { - // If the value was actually null, then we should throw a SqlNullValue instead throw SQL.SqlNullValue(); } @@ -5740,7 +5744,7 @@ private ReadOnlyCollection BuildColumnSchema() _SqlMetaData col = md[i]; SqlDbColumn dbColumn = new SqlDbColumn(md[i]); - if (_typeSystem <= SqlConnectionString.TypeSystem.SQLServer2005 && col.Is2008DateTimeType) + if (_typeSystem <= SqlConnectionString.TypeSystem.SQLServer2005 && col.IsNewKatmaiDateTimeType) { dbColumn.SqlNumericScale = MetaType.MetaNVarChar.Scale; } diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlError.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlError.cs new file mode 100644 index 0000000000..967cf6acf8 --- /dev/null +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlError.cs @@ -0,0 +1,72 @@ +// 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; + +namespace Microsoft.Data.SqlClient +{ + /// + public sealed class SqlError + { + internal SqlError(int infoNumber, byte errorState, byte errorClass, string server, string errorMessage, string procedure, int lineNumber, uint win32ErrorCode, Exception exception = null) + : this(infoNumber, errorState, errorClass, server, errorMessage, procedure, lineNumber, exception) + { + Win32ErrorCode = (int)win32ErrorCode; + } + + internal SqlError(int infoNumber, byte errorState, byte errorClass, string server, string errorMessage, string procedure, int lineNumber, Exception exception = null) + { + Number = infoNumber; + State = errorState; + Class = errorClass; + Server = server; + Message = errorMessage; + Procedure = procedure; + LineNumber = lineNumber; + Win32ErrorCode = 0; + Exception = exception; + if (errorClass != 0) + { + SqlClientEventSource.Log.TryTraceEvent("SqlError.ctor | ERR | Info Number {0}, Error State {1}, Error Class {2}, Error Message '{3}', Procedure '{4}', Line Number {5}", infoNumber, (int)errorState, (int)errorClass, errorMessage, procedure ?? "None", (int)lineNumber); + } + } + + /// + // There is no exception stack included because the correct exception stack is only available + // on SqlException, and to obtain that the SqlError would have to have backpointers all the + // way back to SqlException. If the user needs a call stack, they can obtain it on SqlException. + public override string ToString() + { + return typeof(SqlError).ToString() + ": " + Message; // since this is sealed so we can change GetType to typeof + } + + /// + public string Source { get; private set; } = TdsEnums.SQL_PROVIDER_NAME; + + /// + public int Number { get; private set; } + + /// + public byte State { get; private set; } + + /// + public byte Class { get; private set; } + + /// + public string Server { get; private set; } + + /// + public string Message { get; private set; } + + /// + public string Procedure { get; private set; } + + /// + public int LineNumber { get; private set; } + + internal int Win32ErrorCode { get; private set; } + + internal Exception Exception { get; private set; } + } +} diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlInternalConnection.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlInternalConnection.cs index b863db3cba..fbc4d6f9b7 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlInternalConnection.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlInternalConnection.cs @@ -145,7 +145,7 @@ abstract internal bool IsLockedForBulkCopy } - abstract internal bool Is2008OrNewer + abstract internal bool IsKatmaiOrNewer { get; } @@ -337,7 +337,7 @@ private void EnlistNonNull(Transaction tx) SqlClientEventSource.Log.TryAdvancedTraceEvent("SqlInternalConnection.EnlistNonNull | ADV | Object {0}, Transaction Id {1}, attempting to delegate.", ObjectID, tx?.TransactionInformation?.LocalIdentifier); bool hasDelegatedTransaction = false; - // Promotable transactions are only supported on 2005 + // Promotable transactions are only supported on Yukon // servers or newer. SqlDelegatedTransaction delegatedTransaction = new SqlDelegatedTransaction(this, tx); @@ -469,17 +469,17 @@ private void EnlistNonNull(Transaction tx) EnlistedTransaction = tx; // Tell the base class about our enlistment - // If we're on a 2005 or newer server, and we delegate the + // If we're on a Yukon or newer server, and we delegate the // transaction successfully, we will have done a begin transaction, // which produces a transaction id that we should execute all requests // on. The TdsParser or SmiEventSink will store this information as // the current transaction. // - // Likewise, propagating a transaction to a 2005 or newer server will + // Likewise, propagating a transaction to a Yukon or newer server will // produce a transaction id that The TdsParser or SmiEventSink will // store as the current transaction. // - // In either case, when we're working with a 2005 or newer server + // In either case, when we're working with a Yukon or newer server // we better have a current transaction by now. Debug.Assert(null != CurrentTransaction, "delegated/enlisted transaction with null current transaction?"); @@ -511,7 +511,7 @@ internal void EnlistNull() // which causes the TdsParser or SmiEventSink should to clear the // current transaction. // - // In either case, when we're working with a 2005 or newer server + // In either case, when we're working with a Yukon or newer server // we better not have a current transaction at this point. Debug.Assert(null == CurrentTransaction, "unenlisted transaction with non-null current transaction?"); // verify it! @@ -539,7 +539,7 @@ override public void EnlistTransaction(Transaction transaction) // If a connection is already enlisted in a DTC transaction and you // try to enlist in another one, in 7.0 the existing DTC transaction // would roll back and then the connection would enlist in the new - // one. In SQL 2000 & 2005, when you enlist in a DTC transaction + // one. In SQL 2000 & Yukon, when you enlist in a DTC transaction // while the connection is already enlisted in a DTC transaction, // the connection simply switches enlistments. Regardless, simply // enlist in the user specified distributed transaction. This diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.cs index dcbc62ef0d..484e2233a9 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.cs @@ -636,15 +636,15 @@ internal protected override bool IsNonPoolableTransactionRoot { get { - return IsTransactionRoot && (!Is2008OrNewer || null == Pool); + return IsTransactionRoot && (!IsKatmaiOrNewer || null == Pool); } } - internal override bool Is2008OrNewer + internal override bool IsKatmaiOrNewer { get { - return _parser.Is2008OrNewer; + return _parser.IsKatmaiOrNewer; } } @@ -934,7 +934,7 @@ private void ResetConnection() if (_fResetConnection) { - // Ensure we are either going against 2000, or we are not enlisted in a + // Ensure we are either going against shiloh, or we are not enlisted in a // distributed transaction - otherwise don't reset! // Prepare the parser for the connection reset - the next time a trip // to the server is made. @@ -1001,11 +1001,11 @@ internal override void ExecuteTransaction(TransactionRequest transactionRequest, string transactionName = (null == name) ? string.Empty : name; - ExecuteTransaction2005(transactionRequest, transactionName, iso, internalTransaction, isDelegateControlRequest); + ExecuteTransactionYukon(transactionRequest, transactionName, iso, internalTransaction, isDelegateControlRequest); } - internal void ExecuteTransaction2005( + internal void ExecuteTransactionYukon( TransactionRequest transactionRequest, string transactionName, System.Data.IsolationLevel iso, @@ -1068,7 +1068,7 @@ bool isDelegateControlRequest requestType = TdsEnums.TransactionManagerRequestType.Commit; break; case TransactionRequest.IfRollback: - // Map IfRollback to Rollback since with 2005 and beyond we should never need + // Map IfRollback to Rollback since with Yukon and beyond we should never need // the if since the server will inform us when transactions have completed // as a result of an error on the server. case TransactionRequest.Rollback: @@ -1124,7 +1124,7 @@ bool isDelegateControlRequest } if (internalTransaction.OpenResultsCount != 0) { - SqlClientEventSource.Log.TryTraceEvent(" {0}, Connection is marked to be doomed when closed. Transaction ended with OpenResultsCount {1} > 0, MARSOn {2}", + SqlClientEventSource.Log.TryTraceEvent(" {0}, Connection is marked to be doomed when closed. Transaction ended with OpenResultsCount {1} > 0, MARSOn {2}", ObjectID, internalTransaction.OpenResultsCount, _parser.MARSOn); @@ -2065,7 +2065,7 @@ internal void OnEnvChange(SqlEnvChange rec) break; case TdsEnums.ENV_TRANSACTIONMANAGERADDRESS: - // For now we skip these 2005 only env change notifications + // For now we skip these Yukon only env change notifications break; case TdsEnums.ENV_SPRESETCONNECTIONACK: diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlInternalTransaction.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlInternalTransaction.cs index 5d706c6c0a..408dba0645 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlInternalTransaction.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlInternalTransaction.cs @@ -269,9 +269,9 @@ internal void CloseFromConnection() { if (processFinallyBlock) { - // Always ensure we're zombied; 2005 will send an EnvChange that + // Always ensure we're zombied; Yukon will send an EnvChange that // will cause the zombie, but only if we actually go to the wire; - // 7.0 and 2000 won't send the env change, so we have to handle + // Sphinx and Shiloh won't send the env change, so we have to handle // them ourselves. Zombie(); } @@ -498,7 +498,7 @@ internal void Zombie() // NOTE: we'll be called from the TdsParser when it gets appropriate // ENVCHANGE events that indicate the transaction has completed, however - // we cannot rely upon those events occurring in the case of pre-2005 + // we cannot rely upon those events occurring in the case of pre-Yukon // servers (and when we don't go to the wire because the connection // is broken) so we can also be called from the Commit/Rollback/Save // methods to handle that case as well. diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlParameter.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlParameter.cs index 9845a03aa7..cc919a89e5 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlParameter.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlParameter.cs @@ -1988,7 +1988,7 @@ internal MetaType ValidateTypeLengths() else { // Notes: - // Elevation from (n)(var)char (4001+) to (n)text succeeds without failure only with 2005 and greater. + // Elevation from (n)(var)char (4001+) to (n)text succeeds without failure only with Yukon and greater. // it fails in sql server 2000 maxSizeInBytes = (sizeInCharacters > actualSizeInBytes) ? sizeInCharacters : actualSizeInBytes; } 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 2eecfdc8cc..f1852c24f4 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 @@ -89,7 +89,7 @@ override public IsolationLevel IsolationLevel } } - private bool Is2005PartialZombie + private bool IsYukonPartialZombie { get { @@ -182,7 +182,7 @@ protected override void Dispose(bool disposing) { if (disposing) { - if (!IsZombied && !Is2005PartialZombie) + if (!IsZombied && !IsYukonPartialZombie) { _internalTransaction.Dispose(); } @@ -195,11 +195,11 @@ override public void Rollback() { using (DiagnosticTransactionScope diagnosticScope = s_diagnosticListener.CreateTransactionRollbackScope(_isolationLevel, _connection, InternalTransaction, null)) { - if (Is2005PartialZombie) + if (IsYukonPartialZombie) { // Put something in the trace in case a customer has an issue SqlClientEventSource.Log.TryAdvancedTraceEvent("SqlTransaction.Rollback | ADV | Object Id {0}, partial zombie no rollback required", ObjectID); - _internalTransaction = null; // 2005 zombification + _internalTransaction = null; // yukon zombification } else { @@ -291,7 +291,7 @@ public void Save(string savePointName) internal void Zombie() { - // For 2005, we have to defer "zombification" until + // For Yukon, we have to defer "zombification" until // we get past the users' next rollback, else we'll // throw an exception there that is a breaking change. // Of course, if the connection is already closed, @@ -299,11 +299,11 @@ internal void Zombie() SqlInternalConnection internalConnection = (_connection.InnerConnection as SqlInternalConnection); if (null != internalConnection && !_isFromAPI) { - SqlClientEventSource.Log.TryAdvancedTraceEvent("SqlTransaction.Zombie | ADV | Object Id {0} 2005 deferred zombie", ObjectID); + SqlClientEventSource.Log.TryAdvancedTraceEvent("SqlTransaction.Zombie | ADV | Object Id {0} yukon deferred zombie", ObjectID); } else { - _internalTransaction = null; // pre-2005 zombification + _internalTransaction = null; // pre-yukon zombification } } @@ -316,9 +316,9 @@ private void ZombieCheck() // If this transaction has been completed, throw exception since it is unusable. if (IsZombied) { - if (Is2005PartialZombie) + if (IsYukonPartialZombie) { - _internalTransaction = null; // 2005 zombification + _internalTransaction = null; // yukon zombification } throw ADP.TransactionZombied(this); diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlUtil.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlUtil.cs index 8e9039a6aa..522092b988 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlUtil.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlUtil.cs @@ -394,7 +394,7 @@ internal static Exception ChangePasswordConflictsWithSSPI() { return ADP.Argument(StringsHelper.GetString(Strings.SQL_ChangePasswordConflictsWithSSPI)); } - internal static Exception ChangePasswordRequires2005() + internal static Exception ChangePasswordRequiresYukon() { return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_ChangePasswordRequiresYukon)); } diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs index 6b77e98c2e..44be90bb31 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs @@ -10,6 +10,7 @@ using System.Diagnostics; using System.Globalization; using System.IO; +using System.Reflection; using System.Security.Authentication; using System.Text; using System.Threading; @@ -41,6 +42,7 @@ internal sealed partial class TdsParser { private static int _objectTypeCount; // EventSource counter private readonly SqlClientLogger _logger = new SqlClientLogger(); + private readonly string _typeName; internal readonly int _objectID = Interlocked.Increment(ref _objectTypeCount); internal int ObjectID => _objectID; @@ -88,7 +90,7 @@ internal sealed partial class TdsParser private EncryptionOptions _encryptionOption = s_sniSupportedEncryptionOption; private SqlInternalTransaction _currentTransaction; - private SqlInternalTransaction _pendingTransaction; // pending transaction for 2005 and beyond. + private SqlInternalTransaction _pendingTransaction; // pending transaction for Yukon and beyond. // need to hold on to the transaction id if distributed transaction merely rolls back without defecting. private long _retainedTransactionId = SqlInternalTransaction.NullTransactionId; @@ -111,11 +113,11 @@ internal sealed partial class TdsParser // Version variables - private bool _is2005 = false; // set to true if speaking to 2005 or later + private bool _isYukon = false; // set to true if speaking to Yukon or later - private bool _is2008 = false; + private bool _isKatmai = false; - private bool _is2012 = false; + private bool _isDenali = false; private byte[][] _sniSpnBuffer = null; @@ -188,10 +190,11 @@ internal sealed partial class TdsParser internal TdsParser(bool MARS, bool fAsynchronous) { - _fMARS = MARS; // may change during Connect to pre 2005 servers + _fMARS = MARS; // may change during Connect to pre Yukon servers _physicalStateObj = TdsParserStateObjectFactory.Singleton.CreateTdsParserStateObject(this); DataClassificationVersion = TdsEnums.DATA_CLASSIFICATION_NOT_ENABLED; + _typeName = GetType().Name; } internal SqlInternalConnectionTds Connection @@ -257,11 +260,11 @@ internal EncryptionOptions EncryptionOptions } } - internal bool Is2008OrNewer + internal bool IsKatmaiOrNewer { get { - return _is2008; + return _isKatmai; } } @@ -322,7 +325,7 @@ private bool IncludeTraceHeader { get { - return (_is2012 && SqlClientEventSource.Log.IsEnabled()); + return (_isDenali && SqlClientEventSource.Log.IsEnabled()); } } @@ -529,8 +532,8 @@ internal void Connect( SendPreLoginHandshake(instanceName, encrypt); status = ConsumePreLoginHandshake(encrypt, trustServerCert, integratedSecurity, out marsCapable, out _connHandler._fedAuthRequired); - // Don't need to check for 7.0 failure, since we've already consumed - // one pre-login packet and know we are connecting to 2000. + // Don't need to check for Sphinx failure, since we've already consumed + // one pre-login packet and know we are connecting to Shiloh. if (status == PreLoginHandshakeStatus.InstanceFailure) { SqlClientEventSource.Log.TryTraceEvent(" Prelogin handshake unsuccessful. Login failure"); @@ -804,7 +807,7 @@ private PreLoginHandshakeStatus ConsumePreLoginHandshake(bool encrypt, bool trus { marsCapable = _fMARS; // Assign default value fedAuthRequired = false; - bool is2005OrLater = false; + bool isYukonOrLater = false; Debug.Assert(_physicalStateObj._syncOverAsync, "Should not attempt pends in a synchronous call"); bool result = _physicalStateObj.TryReadNetworkPacket(); if (!result) @@ -863,10 +866,10 @@ private PreLoginHandshakeStatus ConsumePreLoginHandshake(bool encrypt, bool trus int level = (payload[payloadOffset + 2] << 8) | payload[payloadOffset + 3]; - is2005OrLater = majorVersion >= 9; - if (!is2005OrLater) + isYukonOrLater = majorVersion >= 9; + if (!isYukonOrLater) { - marsCapable = false; // If pre-2005, MARS not supported. + marsCapable = false; // If pre-Yukon, MARS not supported. } break; @@ -934,7 +937,7 @@ private PreLoginHandshakeStatus ConsumePreLoginHandshake(bool encrypt, bool trus // Validate Certificate if Trust Server Certificate=false and Encryption forced (EncryptionOptions.ON) from Server. bool shouldValidateServerCert = (_encryptionOption == EncryptionOptions.ON && !trustServerCert) || (_connHandler._accessTokenInBytes != null && !trustServerCert); uint info = (shouldValidateServerCert ? TdsEnums.SNI_SSL_VALIDATE_CERTIFICATE : 0) - | (is2005OrLater ? TdsEnums.SNI_SSL_USE_SCHANNEL_CACHE : 0); + | (isYukonOrLater ? TdsEnums.SNI_SSL_USE_SCHANNEL_CACHE : 0); if (encrypt && !integratedSecurity) { @@ -959,16 +962,8 @@ private PreLoginHandshakeStatus ConsumePreLoginHandshake(bool encrypt, bool trus string warningMessage = protocol.GetProtocolWarning(); if (!string.IsNullOrEmpty(warningMessage)) { - if (!encrypt && LocalAppContextSwitches.SuppressInsecureTLSWarning) - { - // Skip console warning - SqlClientEventSource.Log.TryTraceEvent("{3}", nameof(TdsParser), nameof(ConsumePreLoginHandshake), SqlClientLogger.LogLevel.Warning, warningMessage); - } - else - { - // This logs console warning of insecure protocol in use. - _logger.LogWarning(nameof(TdsParser), nameof(ConsumePreLoginHandshake), warningMessage); - } + // This logs console warning of insecure protocol in use. + _logger.LogWarning(_typeName, MethodBase.GetCurrentMethod().Name, warningMessage); } // create a new packet encryption changes the internal packet size @@ -1534,7 +1529,7 @@ internal void CheckResetConnection(TdsParserStateObject stateObj) { Debug.Assert(!stateObj._fResetConnectionSent, "Unexpected state on WritePacket ResetConnection"); - // Otherwise if 2005 and we grabbed the event, free it. Another execute grabbed the event and + // Otherwise if Yukon and we grabbed the event, free it. Another execute grabbed the event and // took care of sending the reset. stateObj._fResetEventOwned = !_resetConnectionEvent.Set(); Debug.Assert(!stateObj._fResetEventOwned, "Invalid AutoResetEvent state!"); @@ -1544,7 +1539,7 @@ internal void CheckResetConnection(TdsParserStateObject stateObj) { if (_fMARS && stateObj._fResetEventOwned) { - // If exception thrown, and we are on 2005 and own the event, release it! + // If exception thrown, and we are on Yukon and own the event, release it! stateObj._fResetConnectionSent = false; stateObj._fResetEventOwned = !_resetConnectionEvent.Set(); Debug.Assert(!stateObj._fResetEventOwned, "Invalid AutoResetEvent state!"); @@ -1817,7 +1812,7 @@ internal void WriteDouble(double v, TdsParserStateObject stateObj) internal void PrepareResetConnection(bool preserveTransaction) { - // Set flag to reset connection upon next use - only for use on 2000! + // Set flag to reset connection upon next use - only for use on shiloh! _fResetConnection = true; _fPreserveTransaction = preserveTransaction; } @@ -3597,40 +3592,41 @@ private bool TryProcessLoginAck(TdsParserStateObject stateObj, out SqlLoginAck s uint increment = (a.tdsVersion >> 16) & 0xff; // Server responds: - // 0x07000000 -> 7.0 // Notice server response format is different for bwd compat - // 0x07010000 -> 2000 RTM // Notice server response format is different for bwd compat - // 0x71000001 -> 2000 SP1 - // 0x72xx0002 -> 2005 RTM + // 0x07000000 -> Sphinx // Notice server response format is different for bwd compat + // 0x07010000 -> Shiloh RTM // Notice server response format is different for bwd compat + // 0x71000001 -> Shiloh SP1 + // 0x72xx0002 -> Yukon RTM + // information provided by S. Ashwin switch (majorMinor) { - case TdsEnums.SQL2005_MAJOR << 24 | TdsEnums.SQL2005_RTM_MINOR: // 2005 - if (increment != TdsEnums.SQL2005_INCREMENT) + case TdsEnums.YUKON_MAJOR << 24 | TdsEnums.YUKON_RTM_MINOR: // Yukon + if (increment != TdsEnums.YUKON_INCREMENT) { throw SQL.InvalidTDSVersion(); } - _is2005 = true; + _isYukon = true; break; - case TdsEnums.SQL2008_MAJOR << 24 | TdsEnums.SQL2008_MINOR: - if (increment != TdsEnums.SQL2008_INCREMENT) + case TdsEnums.KATMAI_MAJOR << 24 | TdsEnums.KATMAI_MINOR: + if (increment != TdsEnums.KATMAI_INCREMENT) { throw SQL.InvalidTDSVersion(); } - _is2008 = true; + _isKatmai = true; break; - case TdsEnums.SQl2012_MAJOR << 24 | TdsEnums.SQL2012_MINOR: - if (increment != TdsEnums.SQL2012_INCREMENT) + case TdsEnums.DENALI_MAJOR << 24 | TdsEnums.DENALI_MINOR: + if (increment != TdsEnums.DENALI_INCREMENT) { throw SQL.InvalidTDSVersion(); } - _is2012 = true; + _isDenali = true; break; default: throw SQL.InvalidTDSVersion(); } - _is2008 |= _is2012; - _is2005 |= _is2008; + _isKatmai |= _isDenali; + _isYukon |= _isKatmai; stateObj._outBytesUsed = stateObj._outputHeaderLen; byte len; @@ -3898,7 +3894,7 @@ internal bool TryProcessReturnValue(int length, TdsParserStateObject stateObj, o { returnValue = null; SqlReturnValue rec = new SqlReturnValue(); - rec.length = length; // In 2005 this length is -1 + rec.length = length; // In Yukon this length is -1 ushort parameterIndex; if (!stateObj.TryReadUInt16(out parameterIndex)) { @@ -3928,7 +3924,7 @@ internal bool TryProcessReturnValue(int length, TdsParserStateObject stateObj, o uint userType; - // read user type - 4 bytes 2005, 2 backwards + // read user type - 4 bytes Yukon, 2 backwards if (!stateObj.TryReadUInt32(out userType)) { return false; @@ -3985,8 +3981,8 @@ internal bool TryProcessReturnValue(int length, TdsParserStateObject stateObj, o rec.metaType = MetaType.GetSqlDataType(tdsType, userType, tdsLen); rec.type = rec.metaType.SqlDbType; - // always use the nullable type for parameters if 2000 or later - // 7.0 sometimes sends fixed length return values + // always use the nullable type for parameters if Shiloh or later + // Sphinx sometimes sends fixed length return values rec.tdsType = rec.metaType.NullableType; rec.IsNullable = true; if (tdsLen == TdsEnums.SQL_USHORTVARMAXLEN) @@ -4898,7 +4894,7 @@ private bool TryCommonProcessMetaData(TdsParserStateObject stateObj, _SqlMetaDat byte byteLen; uint userType; - // read user type - 4 bytes 2005, 2 backwards + // read user type - 4 bytes Yukon, 2 backwards if (!stateObj.TryReadUInt32(out userType)) { return false; @@ -7478,7 +7474,7 @@ internal int GetEncodingCharLength(string value, int numChars, int charOffset, E // internal bool TryGetDataLength(SqlMetaDataPriv colmeta, TdsParserStateObject stateObj, out ulong length) { - // Handle 2005 specific tokens + // Handle Yukon specific tokens if (colmeta.metaType.IsPlp) { Debug.Assert(colmeta.tdsType == TdsEnums.SQLXMLTYPE || @@ -7532,7 +7528,7 @@ internal bool TryGetTokenLength(byte token, TdsParserStateObject stateObj, out i } else if (token == TdsEnums.SQLRETURNVALUE) { - tokenLength = -1; // In 2005, the RETURNVALUE token stream no longer has length + tokenLength = -1; // In Yukon, the RETURNVALUE token stream no longer has length return true; } else if (token == TdsEnums.SQLXMLTYPE) @@ -7992,7 +7988,7 @@ internal void TdsLogin(SqlLogin rec, TdsEnums.FeatureExtension requestedFeatures _physicalStateObj._outputMessageType = TdsEnums.MT_LOGIN7; // length in bytes - int length = TdsEnums.SQL2005_LOG_REC_FIXED_LEN; + int length = TdsEnums.YUKON_LOG_REC_FIXED_LEN; string clientInterfaceName = TdsEnums.SQL_PROVIDER_NAME; Debug.Assert(TdsEnums.MAXLEN_CLIENTINTERFACE >= clientInterfaceName.Length, "cchCltIntName can specify at most 128 unicode characters. See Tds spec"); @@ -8098,7 +8094,7 @@ internal void TdsLogin(SqlLogin rec, TdsEnums.FeatureExtension requestedFeatures WriteInt(length, _physicalStateObj); if (recoverySessionData == null) { - WriteInt((TdsEnums.SQl2012_MAJOR << 24) | (TdsEnums.SQL2012_INCREMENT << 16) | TdsEnums.SQL2012_MINOR, _physicalStateObj); + WriteInt((TdsEnums.DENALI_MAJOR << 24) | (TdsEnums.DENALI_INCREMENT << 16) | TdsEnums.DENALI_MINOR, _physicalStateObj); } else { @@ -8182,7 +8178,7 @@ internal void TdsLogin(SqlLogin rec, TdsEnums.FeatureExtension requestedFeatures WriteInt(0, _physicalStateObj); // LCID is unused by server // Start writing offset and length of variable length portions - int offset = TdsEnums.SQL2005_LOG_REC_FIXED_LEN; + int offset = TdsEnums.YUKON_LOG_REC_FIXED_LEN; // write offset/length pairs @@ -9000,7 +8996,7 @@ internal Task TdsExecuteRPC(SqlCommand cmd, _SqlRPC[] rpcArray, int timeout, boo { if (rpcext.ProcID != 0) { - // Perf optimization for 2000 and later, + // Perf optimization for Shiloh and later, Debug.Assert(rpcext.ProcID < 255, "rpcExec:ProcID can't be larger than 255"); WriteShort(0xffff, stateObj); WriteShort((short)(rpcext.ProcID), stateObj); @@ -9065,14 +9061,14 @@ internal Task TdsExecuteRPC(SqlCommand cmd, _SqlRPC[] rpcArray, int timeout, boo // type (parameter record stores the MetaType class which is a helper that encapsulates all the type information we need here) MetaType mt = param.InternalMetaType; - if (mt.Is2008Type) + if (mt.IsNewKatmaiType) { WriteSmiParameter(param, i, 0 != (options & TdsEnums.RPC_PARAM_DEFAULT), stateObj, enableOptimizedParameterBinding, isAdvancedTraceOn); continue; } - if ((!_is2005 && !mt.Is80Supported) || - (!_is2008 && !mt.Is90Supported)) + if ((!_isYukon && !mt.Is80Supported) || + (!_isKatmai && !mt.Is90Supported)) { throw ADP.VersionDoesNotSupportDataType(mt.TypeName); } @@ -9135,7 +9131,7 @@ internal Task TdsExecuteRPC(SqlCommand cmd, _SqlRPC[] rpcArray, int timeout, boo // If this is not the last RPC we are sending, add the batch flag if (ii < (rpcArray.Length - 1)) { - stateObj.WriteByte(TdsEnums.SQL2005_RPCBATCHFLAG); + stateObj.WriteByte(TdsEnums.YUKON_RPCBATCHFLAG); } } // rpc for loop @@ -9411,7 +9407,7 @@ private Task TDSExecuteRPCAddParameter(TdsParserStateObject stateObj, SqlParamet maxsize = (size > codePageByteSize) ? size : codePageByteSize; if (maxsize == 0) { - // 2005 doesn't like 0 as MaxSize. Change it to 2 for unicode types + // Yukon doesn't like 0 as MaxSize. Change it to 2 for unicode types if (mt.IsNCharType) maxsize = 2; else @@ -9436,9 +9432,9 @@ private Task TDSExecuteRPCAddParameter(TdsParserStateObject stateObj, SqlParamet } else if (mt.SqlDbType == SqlDbType.Udt) { - Debug.Assert(_is2005, "Invalid DataType UDT for non-2005 or later server!"); + Debug.Assert(_isYukon, "Invalid DataType UDT for non-Yukon or later server!"); - int maxSupportedSize = Is2008OrNewer ? int.MaxValue : short.MaxValue; + int maxSupportedSize = IsKatmaiOrNewer ? int.MaxValue : short.MaxValue; byte[] udtVal = null; Format format = Format.Native; @@ -9528,9 +9524,9 @@ private Task TDSExecuteRPCAddParameter(TdsParserStateObject stateObj, SqlParamet else if ((!mt.IsVarTime) && (mt.SqlDbType != SqlDbType.Date)) { // Time, Date, DateTime2, DateTimeoffset do not have the size written out maxsize = (size > actualSize) ? size : actualSize; - if (maxsize == 0 && _is2005) + if (maxsize == 0 && _isYukon) { - // 2005 doesn't like 0 as MaxSize. Change it to 2 for unicode types (SQL9 - 682322) + // Yukon doesn't like 0 as MaxSize. Change it to 2 for unicode types (SQL9 - 682322) if (mt.IsNCharType) maxsize = 2; else @@ -9562,7 +9558,7 @@ private Task TDSExecuteRPCAddParameter(TdsParserStateObject stateObj, SqlParamet // write out collation or xml metadata - if (_is2005 && (mt.SqlDbType == SqlDbType.Xml)) + if (_isYukon && (mt.SqlDbType == SqlDbType.Xml)) { if (!string.IsNullOrEmpty(param.XmlSchemaCollectionDatabase) || !string.IsNullOrEmpty(param.XmlSchemaCollectionOwningSchema) || @@ -9766,7 +9762,7 @@ private void WriteSmiParameter(SqlParameter param, int paramIndex, bool sendDefa ParameterPeekAheadValue peekAhead; SmiParameterMetaData metaData = param.MetaDataForSmi(out peekAhead); - if (!_is2008) + if (!_isKatmai) { MetaType mt = MetaType.GetMetaTypeFromSqlDbType(metaData.SqlDbType, metaData.IsMultiValued); throw ADP.VersionDoesNotSupportDataType(mt.TypeName); @@ -10356,7 +10352,7 @@ internal void WriteBulkCopyMetaData(_SqlMetaDataSet metadataCollection, int coun { _SqlMetaData md = metadataCollection[i]; - // read user type - 4 bytes 2005, 2 backwards + // read user type - 4 bytes Yukon, 2 backwards WriteInt(0x0, stateObj); // Write the flags @@ -10759,7 +10755,7 @@ private Task WriteBulkCopyValueSetupContinuation(Task internalWriteTask, Encodin // Write mars header data, not including the mars header length private void WriteMarsHeaderData(TdsParserStateObject stateObj, SqlInternalTransaction transaction) { - // Function to send over additional payload header data for 2005 and beyond only. + // Function to send over additional payload header data for Yukon and beyond only. // These are not necessary - can have local started in distributed. // Debug.Assert(!(null != sqlTransaction && null != distributedTransaction), "Error to have local (api started) and distributed transaction at the same time!"); @@ -10835,7 +10831,7 @@ private int GetNotificationHeaderSize(SqlNotificationRequest notificationRequest // Write query notificaiton header data, not including the notificaiton header length private void WriteQueryNotificationHeaderData(SqlNotificationRequest notificationRequest, TdsParserStateObject stateObj) { - Debug.Assert(_is2005, "WriteQueryNotificationHeaderData called on a non-2005 server"); + Debug.Assert(_isYukon, "WriteQueryNotificationHeaderData called on a non-Yukon server"); // We may need to update the notification header length if the header is changed in the future @@ -10866,7 +10862,7 @@ private void WriteQueryNotificationHeaderData(SqlNotificationRequest notificatio private void WriteTraceHeaderData(TdsParserStateObject stateObj) { - Debug.Assert(this.IncludeTraceHeader, "WriteTraceHeaderData can only be called on a 2012 or higher version server and bid trace with the control bit are on"); + Debug.Assert(this.IncludeTraceHeader, "WriteTraceHeaderData can only be called on a Denali or higher version server and bid trace with the control bit are on"); // We may need to update the trace header length if trace header is changed in the future @@ -11098,21 +11094,15 @@ private Task WriteUnterminatedSqlValue(object value, MetaType type, int actualLe { Debug.Assert(actualLength == 16, "Invalid length for guid type in com+ object"); Span b = stackalloc byte[16]; - if (value is Guid guid) + SqlGuid sqlGuid = (SqlGuid)value; + + if (sqlGuid.IsNull) { - FillGuidBytes(guid, b); + b.Clear(); // this is needed because initlocals may be supressed in framework assemblies meaning the memory is not automaticaly zeroed } else { - SqlGuid sqlGuid = (SqlGuid)value; - if (sqlGuid.IsNull) - { - b.Clear(); // this is needed because initlocals may be supressed in framework assemblies meaning the memory is not automaticaly zeroed - } - else - { - FillGuidBytes(sqlGuid.Value, b); - } + FillGuidBytes(sqlGuid.Value, b); } stateObj.WriteByteSpan(b); break; @@ -12808,7 +12798,7 @@ private bool TryProcessUDTMetaData(SqlMetaDataPriv metaData, TdsParserStateObjec + " _connHandler = {14}\n\t" + " _fMARS = {15}\n\t" + " _sessionPool = {16}\n\t" - + " _is2005 = {17}\n\t" + + " _isYukon = {17}\n\t" + " _sniSpnBuffer = {18}\n\t" + " _errors = {19}\n\t" + " _warnings = {20}\n\t" @@ -12840,7 +12830,7 @@ internal string TraceString() null == _connHandler ? "(null)" : _connHandler.ObjectID.ToString((IFormatProvider)null), _fMARS ? bool.TrueString : bool.FalseString, null == _sessionPool ? "(null)" : _sessionPool.TraceString(), - _is2005 ? bool.TrueString : bool.FalseString, + _isYukon ? bool.TrueString : bool.FalseString, null == _sniSpnBuffer ? "(null)" : _sniSpnBuffer.Length.ToString((IFormatProvider)null), _physicalStateObj != null ? "(null)" : _physicalStateObj.ErrorCount.ToString((IFormatProvider)null), _physicalStateObj != null ? "(null)" : _physicalStateObj.WarningCount.ToString((IFormatProvider)null), diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserHelperClasses.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserHelperClasses.cs index 6daecb969c..428c03b676 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserHelperClasses.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserHelperClasses.cs @@ -324,7 +324,7 @@ private void Set(_SqlMetadataFlags flag, bool value) flags = value ? flags | flag : flags & ~flag; } - internal bool Is2008DateTimeType + internal bool IsNewKatmaiDateTimeType { get { diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObject.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObject.cs index cbeb228ab9..7e06c3df98 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObject.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObject.cs @@ -174,7 +174,7 @@ public TimeoutState(int value) internal ulong _longlen; // plp data length indicator internal ulong _longlenleft; // Length of data left to read (64 bit lengths) internal int[] _decimalBits; // scratch buffer for decimal/numeric data - internal byte[] _bTmp = new byte[TdsEnums.SQL2005_HEADER_LEN]; // Scratch buffer for misc use + internal byte[] _bTmp = new byte[TdsEnums.YUKON_HEADER_LEN]; // Scratch buffer for misc use internal int _bTmpRead; // Counter for number of temporary bytes read internal Decoder _plpdecoder; // Decoder object to process plp character data internal bool _accumulateInfoEvents; // TRUE - accumulate info messages during TdsParser.Run, FALSE - fire them @@ -494,8 +494,8 @@ internal bool TryStartNewRow(bool isNullCompressed, int nullBitmapColumnsCount = // initialize or unset null bitmap information for the current row if (isNullCompressed) { - // assert that NBCROW is not in use by 2005 or before - Debug.Assert(_parser.Is2008OrNewer, "NBCROW is sent by pre-2008 server"); + // assert that NBCROW is not in use by Yukon or before + Debug.Assert(_parser.IsKatmaiOrNewer, "NBCROW is sent by pre-Katmai server"); if (!_nullBitmapInfo.TryInitialize(this, nullBitmapColumnsCount)) { @@ -3336,9 +3336,9 @@ internal Task WritePacket(byte flushMode, bool canAccumulate = false) } if ( - // This appears to be an optimization to avoid writing empty packets in 2005 - // However, since we don't know the version prior to login Is2005OrNewer was always false prior to login - // So removing the Is2005OrNewer check causes issues since the login packet happens to meet the rest of the conditions below + // This appears to be an optimization to avoid writing empty packets in Yukon + // However, since we don't know the version prior to login IsYukonOrNewer was always false prior to login + // So removing the IsYukonOrNewer check causes issues since the login packet happens to meet the rest of the conditions below // So we need to avoid this check prior to login completing state == TdsParserState.OpenLoggedIn && !_bulkCopyOpperationInProgress && // ignore the condition checking for bulk copy diff --git a/src/Microsoft.Data.SqlClient/netfx/ref/Microsoft.Data.SqlClient.cs b/src/Microsoft.Data.SqlClient/netfx/ref/Microsoft.Data.SqlClient.cs index eca9091a58..e078631f4e 100644 --- a/src/Microsoft.Data.SqlClient/netfx/ref/Microsoft.Data.SqlClient.cs +++ b/src/Microsoft.Data.SqlClient/netfx/ref/Microsoft.Data.SqlClient.cs @@ -384,8 +384,6 @@ public partial class SqlClientLogger public SqlClientLogger() { } /// public bool IsLoggingEnabled { get { throw null; } } - /// - public void LogWarning(string type, string method, string message) { } /// public bool LogAssert(bool value, string type, string method, string message) { throw null; } /// diff --git a/src/Microsoft.Data.SqlClient/netfx/src/.editorconfig b/src/Microsoft.Data.SqlClient/netfx/src/.editorconfig deleted file mode 100644 index f3238bb87b..0000000000 --- a/src/Microsoft.Data.SqlClient/netfx/src/.editorconfig +++ /dev/null @@ -1,9 +0,0 @@ -# editorconfig.org - -# top-most EditorConfig file -root = false - -[*.cs] - -# IDE0090: Use 'new(...)' -csharp_style_implicit_object_creation_when_type_is_apparent = false 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 5f928e41fb..dc4e369dfc 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj @@ -165,9 +165,6 @@ Microsoft\Data\SqlClient\AzureAttestationBasedEnclaveProvider.cs - - Microsoft\Data\SqlClient\NoneAttestationEnclaveProvider.cs - Microsoft\Data\SqlClient\EnclaveDelegate.cs @@ -249,9 +246,6 @@ Microsoft\Data\SqlClient\Server\SmiMetaDataProperty.cs - - Microsoft\Data\SqlClient\Server\SqlSer.cs - Microsoft\Data\SqlClient\ColumnEncryptionKeyInfo.cs @@ -378,9 +372,6 @@ Microsoft\Data\SqlClient\SqlEnums.cs - - Microsoft\Data\SqlClient\SqlError.cs - Microsoft\Data\SqlClient\SqlErrorCollection.cs @@ -582,6 +573,7 @@ + @@ -636,8 +628,12 @@ + + + + @@ -711,4 +707,4 @@ - + \ No newline at end of file diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/LocalDBAPI.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/LocalDBAPI.cs index e3b4ea2ef4..f1f4c955af 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/LocalDBAPI.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/LocalDBAPI.cs @@ -16,11 +16,11 @@ namespace Microsoft.Data { + internal static class LocalDBAPI { - private const string LocalDbPrefix = @"(localdb)\"; - private const string LocalDbPrefix_NP = @"np:\\.\pipe\LOCALDB#"; - const string Const_partialTrustFlagKey = "ALLOW_LOCALDB_IN_PARTIAL_TRUST"; + const string const_localDbPrefix = @"(localdb)\"; + const string const_partialTrustFlagKey = "ALLOW_LOCALDB_IN_PARTIAL_TRUST"; static PermissionSet _fullTrust = null; static bool _partialTrustFlagChecked = false; @@ -30,28 +30,19 @@ internal static class LocalDBAPI // check if name is in format (localdb)\ and return instance name if it is internal static string GetLocalDbInstanceNameFromServerName(string serverName) { - if (serverName is not null) - { - // it can start with spaces if specified in quotes - // Memory allocation is reduced by using ReadOnlySpan - ReadOnlySpan input = serverName.AsSpan().Trim(); - if (input.StartsWith(LocalDbPrefix.AsSpan(), StringComparison.OrdinalIgnoreCase)) - { - input = input.Slice(LocalDbPrefix.Length); - if (!input.IsEmpty) - { - return input.ToString(); - } - } - else if (input.StartsWith(LocalDbPrefix_NP.AsSpan(), StringComparison.OrdinalIgnoreCase)) - { - return input.ToString(); - } - - } - return null; + if (serverName == null) + return null; + serverName = serverName.TrimStart(); // it can start with spaces if specified in quotes + if (!serverName.StartsWith(const_localDbPrefix, StringComparison.OrdinalIgnoreCase)) + return null; + string instanceName = serverName.Substring(const_localDbPrefix.Length).Trim(); + if (instanceName.Length == 0) + return null; + else + return instanceName; } + internal static void ReleaseDLLHandles() { s_userInstanceDLLHandle = IntPtr.Zero; @@ -270,7 +261,7 @@ internal static void DemandLocalDBPermissions() { if (!_partialTrustFlagChecked) { - object partialTrustFlagValue = AppDomain.CurrentDomain.GetData(Const_partialTrustFlagKey); + object partialTrustFlagValue = AppDomain.CurrentDomain.GetData(const_partialTrustFlagKey); if (partialTrustFlagValue != null && partialTrustFlagValue is bool) { _partialTrustAllowed = (bool)partialTrustFlagValue; diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/Server/MetadataUtilsSmi.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/Server/MetadataUtilsSmi.cs index 92baf05ff2..94edcab2d3 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/Server/MetadataUtilsSmi.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/Server/MetadataUtilsSmi.cs @@ -262,7 +262,7 @@ internal static ExtendedClrTypeCode DetermineExtendedTypeCodeForUseWithSqlDbType break; case SqlDbType.Date: case SqlDbType.DateTime2: - if (smiVersion >= SmiContextFactory.Sql2008Version) + if (smiVersion >= SmiContextFactory.KatmaiVersion) { goto case SqlDbType.DateTime; } @@ -364,11 +364,11 @@ internal static ExtendedClrTypeCode DetermineExtendedTypeCodeForUseWithSqlDbType } break; case SqlDbType.Time: - if (value.GetType() == typeof(TimeSpan) && smiVersion >= SmiContextFactory.Sql2008Version) + if (value.GetType() == typeof(TimeSpan) && smiVersion >= SmiContextFactory.KatmaiVersion) extendedCode = ExtendedClrTypeCode.TimeSpan; break; case SqlDbType.DateTimeOffset: - if (value.GetType() == typeof(DateTimeOffset) && smiVersion >= SmiContextFactory.Sql2008Version) + if (value.GetType() == typeof(DateTimeOffset) && smiVersion >= SmiContextFactory.KatmaiVersion) extendedCode = ExtendedClrTypeCode.DateTimeOffset; break; case SqlDbType.Xml: @@ -462,8 +462,8 @@ static internal SqlDbType InferSqlDbTypeFromTypeCode(ExtendedClrTypeCode typeCod return __extendedTypeCodeToSqlDbTypeMap[(int)typeCode + 1]; } - // Infer SqlDbType from Type in the general case. 2008-only (or later) features that need to - // infer types should use InferSqlDbTypeFromType_2008. + // Infer SqlDbType from Type in the general case. Katmai-only (or later) features that need to + // infer types should use InferSqlDbTypeFromType_Katmai. static internal SqlDbType InferSqlDbTypeFromType(Type type) { ExtendedClrTypeCode typeCode = DetermineExtendedTypeCodeFromType(type); @@ -480,12 +480,12 @@ static internal SqlDbType InferSqlDbTypeFromType(Type type) return returnType; } - // Inference rules changed for 2008-or-later-only cases. Only features that are guaranteed to be - // running against 2008 and don't have backward compat issues should call this code path. - // example: TVP's are a new 2008 feature (no back compat issues) so can infer DATETIME2 + // Inference rules changed for Katmai-or-later-only cases. Only features that are guaranteed to be + // running against Katmai and don't have backward compat issues should call this code path. + // example: TVP's are a new Katmai feature (no back compat issues) so can infer DATETIME2 // when mapping System.DateTime from DateTable or DbDataReader. DATETIME2 is better because // of greater range that can handle all DateTime values. - static internal SqlDbType InferSqlDbTypeFromType_2008(Type type) + static internal SqlDbType InferSqlDbTypeFromType_Katmai(Type type) { SqlDbType returnType = InferSqlDbTypeFromType(type); if (SqlDbType.DateTime == returnType) @@ -503,8 +503,8 @@ static internal bool IsValidForSmiVersion(SmiExtendedMetaData md, ulong smiVersi } else { - // 2005 doesn't support Structured nor the new time types - Debug.Assert(SmiContextFactory.Sql2005Version == smiVersion, "Other versions should have been eliminated during link stage"); + // Yukon doesn't support Structured nor the new time types + Debug.Assert(SmiContextFactory.YukonVersion == smiVersion, "Other versions should have been eliminated during link stage"); return md.SqlDbType != SqlDbType.Structured && md.SqlDbType != SqlDbType.Date && md.SqlDbType != SqlDbType.DateTime2 && @@ -697,7 +697,7 @@ private static CultureInfo GetColumnLocale(DataColumn column) // Extract metadata for a single DataColumn static internal SmiExtendedMetaData SmiMetaDataFromDataColumn(DataColumn column, DataTable parent) { - SqlDbType dbType = InferSqlDbTypeFromType_2008(column.DataType); + SqlDbType dbType = InferSqlDbTypeFromType_Katmai(column.DataType); if (InvalidSqlDbType == dbType) { throw SQL.UnsupportedColumnTypeForSqlProvider(column.ColumnName, column.DataType.Name); @@ -837,7 +837,7 @@ static internal SmiExtendedMetaData SmiMetaDataFromSchemaTableRow(DataRow schema throw SQL.NullSchemaTableDataTypeNotSupported(colName); } Type colType = (Type)temp; - SqlDbType colDbType = InferSqlDbTypeFromType_2008(colType); + SqlDbType colDbType = InferSqlDbTypeFromType_Katmai(colType); if (InvalidSqlDbType == colDbType) { // Unknown through standard mapping, use VarBinary for columns that are Object typed, otherwise error diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/Server/SmiContextFactory.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/Server/SmiContextFactory.cs index d231fe861a..aadbc0d4b1 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/Server/SmiContextFactory.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/Server/SmiContextFactory.cs @@ -20,11 +20,11 @@ sealed internal class SmiContextFactory private readonly string _serverVersion; private readonly SmiEventSink_Default _eventSinkForGetCurrentContext; - internal const ulong Sql2005Version = 100; - internal const ulong Sql2008Version = 210; - internal const ulong LatestVersion = Sql2008Version; + internal const ulong YukonVersion = 100; + internal const ulong KatmaiVersion = 210; + internal const ulong LatestVersion = KatmaiVersion; - private readonly ulong[] __supportedSmiVersions = new ulong[] { Sql2005Version, Sql2008Version }; + private readonly ulong[] __supportedSmiVersions = new ulong[] { YukonVersion, KatmaiVersion }; // Used as the key for SmiContext.GetContextValue() internal enum ContextKey diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/Server/TriggerAction.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/Server/TriggerAction.cs index 1f1b011ee1..bf5a789125 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/Server/TriggerAction.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/Server/TriggerAction.cs @@ -106,161 +106,161 @@ internal enum EMDEventType // WHEN ADDING, PLEASE CHECK WITH FILE-OWNER FOR WHICH NUMBERS TO USE. THANKS! }; - /// + /// public enum TriggerAction { - /// + /// Invalid = EMDEventType.x_eet_Invalid, - /// + /// Insert = EMDEventType.x_eet_Insert, - /// + /// Update = EMDEventType.x_eet_Update, - /// + /// Delete = EMDEventType.x_eet_Delete, - /// + /// CreateTable = EMDEventType.x_eet_Create_Table, - /// + /// AlterTable = EMDEventType.x_eet_Alter_Table, - /// + /// DropTable = EMDEventType.x_eet_Drop_Table, - /// + /// CreateIndex = EMDEventType.x_eet_Create_Index, - /// + /// AlterIndex = EMDEventType.x_eet_Alter_Index, - /// + /// DropIndex = EMDEventType.x_eet_Drop_Index, - /// + /// CreateSynonym = EMDEventType.x_eet_Create_Synonym, - /// + /// DropSynonym = EMDEventType.x_eet_Drop_Synonym, - /// + /// CreateSecurityExpression = EMDEventType.x_eet_Create_Secexpr, - /// + /// DropSecurityExpression = EMDEventType.x_eet_Drop_Secexpr, - /// + /// CreateView = EMDEventType.x_eet_Create_View, - /// + /// AlterView = EMDEventType.x_eet_Alter_View, - /// + /// DropView = EMDEventType.x_eet_Drop_View, - /// + /// CreateProcedure = EMDEventType.x_eet_Create_Procedure, - /// + /// AlterProcedure = EMDEventType.x_eet_Alter_Procedure, - /// + /// DropProcedure = EMDEventType.x_eet_Drop_Procedure, - /// + /// CreateFunction = EMDEventType.x_eet_Create_Function, - /// + /// AlterFunction = EMDEventType.x_eet_Alter_Function, - /// + /// DropFunction = EMDEventType.x_eet_Drop_Function, - /// + /// CreateTrigger = EMDEventType.x_eet_Create_Trigger, - /// + /// AlterTrigger = EMDEventType.x_eet_Alter_Trigger, - /// + /// DropTrigger = EMDEventType.x_eet_Drop_Trigger, - /// + /// CreateEventNotification = EMDEventType.x_eet_Create_Event_Notification, - /// + /// DropEventNotification = EMDEventType.x_eet_Drop_Event_Notification, - /// + /// CreateType = EMDEventType.x_eet_Create_Type, // Alter_Type = EMDEventType.x_eet_Alter_Type, - /// + /// DropType = EMDEventType.x_eet_Drop_Type, - /// + /// CreateAssembly = EMDEventType.x_eet_Create_Assembly, - /// + /// AlterAssembly = EMDEventType.x_eet_Alter_Assembly, - /// + /// DropAssembly = EMDEventType.x_eet_Drop_Assembly, - /// + /// CreateUser = EMDEventType.x_eet_Create_User, - /// + /// AlterUser = EMDEventType.x_eet_Alter_User, - /// + /// DropUser = EMDEventType.x_eet_Drop_User, - /// + /// CreateRole = EMDEventType.x_eet_Create_Role, - /// + /// AlterRole = EMDEventType.x_eet_Alter_Role, - /// + /// DropRole = EMDEventType.x_eet_Drop_Role, - /// + /// CreateAppRole = EMDEventType.x_eet_Create_AppRole, - /// + /// AlterAppRole = EMDEventType.x_eet_Alter_AppRole, - /// + /// DropAppRole = EMDEventType.x_eet_Drop_AppRole, - /// + /// CreateSchema = EMDEventType.x_eet_Create_Schema, - /// + /// AlterSchema = EMDEventType.x_eet_Alter_Schema, - /// + /// DropSchema = EMDEventType.x_eet_Drop_Schema, - /// + /// CreateLogin = EMDEventType.x_eet_Create_Login, - /// + /// AlterLogin = EMDEventType.x_eet_Alter_Login, - /// + /// DropLogin = EMDEventType.x_eet_Drop_Login, - /// + /// CreateMsgType = EMDEventType.x_eet_Create_MsgType, - /// + /// DropMsgType = EMDEventType.x_eet_Drop_MsgType, - /// + /// CreateContract = EMDEventType.x_eet_Create_Contract, - /// + /// DropContract = EMDEventType.x_eet_Drop_Contract, - /// + /// CreateQueue = EMDEventType.x_eet_Create_Queue, - /// + /// AlterQueue = EMDEventType.x_eet_Alter_Queue, - /// + /// DropQueue = EMDEventType.x_eet_Drop_Queue, - /// + /// CreateService = EMDEventType.x_eet_Create_Service, - /// + /// AlterService = EMDEventType.x_eet_Alter_Service, - /// + /// DropService = EMDEventType.x_eet_Drop_Service, - /// + /// CreateRoute = EMDEventType.x_eet_Create_Route, - /// + /// AlterRoute = EMDEventType.x_eet_Alter_Route, - /// + /// DropRoute = EMDEventType.x_eet_Drop_Route, - /// + /// GrantStatement = EMDEventType.x_eet_Grant_Statement, - /// + /// DenyStatement = EMDEventType.x_eet_Deny_Statement, - /// + /// RevokeStatement = EMDEventType.x_eet_Revoke_Statement, - /// + /// GrantObject = EMDEventType.x_eet_Grant_Object, - /// + /// DenyObject = EMDEventType.x_eet_Deny_Object, - /// + /// RevokeObject = EMDEventType.x_eet_Revoke_Object, - /// + /// CreateBinding = EMDEventType.x_eet_Create_Binding, - /// + /// AlterBinding = EMDEventType.x_eet_Alter_Binding, - /// + /// DropBinding = EMDEventType.x_eet_Drop_Binding, - /// + /// CreatePartitionFunction = EMDEventType.x_eet_Create_Partition_Function, - /// + /// AlterPartitionFunction = EMDEventType.x_eet_Alter_Partition_Function, - /// + /// DropPartitionFunction = EMDEventType.x_eet_Drop_Partition_Function, - /// + /// CreatePartitionScheme = EMDEventType.x_eet_Create_Partition_Scheme, - /// + /// AlterPartitionScheme = EMDEventType.x_eet_Alter_Partition_Scheme, - /// + /// DropPartitionScheme = EMDEventType.x_eet_Drop_Partition_Scheme, } } diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/Server/sqlser.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/Server/sqlser.cs new file mode 100644 index 0000000000..2967aaaa55 --- /dev/null +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/Server/sqlser.cs @@ -0,0 +1,295 @@ +// 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; +using System.Collections; +using System.IO; +using System.Reflection; +using System.Runtime.CompilerServices; +using Microsoft.Data.Common; + +namespace Microsoft.Data.SqlClient.Server +{ + internal class SerializationHelperSql9 + { + // Don't let anyone create an instance of this class. + private SerializationHelperSql9() { } + + // Get the m_size of the serialized stream for this type, in bytes. + // This method creates an instance of the type using the public + // no-argument constructor, serializes it, and returns the m_size + // in bytes. + // Prevent inlining so that reflection calls are not moved to caller that may be in a different assembly that may have a different grant set. + [MethodImpl(MethodImplOptions.NoInlining)] + internal static int SizeInBytes(Type t) => SizeInBytes(Activator.CreateInstance(t)); + + // Get the m_size of the serialized stream for this type, in bytes. + internal static int SizeInBytes(object instance) + { + Type t = instance.GetType(); + Format k = GetFormat(t); + DummyStream stream = new DummyStream(); + Serializer ser = GetSerializer(instance.GetType()); + ser.Serialize(stream, instance); + return (int)stream.Length; + } + + internal static void Serialize(Stream s, object instance) + { + GetSerializer(instance.GetType()).Serialize(s, instance); + } + + internal static object Deserialize(Stream s, Type resultType) => GetSerializer(resultType).Deserialize(s); + + private static Format GetFormat(Type t) => GetUdtAttribute(t).Format; + + // Cache the relationship between a type and its serializer. + // This is expensive to compute since it involves traversing the + // custom attributes of the type using reflection. + // + // Use a per-thread cache, so that there are no synchronization + // issues when accessing cache entries from multiple threads. + [ThreadStatic] + private static Hashtable s_types2Serializers; + + private static Serializer GetSerializer(Type t) + { + if (s_types2Serializers == null) + s_types2Serializers = new Hashtable(); + + Serializer s = (Serializer)s_types2Serializers[t]; + if (s == null) + { + s = GetNewSerializer(t); + s_types2Serializers[t] = s; + } + return s; + } + + internal static int GetUdtMaxLength(Type t) + { + SqlUdtInfo udtInfo = SqlUdtInfo.GetFromType(t); + + if (Format.Native == udtInfo.SerializationFormat) + { + // In the native format, the user does not specify the + // max byte size, it is computed from the type definition + return SerializationHelperSql9.SizeInBytes(t); + } + else + { + // In all other formats, the user specifies the maximum size in bytes. + return udtInfo.MaxByteSize; + } + } + + private static object[] GetCustomAttributes(Type t) + { + object[] attrs = t.GetCustomAttributes(typeof(SqlUserDefinedTypeAttribute), false); + + // If we don't find a Microsoft.Data.SqlClient.Server.SqlUserDefinedTypeAttribute, + // search for a Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute from the + // old System.Data.SqlClient assembly and copy it to our + // Microsoft.Data.SqlClient.Server.SqlUserDefinedTypeAttribute for reference. + if (attrs == null || attrs.Length == 0) + { + object[] attr = t.GetCustomAttributes(false); + attrs = new object[0]; + if (attr != null && attr.Length > 0) + { + for (int i = 0; i < attr.Length; i++) + { + if (attr[i].GetType().FullName.Equals("Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute")) + { + SqlUserDefinedTypeAttribute newAttr = null; + PropertyInfo[] sourceProps = attr[i].GetType().GetProperties(); + + foreach (PropertyInfo sourceProp in sourceProps) + { + if (sourceProp.Name.Equals("Format")) + { + newAttr = new SqlUserDefinedTypeAttribute((Format)sourceProp.GetValue(attr[i], null)); + break; + } + } + if (newAttr != null) + { + foreach (PropertyInfo targetProp in newAttr.GetType().GetProperties()) + { + if (targetProp.CanRead && targetProp.CanWrite) + { + object copyValue = attr[i].GetType().GetProperty(targetProp.Name).GetValue(attr[i]); + targetProp.SetValue(newAttr, copyValue); + } + } + } + + attrs = new object[1] { newAttr }; + break; + } + } + } + } + + return attrs; + } + + internal static SqlUserDefinedTypeAttribute GetUdtAttribute(Type t) + { + SqlUserDefinedTypeAttribute udtAttr = null; + object[] attr = GetCustomAttributes(t); + + if (attr != null && attr.Length == 1) + { + udtAttr = (SqlUserDefinedTypeAttribute)attr[0]; + } + else + { + Type InvalidUdtExceptionType = typeof(InvalidUdtException); + var arguments = new Type[] { typeof(Type), typeof(String) }; + MethodInfo Create = InvalidUdtExceptionType.GetMethod("Create", arguments); + Create.Invoke(null, new object[] { t, Strings.SqlUdtReason_NoUdtAttribute }); + } + return udtAttr; + } + + // Create a new serializer for the given type. + private static Serializer GetNewSerializer(Type t) + { + SqlUserDefinedTypeAttribute udtAttr = GetUdtAttribute(t); + + switch (udtAttr.Format) + { + case Format.Native: + return new NormalizedSerializer(t); + case Format.UserDefined: + return new BinarySerializeSerializer(t); + case Format.Unknown: // should never happen, but fall through + default: + throw ADP.InvalidUserDefinedTypeSerializationFormat(udtAttr.Format); + } + } + } + + // The base serializer class. + internal abstract class Serializer + { + public abstract object Deserialize(Stream s); + public abstract void Serialize(Stream s, object o); + protected Type _type; + + protected Serializer(Type t) + { + _type = t; + } + } + + internal sealed class NormalizedSerializer : Serializer + { + private BinaryOrderedUdtNormalizer _normalizer; + private bool _isFixedSize; + private int _maxSize; + + internal NormalizedSerializer(Type t) : base(t) + { + SqlUserDefinedTypeAttribute udtAttr = SerializationHelperSql9.GetUdtAttribute(t); + _normalizer = new BinaryOrderedUdtNormalizer(t, true); + _isFixedSize = udtAttr.IsFixedLength; + _maxSize = _normalizer.Size; + } + + public override void Serialize(Stream s, object o) => _normalizer.NormalizeTopObject(o, s); + + public override object Deserialize(Stream s) => _normalizer.DeNormalizeTopObject(_type, s); + } + + internal sealed class BinarySerializeSerializer : Serializer + { + internal BinarySerializeSerializer(Type t) : base(t) + { + } + + public override void Serialize(Stream s, object o) + { + BinaryWriter w = new BinaryWriter(s); + if (o is Microsoft.SqlServer.Server.IBinarySerialize) + { + ((SqlServer.Server.IBinarySerialize)o).Write(w); + } + else + { + ((IBinarySerialize)o).Write(w); + } + } + + // Prevent inlining so that reflection calls are not moved + // to a caller that may be in a different assembly that may + // have a different grant set. + [MethodImpl(MethodImplOptions.NoInlining)] + public override object Deserialize(Stream s) + { + object instance = Activator.CreateInstance(_type); + BinaryReader r = new BinaryReader(s); + if (instance is Microsoft.SqlServer.Server.IBinarySerialize) + { + ((SqlServer.Server.IBinarySerialize)instance).Read(r); + } + else + { + ((IBinarySerialize)instance).Read(r); + } + return instance; + } + } + + // A dummy stream class, used to get the number of bytes written + // to the stream. + internal sealed class DummyStream : Stream + { + private long _size; + + public DummyStream() + { + } + + private void DontDoIt() + { + throw new Exception(StringsHelper.GetString(Strings.Sql_InternalError)); + } + + public override bool CanRead => false; + + public override bool CanWrite => true; + + public override bool CanSeek => false; + + public override long Position + { + get => _size; + set =>_size = value; + } + + public override long Length => _size; + + public override void SetLength(long value) => _size = value; + + public override long Seek(long value, SeekOrigin loc) + { + DontDoIt(); + return -1; + } + + public override void Flush() + { + } + + public override int Read(byte[] buffer, int offset, int count) + { + DontDoIt(); + return -1; + } + + public override void Write(byte[] buffer, int offset, int count) => _size += count; + } +} diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SimulatorEnclaveProvider.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SimulatorEnclaveProvider.cs new file mode 100644 index 0000000000..9a8550934c --- /dev/null +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SimulatorEnclaveProvider.cs @@ -0,0 +1,114 @@ +// 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; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Runtime.Caching; +using System.Security.Cryptography; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using System.Collections.Concurrent; + +namespace Microsoft.Data.SqlClient +{ + internal class SimulatorEnclaveProvider : EnclaveProviderBase + { + private static readonly int EnclaveSessionHandleSize = 8; + + // When overridden in a derived class, looks up an existing enclave session information in the enclave session cache. + // If the enclave provider doesn't implement enclave session caching, this method is expected to return null in the sqlEnclaveSession parameter. + internal override void GetEnclaveSession(EnclaveSessionParameters enclaveSessionParameters, bool generateCustomData, out SqlEnclaveSession sqlEnclaveSession, out long counter, out byte[] customData, out int customDataLength) + { + GetEnclaveSessionHelper(enclaveSessionParameters, false, out sqlEnclaveSession, out counter, out customData, out customDataLength); + } + + // Gets the information that SqlClient subsequently uses to initiate the process of attesting the enclave and to establish a secure session with the enclave. + internal override SqlEnclaveAttestationParameters GetAttestationParameters(string attestationUrl, byte[] customData, int customDataLength) + { + ECDiffieHellmanCng clientDHKey = new ECDiffieHellmanCng(384); + clientDHKey.KeyDerivationFunction = ECDiffieHellmanKeyDerivationFunction.Hash; + clientDHKey.HashAlgorithm = CngAlgorithm.Sha256; + + return new SqlEnclaveAttestationParameters(2, new byte[] { }, clientDHKey); + } + + // When overridden in a derived class, performs enclave attestation, generates a symmetric key for the session, creates a an enclave session and stores the session information in the cache. + internal override void CreateEnclaveSession(byte[] attestationInfo, ECDiffieHellman clientDHKey, EnclaveSessionParameters enclaveSessionParameters, byte[] customData, int customDataLength, out SqlEnclaveSession sqlEnclaveSession, out long counter) + { + ////for simulator: enclave does not send public key, and sends an empty attestation info + //// The only non-trivial content it sends is the session setup info (DH pubkey of enclave) + + sqlEnclaveSession = null; + counter = 0; + try + { + ThreadRetryCache.Remove(Thread.CurrentThread.ManagedThreadId.ToString()); + sqlEnclaveSession = GetEnclaveSessionFromCache(enclaveSessionParameters, out counter); + + if (sqlEnclaveSession == null) + { + if (!string.IsNullOrEmpty(enclaveSessionParameters.AttestationUrl)) + { + ////Read AttestationInfo + int attestationInfoOffset = 0; + uint sizeOfTrustedModuleAttestationInfoBuffer = BitConverter.ToUInt32(attestationInfo, attestationInfoOffset); + attestationInfoOffset += sizeof(UInt32); + int sizeOfTrustedModuleAttestationInfoBufferInt = checked((int)sizeOfTrustedModuleAttestationInfoBuffer); + Debug.Assert(sizeOfTrustedModuleAttestationInfoBuffer == 0); + + ////read secure session info + uint sizeOfSecureSessionInfoResponse = BitConverter.ToUInt32(attestationInfo, attestationInfoOffset); + attestationInfoOffset += sizeof(UInt32); + + byte[] enclaveSessionHandle = new byte[EnclaveSessionHandleSize]; + Buffer.BlockCopy(attestationInfo, attestationInfoOffset, enclaveSessionHandle, 0, EnclaveSessionHandleSize); + attestationInfoOffset += EnclaveSessionHandleSize; + + uint sizeOfTrustedModuleDHPublicKeyBuffer = BitConverter.ToUInt32(attestationInfo, attestationInfoOffset); + attestationInfoOffset += sizeof(UInt32); + uint sizeOfTrustedModuleDHPublicKeySignatureBuffer = BitConverter.ToUInt32(attestationInfo, attestationInfoOffset); + attestationInfoOffset += sizeof(UInt32); + int sizeOfTrustedModuleDHPublicKeyBufferInt = checked((int)sizeOfTrustedModuleDHPublicKeyBuffer); + + byte[] trustedModuleDHPublicKey = new byte[sizeOfTrustedModuleDHPublicKeyBuffer]; + Buffer.BlockCopy(attestationInfo, attestationInfoOffset, trustedModuleDHPublicKey, 0, + sizeOfTrustedModuleDHPublicKeyBufferInt); + attestationInfoOffset += sizeOfTrustedModuleDHPublicKeyBufferInt; + + byte[] trustedModuleDHPublicKeySignature = new byte[sizeOfTrustedModuleDHPublicKeySignatureBuffer]; + Buffer.BlockCopy(attestationInfo, attestationInfoOffset, trustedModuleDHPublicKeySignature, 0, + checked((int)sizeOfTrustedModuleDHPublicKeySignatureBuffer)); + + byte[] sharedSecret; + using ECDiffieHellman ecdh = KeyConverter.CreateECDiffieHellmanFromPublicKeyBlob(trustedModuleDHPublicKey); + sharedSecret = KeyConverter.DeriveKey(clientDHKey, ecdh.PublicKey); + long sessionId = BitConverter.ToInt64(enclaveSessionHandle, 0); + sqlEnclaveSession = AddEnclaveSessionToCache(enclaveSessionParameters, sharedSecret, sessionId, out counter); + } + else + { + throw new AlwaysEncryptedAttestationException(Strings.FailToCreateEnclaveSession); + } + } + } + finally + { + UpdateEnclaveSessionLockStatus(sqlEnclaveSession); + } + } + + /// + /// When overridden in a derived class, looks up and evicts an enclave session from the enclave session cache, if the provider implements session caching. + /// + /// The set of parameters required for enclave session. + /// The session to be invalidated. + internal override void InvalidateEnclaveSession(EnclaveSessionParameters enclaveSessionParameters, SqlEnclaveSession enclaveSessionToInvalidate) + { + InvalidateEnclaveSessionHelper(enclaveSessionParameters, enclaveSessionToInvalidate); + } + } +} diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlBuffer.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlBuffer.cs index f2d332c95f..36c0df16d3 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlBuffer.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlBuffer.cs @@ -24,7 +24,6 @@ internal enum StorageType Int16, Int32, Int64, - Guid, Money, Single, String, @@ -95,8 +94,6 @@ internal struct Storage [FieldOffset(0)] internal long _int64; // also used to store Money, UtcDateTime, Date , and Time [FieldOffset(0)] - internal Guid _guid; - [FieldOffset(0)] internal float _single; [FieldOffset(0)] internal TimeInfo _timeInfo; @@ -126,7 +123,7 @@ private SqlBuffer(SqlBuffer value) _object = value._object; } - internal bool IsEmpty => _type == StorageType.Empty; + internal bool IsEmpty => StorageType.Empty == _type; internal bool IsNull => _isNull; @@ -219,16 +216,16 @@ internal decimal Decimal // Only removing trailing zeros from a decimal part won't hit its value! if (_value._numericInfo._scale > 0) { - int zeroCnt = FindTrailingZerosAndPrec((uint)_value._numericInfo._data1, (uint)_value._numericInfo._data2, - (uint)_value._numericInfo._data3, (uint)_value._numericInfo._data4, + int zeroCnt = FindTrailingZerosAndPrec((uint)_value._numericInfo._data1, (uint)_value._numericInfo._data2, + (uint)_value._numericInfo._data3, (uint)_value._numericInfo._data4, _value._numericInfo._scale, out int precision); int minScale = _value._numericInfo._scale - zeroCnt; // minimum possible sacle after removing the trailing zeros. if (zeroCnt > 0 && minScale <= 28 && precision <= 29) { - SqlDecimal sqlValue = new(_value._numericInfo._precision, _value._numericInfo._scale, _value._numericInfo._positive, - _value._numericInfo._data1, _value._numericInfo._data2, + SqlDecimal sqlValue = new(_value._numericInfo._precision, _value._numericInfo._scale, _value._numericInfo._positive, + _value._numericInfo._data1, _value._numericInfo._data2, _value._numericInfo._data3, _value._numericInfo._data4); int integral = precision - minScale; @@ -376,23 +373,9 @@ internal Guid Guid { get { + // TODO: It is possible to further optimize this, by storing the data from the wire without constructing a SqlGuid first, however we're already twice as fast! ThrowIfNull(); - if (StorageType.Guid == _type) - { - return _value._guid; - } - else if (StorageType.SqlGuid == _type) - { - return ((SqlGuid)_object).Value; - } - return (Guid)Value; - } - set - { - Debug.Assert(IsEmpty, "setting value a second time?"); - _type = StorageType.Guid; - _value._guid = value; - _isNull = false; + return SqlGuid.Value; } } @@ -498,8 +481,8 @@ internal string String } } - // use static list of format strings indexed by scale for perf - private static readonly string[] s_sql2008DateTimeOffsetFormatByScale = new string[] { + // use static list of format strings indexed by scale for perf! + private static readonly string[] s_katmaiDateTimeOffsetFormatByScale = new string[] { "yyyy-MM-dd HH:mm:ss zzz", "yyyy-MM-dd HH:mm:ss.f zzz", "yyyy-MM-dd HH:mm:ss.ff zzz", @@ -510,7 +493,7 @@ internal string String "yyyy-MM-dd HH:mm:ss.fffffff zzz", }; - private static readonly string[] s_sql2008DateTime2FormatByScale = new string[] { + private static readonly string[] s_katmaiDateTime2FormatByScale = new string[] { "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm:ss.f", "yyyy-MM-dd HH:mm:ss.ff", @@ -521,7 +504,7 @@ internal string String "yyyy-MM-dd HH:mm:ss.fffffff", }; - private static readonly string[] s_sql2008TimeFormatByScale = new string[] { + private static readonly string[] s_katmaiTimeFormatByScale = new string[] { "HH:mm:ss", "HH:mm:ss.f", "HH:mm:ss.ff", @@ -532,7 +515,7 @@ internal string String "HH:mm:ss.fffffff", }; - internal string Sql2008DateTimeString + internal string KatmaiDateTimeString { get { @@ -545,24 +528,24 @@ internal string Sql2008DateTimeString if (StorageType.Time == _type) { byte scale = _value._timeInfo._scale; - return new DateTime(_value._timeInfo._ticks).ToString(s_sql2008TimeFormatByScale[scale], DateTimeFormatInfo.InvariantInfo); + return new DateTime(_value._timeInfo._ticks).ToString(s_katmaiTimeFormatByScale[scale], DateTimeFormatInfo.InvariantInfo); } if (StorageType.DateTime2 == _type) { byte scale = _value._dateTime2Info._timeInfo._scale; - return DateTime.ToString(s_sql2008DateTime2FormatByScale[scale], DateTimeFormatInfo.InvariantInfo); + return DateTime.ToString(s_katmaiDateTime2FormatByScale[scale], DateTimeFormatInfo.InvariantInfo); } if (StorageType.DateTimeOffset == _type) { DateTimeOffset dto = DateTimeOffset; byte scale = _value._dateTimeOffsetInfo._dateTime2Info._timeInfo._scale; - return dto.ToString(s_sql2008DateTimeOffsetFormatByScale[scale], DateTimeFormatInfo.InvariantInfo); + return dto.ToString(s_katmaiDateTimeOffsetFormatByScale[scale], DateTimeFormatInfo.InvariantInfo); } return (string)Value; // anything else we haven't thought of goes through boxing. } } - internal SqlString Sql2008DateTimeSqlString + internal SqlString KatmaiDateTimeSqlString { get { @@ -575,7 +558,7 @@ internal SqlString Sql2008DateTimeSqlString { return SqlString.Null; } - return new SqlString(Sql2008DateTimeString); + return new SqlString(KatmaiDateTimeString); } return (SqlString)SqlValue; // anything else we haven't thought of goes through boxing. } @@ -774,13 +757,9 @@ internal SqlGuid SqlGuid { get { - if (StorageType.Guid == _type) + if (StorageType.SqlGuid == _type) { - return new SqlGuid(_value._guid); - } - else if (StorageType.SqlGuid == _type) - { - return IsNull ? SqlGuid.Null : (SqlGuid)_object; + return (SqlGuid)_object; } return (SqlGuid)SqlValue; // anything else we haven't thought of goes through boxing. } @@ -922,8 +901,6 @@ internal object SqlValue return SqlInt32; case StorageType.Int64: return SqlInt64; - case StorageType.Guid: - return SqlGuid; case StorageType.Money: return SqlMoney; case StorageType.Single: @@ -979,10 +956,6 @@ internal object SqlValue } } - - // these variables store pre-boxed bool values to be used when returning a boolean - // in a object typed location, if these are not used a new value is boxed each time - // one is needed which leads to a lot of garbage which needs to be collected private static readonly object s_cachedTrueObject = true; private static readonly object s_cachedFalseObject = false; @@ -999,7 +972,7 @@ internal object Value case StorageType.Empty: return DBNull.Value; case StorageType.Boolean: - return Boolean ? s_cachedTrueObject : s_cachedFalseObject; // return pre-boxed values for perf + return Boolean ? s_cachedTrueObject : s_cachedFalseObject; case StorageType.Byte: return Byte; case StorageType.DateTime: @@ -1014,8 +987,6 @@ internal object Value return Int32; case StorageType.Int64: return Int64; - case StorageType.Guid: - return Guid; case StorageType.Money: return Decimal; case StorageType.Single: @@ -1077,8 +1048,6 @@ internal Type GetTypeFromStorageType(bool isSqlType) return typeof(SqlInt32); case StorageType.Int64: return typeof(SqlInt64); - case StorageType.Guid: - return typeof(SqlGuid); case StorageType.Money: return typeof(SqlMoney); case StorageType.Single: @@ -1118,8 +1087,6 @@ internal Type GetTypeFromStorageType(bool isSqlType) return typeof(int); case StorageType.Int64: return typeof(long); - case StorageType.Guid: - return typeof(Guid); case StorageType.Money: return typeof(decimal); case StorageType.Single: @@ -1342,59 +1309,5 @@ private void ThrowIfNull() throw new SqlNullValueException(); } } - // [Field]As method explanation: - // these methods are used to bridge generic to non-generic access to value type fields on the storage struct - // where typeof(T) == typeof(field) - // 1) RyuJIT will recognize the pattern of (T)(object)T as being redundant and eliminate - // the T and object casts leaving T, so while this looks like it will put every value type instance in a box the - // generated assembly will be short and direct - // 2) another jit may not recognize the pattern and should emit the code as seen. this will box and then unbox the - // value type which is no worse than the mechanism that this code replaces - // where typeof(T) != typeof(field) - // the jit will emit all the cast operations as written. this will put the value into a box and then attempt to - // cast it, because it is an object no conversions are used and this will generate the desired InvalidCastException - // for example users cannot widen a short to an int preserving external expectations - - internal T ByteAs() - { - ThrowIfNull(); - return (T)(object)_value._byte; - } - - internal T BooleanAs() - { - ThrowIfNull(); - return (T)(object)_value._boolean; - } - - internal T Int32As() - { - ThrowIfNull(); - return (T)(object)_value._int32; - } - - internal T Int16As() - { - ThrowIfNull(); - return (T)(object)_value._int16; - } - - internal T Int64As() - { - ThrowIfNull(); - return (T)(object)_value._int64; - } - - internal T DoubleAs() - { - ThrowIfNull(); - return (T)(object)_value._double; - } - - internal T SingleAs() - { - ThrowIfNull(); - return (T)(object)_value._single; - } } } diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlBulkCopy.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlBulkCopy.cs index 81ccfb570a..3a2f91e7e7 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlBulkCopy.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlBulkCopy.cs @@ -436,16 +436,16 @@ private string CreateInitialQuery() string TDSCommand; TDSCommand = "select @@trancount; SET FMTONLY ON select * from " + ADP.BuildMultiPartName(parts) + " SET FMTONLY OFF "; - if (_connection.Is2000) + if (_connection.IsShiloh) { // If its a temp DB then try to connect string TableCollationsStoredProc; - if (_connection.Is2008OrNewer) + if (_connection.IsKatmaiOrNewer) { TableCollationsStoredProc = "sp_tablecollations_100"; } - else if (_connection.Is2005OrNewer) + else if (_connection.IsYukonOrNewer) { TableCollationsStoredProc = "sp_tablecollations_90"; } @@ -546,7 +546,7 @@ private string AnalyzeTargetAndCreateUpdateBulkCommand(BulkCopySimpleResultSet i StringBuilder updateBulkCommandText = new StringBuilder(); - if (_connection.Is2000 && 0 == internalResults[CollationResultId].Count) + if (_connection.IsShiloh && 0 == internalResults[CollationResultId].Count) { throw SQL.BulkLoadNoCollation(); } @@ -559,7 +559,7 @@ private string AnalyzeTargetAndCreateUpdateBulkCommand(BulkCopySimpleResultSet i bool isInTransaction; - if (_parser.Is2005OrNewer) + if (_parser.IsYukonOrNewer) { isInTransaction = _connection.HasLocalTransaction; } @@ -683,9 +683,9 @@ private string AnalyzeTargetAndCreateUpdateBulkCommand(BulkCopySimpleResultSet i } } - if (_connection.Is2000) + if (_connection.IsShiloh) { - // 2000 or above! + // Shiloh or above! // get collation for column i Result rowset = internalResults[CollationResultId]; @@ -2288,7 +2288,7 @@ private Task ReadWriteColumnValueAsync(int col) // Target type shouldn't be encrypted Debug.Assert(!metadata.isEncrypted, "Can't encrypt SQL Variant type"); SqlBuffer.StorageType variantInternalType = SqlBuffer.StorageType.Empty; - if ((_sqlDataReaderRowSource != null) && (_connection.Is2008OrNewer)) + if ((_sqlDataReaderRowSource != null) && (_connection.IsKatmaiOrNewer)) { variantInternalType = _sqlDataReaderRowSource.GetVariantInternalStorageType(_sortedColumnMappings[col]._sourceColumnOrdinal); } diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlClientPermission.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlClientPermission.cs index 8c497f90d2..2d8b080be7 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlClientPermission.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlClientPermission.cs @@ -15,23 +15,23 @@ namespace Microsoft.Data.SqlClient { - /// + /// [Serializable] public sealed class SqlClientPermission : System.Data.Common.DBDataPermission { - /// + /// [Obsolete("SqlClientPermission() has been deprecated. Use the SqlClientPermission(PermissionState.None) constructor. http://go.microsoft.com/fwlink/?linkid=14202", true)] // MDAC 86034 public SqlClientPermission() : this(PermissionState.None) { } - /// + /// public SqlClientPermission(PermissionState state) : base(state) { } - /// + /// [Obsolete("SqlClientPermission(PermissionState state, Boolean allowBlankPassword) has been deprecated. Use the SqlClientPermission(PermissionState.None) constructor. http://go.microsoft.com/fwlink/?linkid=14202", true)] // MDAC 86034 public SqlClientPermission(PermissionState state, bool allowBlankPassword) : this(state) { @@ -61,14 +61,14 @@ internal SqlClientPermission(SqlConnectionString constr) : base(PermissionState. } } - /// + /// public override void Add(string connectionString, string restrictions, KeyRestrictionBehavior behavior) { DBConnectionString constr = new DBConnectionString(connectionString, restrictions, behavior, SqlConnectionString.GetParseSynonyms(), false); AddPermissionEntry(constr); } - /// + /// override public IPermission Copy() { return new SqlClientPermission(this); @@ -126,7 +126,7 @@ private void CopyFrom(SqlClientPermission permission) } } - /// + /// override public IPermission Intersect(IPermission target) { // used during Deny actions if (null == target) @@ -179,7 +179,7 @@ private bool IsEmpty() return flag; } - /// + /// override public bool IsSubsetOf(IPermission target) { if (null == target) @@ -218,7 +218,7 @@ override public bool IsSubsetOf(IPermission target) return subset; } - /// + /// override public IPermission Union(IPermission target) { if (null == target) @@ -281,7 +281,7 @@ private string EncodeXmlValue(string value) // // // - /// + /// override public void FromXml(SecurityElement securityElement) { // code derived from CodeAccessPermission.ValidateElement @@ -344,7 +344,7 @@ override public void FromXml(SecurityElement securityElement) // // // - /// + /// override public SecurityElement ToXml() { Type type = this.GetType(); @@ -410,18 +410,18 @@ private static class XmlStr } - /// + /// [AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Assembly, AllowMultiple = true, Inherited = false)] [Serializable] public sealed class SqlClientPermissionAttribute : DBDataPermissionAttribute { - /// + /// public SqlClientPermissionAttribute(SecurityAction action) : base(action) { } - /// + /// override public IPermission CreatePermission() { return new SqlClientPermission(this); diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlColumnEncryptionCertificateStoreProvider.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlColumnEncryptionCertificateStoreProvider.cs index e8dca4c858..bbe7e2f76b 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlColumnEncryptionCertificateStoreProvider.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlColumnEncryptionCertificateStoreProvider.cs @@ -10,7 +10,7 @@ namespace Microsoft.Data.SqlClient { - /// + /// public class SqlColumnEncryptionCertificateStoreProvider : SqlColumnEncryptionKeyStoreProvider { // Constants @@ -18,7 +18,7 @@ public class SqlColumnEncryptionCertificateStoreProvider : SqlColumnEncryptionKe // Assumption: Certificate Locations (LocalMachine & CurrentUser), Certificate Store name "My" // Certificate provider name (CertificateStore) dont need to be localized. - /// + /// public const string ProviderName = @"MSSQL_CERTIFICATE_STORE"; /// @@ -56,7 +56,7 @@ public class SqlColumnEncryptionCertificateStoreProvider : SqlColumnEncryptionKe /// private readonly byte[] _version = new byte[] { 0x01 }; - /// + /// public override byte[] DecryptColumnEncryptionKey(string masterKeyPath, string encryptionAlgorithm, byte[] encryptedColumnEncryptionKey) { // Validate the input parameters @@ -150,7 +150,7 @@ public override byte[] DecryptColumnEncryptionKey(string masterKeyPath, string e return RSADecrypt(cipherText, certificate); } - /// + /// public override byte[] EncryptColumnEncryptionKey(string masterKeyPath, string encryptionAlgorithm, byte[] columnEncryptionKey) { // Validate the input parameters @@ -240,7 +240,7 @@ public override byte[] EncryptColumnEncryptionKey(string masterKeyPath, string e return encryptedColumnEncryptionKey; } - /// + /// public override byte[] SignColumnMasterKeyMetadata(string masterKeyPath, bool allowEnclaveComputations) { var hash = ComputeMasterKeyMetadataHash(masterKeyPath, allowEnclaveComputations, isSystemOp: false); @@ -253,7 +253,7 @@ public override byte[] SignColumnMasterKeyMetadata(string masterKeyPath, bool al return signature; } - /// + /// public override bool VerifyColumnMasterKeyMetadata(string masterKeyPath, bool allowEnclaveComputations, byte[] signature) { var hash = ComputeMasterKeyMetadataHash(masterKeyPath, allowEnclaveComputations, isSystemOp: true); diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlColumnEncryptionCngProvider.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlColumnEncryptionCngProvider.cs index ad84233197..bded38eeee 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlColumnEncryptionCngProvider.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlColumnEncryptionCngProvider.cs @@ -9,10 +9,10 @@ namespace Microsoft.Data.SqlClient { - /// + /// public class SqlColumnEncryptionCngProvider : SqlColumnEncryptionKeyStoreProvider { - /// + /// public const string ProviderName = @"MSSQL_CNG_STORE"; /// @@ -26,7 +26,7 @@ public class SqlColumnEncryptionCngProvider : SqlColumnEncryptionKeyStoreProvide /// private readonly byte[] _version = new byte[] { 0x01 }; - /// + /// public override byte[] DecryptColumnEncryptionKey(string masterKeyPath, string encryptionAlgorithm, byte[] encryptedColumnEncryptionKey) { // Validate the input parameters @@ -120,7 +120,7 @@ public override byte[] DecryptColumnEncryptionKey(string masterKeyPath, string e return RSADecrypt(rsaCngProvider, cipherText); } - /// + /// public override byte[] EncryptColumnEncryptionKey(string masterKeyPath, string encryptionAlgorithm, byte[] columnEncryptionKey) { // Validate the input parameters @@ -210,13 +210,13 @@ public override byte[] EncryptColumnEncryptionKey(string masterKeyPath, string e return encryptedColumnEncryptionKey; } - /// + /// public override byte[] SignColumnMasterKeyMetadata(string masterKeyPath, bool allowEnclaveComputations) { throw new NotSupportedException(); } - /// + /// public override bool VerifyColumnMasterKeyMetadata(string masterKeyPath, bool allowEnclaveComputations, byte[] signature) { throw new NotSupportedException(); diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlColumnEncryptionCspProvider.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlColumnEncryptionCspProvider.cs index 6296d4005d..33996913c2 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlColumnEncryptionCspProvider.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlColumnEncryptionCspProvider.cs @@ -10,10 +10,10 @@ namespace Microsoft.Data.SqlClient { - /// + /// public class SqlColumnEncryptionCspProvider : SqlColumnEncryptionKeyStoreProvider { - /// + /// public const string ProviderName = @"MSSQL_CSP_PROVIDER"; /// @@ -30,7 +30,7 @@ public class SqlColumnEncryptionCspProvider : SqlColumnEncryptionKeyStoreProvide /// private readonly byte[] _version = new byte[] { 0x01 }; - /// + /// public override byte[] DecryptColumnEncryptionKey(string masterKeyPath, string encryptionAlgorithm, byte[] encryptedColumnEncryptionKey) { // Validate the input parameters @@ -124,7 +124,7 @@ public override byte[] DecryptColumnEncryptionKey(string masterKeyPath, string e return RSADecrypt(rsaProvider, cipherText); } - /// + /// public override byte[] EncryptColumnEncryptionKey(string masterKeyPath, string encryptionAlgorithm, byte[] columnEncryptionKey) { // Validate the input parameters @@ -214,13 +214,13 @@ public override byte[] EncryptColumnEncryptionKey(string masterKeyPath, string e return encryptedColumnEncryptionKey; } - /// + /// public override byte[] SignColumnMasterKeyMetadata(string masterKeyPath, bool allowEnclaveComputations) { throw new NotSupportedException(); } - /// + /// public override bool VerifyColumnMasterKeyMetadata(string masterKeyPath, bool allowEnclaveComputations, byte[] signature) { throw new NotSupportedException(); diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlCommand.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlCommand.cs index 1658944d87..35f5353f89 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlCommand.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlCommand.cs @@ -86,9 +86,9 @@ public sealed class SqlCommand : DbCommand, ICloneable internal static readonly Action s_cancelIgnoreFailure = CancelIgnoreFailureCallback; // devnote: Prepare - // Against 7.0 Server a prepare/unprepare requires an extra roundtrip to the server. + // Against 7.0 Server (Sphinx) a prepare/unprepare requires an extra roundtrip to the server. // - // From 8.0 (2000) and above the preparation can be done as part of the command execution. + // From 8.0 (Shiloh) and above (Yukon) the preparation can be done as part of the command execution. // private enum EXECTYPE { @@ -386,7 +386,7 @@ internal override void ParametersAvailable(SmiParameterMetaData[] metaData, ITyp } } - Debug.Assert(SmiContextFactory.Instance.NegotiatedSmiVersion >= SmiContextFactory.Sql2005Version); + Debug.Assert(SmiContextFactory.Instance.NegotiatedSmiVersion >= SmiContextFactory.YukonVersion); _command.OnParametersAvailableSmi(metaData, parameterValues); } @@ -396,7 +396,7 @@ internal override void ParameterAvailable(SmiParameterMetaData metaData, SmiType { SqlClientEventSource.Log.AdvancedTraceEvent(" {0}, metaData[{1}] is {2}{ 3}", _command.ObjectID, ordinal, metaData?.GetType(), metaData?.TraceString()); } - Debug.Assert(SmiContextFactory.Instance.NegotiatedSmiVersion >= SmiContextFactory.Sql2008Version); + Debug.Assert(SmiContextFactory.Instance.NegotiatedSmiVersion >= SmiContextFactory.KatmaiVersion); _command.OnParameterAvailableSmi(metaData, parameterValues, ordinal); } } @@ -610,14 +610,14 @@ private SqlInternalConnectionTds InternalTdsConnection } } - private bool Is2000 + private bool IsShiloh { get { Debug.Assert(_activeConnection != null, "The active connection is null!"); if (_activeConnection == null) return false; - return _activeConnection.Is2000; + return _activeConnection.IsShiloh; } } @@ -3374,8 +3374,8 @@ private enum ProcParamsColIndex { ParameterName = 0, ParameterType, - DataType, // obsolete in 2008, use ManagedDataType instead - ManagedDataType, // new in 2008 + DataType, // obsolete in katmai, use ManagedDataType instead + ManagedDataType, // new in katmai CharacterMaximumLength, NumericPrecision, NumericScale, @@ -3385,16 +3385,16 @@ private enum ProcParamsColIndex XmlSchemaCollectionCatalogName, XmlSchemaCollectionSchemaName, XmlSchemaCollectionName, - UdtTypeName, // obsolete in 2008. Holds the actual typename if UDT, since TypeName didn't back then. - DateTimeScale // new in 2008 + UdtTypeName, // obsolete in Katmai. Holds the actual typename if UDT, since TypeName didn't back then. + DateTimeScale // new in Katmai }; - // 2005- column ordinals (this array indexed by ProcParamsColIndex - internal static readonly string[] PreSql2008ProcParamsNames = new string[] { + // Yukon- column ordinals (this array indexed by ProcParamsColIndex + internal static readonly string[] PreKatmaiProcParamsNames = new string[] { "PARAMETER_NAME", // ParameterName, "PARAMETER_TYPE", // ParameterType, "DATA_TYPE", // DataType - null, // ManagedDataType, introduced in 2008 + null, // ManagedDataType, introduced in Katmai "CHARACTER_MAXIMUM_LENGTH", // CharacterMaximumLength, "NUMERIC_PRECISION", // NumericPrecision, "NUMERIC_SCALE", // NumericScale, @@ -3405,14 +3405,14 @@ private enum ProcParamsColIndex "XML_SCHEMANAME", // XmlSchemaCollectionSchemaName, "XML_SCHEMACOLLECTIONNAME", // XmlSchemaCollectionName "UDT_NAME", // UdtTypeName - null, // Scale for datetime types with scale, introduced in 2008 + null, // Scale for datetime types with scale, introduced in Katmai }; - // 2008+ column ordinals (this array indexed by ProcParamsColIndex - internal static readonly string[] Sql2008ProcParamsNames = new string[] { + // Katmai+ column ordinals (this array indexed by ProcParamsColIndex + internal static readonly string[] KatmaiProcParamsNames = new string[] { "PARAMETER_NAME", // ParameterName, "PARAMETER_TYPE", // ParameterType, - null, // DataType, removed from 2008+ + null, // DataType, removed from Katmai+ "MANAGED_DATA_TYPE", // ManagedDataType, "CHARACTER_MAXIMUM_LENGTH", // CharacterMaximumLength, "NUMERIC_PRECISION", // NumericPrecision, @@ -3423,7 +3423,7 @@ private enum ProcParamsColIndex "XML_CATALOGNAME", // XmlSchemaCollectionCatalogName, "XML_SCHEMANAME", // XmlSchemaCollectionSchemaName, "XML_SCHEMACOLLECTIONNAME", // XmlSchemaCollectionName - null, // UdtTypeName, removed from 2008+ + null, // UdtTypeName, removed from Katmai+ "SS_DATETIME_PRECISION", // Scale for datetime types with scale }; @@ -3458,7 +3458,7 @@ internal void DeriveParameters() StringBuilder cmdText = new StringBuilder(); // Build call for sp_procedure_params_rowset built of unquoted values from user: - // [user server, if provided].[user catalog, else current database].[sys if 2005, else blank].[sp_procedure_params_rowset] + // [user server, if provided].[user catalog, else current database].[sys if Yukon, else blank].[sp_procedure_params_rowset] // Server - pass only if user provided. if (!ADP.IsEmpty(parsedSProc[0])) @@ -3475,21 +3475,21 @@ internal void DeriveParameters() SqlCommandSet.BuildStoredProcedureName(cmdText, parsedSProc[1]); cmdText.Append("."); - // Schema - only if 2005, and then only pass sys. Also - pass managed version of sproc - // for 2005, else older sproc. + // Schema - only if Yukon, and then only pass sys. Also - pass managed version of sproc + // for Yukon, else older sproc. string[] colNames; bool useManagedDataType; - if (Connection.Is2008OrNewer) + if (Connection.IsKatmaiOrNewer) { // Procedure - [sp_procedure_params_managed] cmdText.Append("[sys].[").Append(TdsEnums.SP_PARAMS_MGD10).Append("]"); - colNames = Sql2008ProcParamsNames; + colNames = KatmaiProcParamsNames; useManagedDataType = true; } else { - if (this.Connection.Is2005OrNewer) + if (this.Connection.IsYukonOrNewer) { // Procedure - [sp_procedure_params_managed] cmdText.Append("[sys].[").Append(TdsEnums.SP_PARAMS_MANAGED).Append("]"); @@ -3500,7 +3500,7 @@ internal void DeriveParameters() cmdText.Append(".[").Append(TdsEnums.SP_PARAMS).Append("]"); } - colNames = PreSql2008ProcParamsNames; + colNames = PreKatmaiProcParamsNames; useManagedDataType = false; } @@ -3556,7 +3556,7 @@ internal void DeriveParameters() { p.SqlDbType = (SqlDbType)(short)r[colNames[(int)ProcParamsColIndex.ManagedDataType]]; - // 2005 didn't have as accurate of information as we're getting for 2008, so re-map a couple of + // Yukon didn't have as accurate of information as we're getting for Katmai, so re-map a couple of // types for backward compatability. switch (p.SqlDbType) { @@ -3590,9 +3590,9 @@ internal void DeriveParameters() { int size = (int)a; - // Map MAX sizes correctly. The 2008 server-side proc sends 0 for these instead of -1. - // Should be fixed on the 2008 side, but would likely hold up the RI, and is safer to fix here. - // If we can get the server-side fixed before shipping 2008, we can remove this mapping. + // Map MAX sizes correctly. The Katmai server-side proc sends 0 for these instead of -1. + // Should be fixed on the Katmai side, but would likely hold up the RI, and is safer to fix here. + // If we can get the server-side fixed before shipping Katmai, we can remove this mapping. if (0 == size && (p.SqlDbType == SqlDbType.NVarChar || p.SqlDbType == SqlDbType.VarBinary || @@ -3616,7 +3616,7 @@ internal void DeriveParameters() if (SqlDbType.Udt == p.SqlDbType) { - Debug.Assert(this._activeConnection.Is2005OrNewer, "Invalid datatype token received from pre-2005 server"); + Debug.Assert(this._activeConnection.IsYukonOrNewer, "Invalid datatype token received from pre-yukon server"); string udtTypeName; if (useManagedDataType) @@ -3637,7 +3637,7 @@ internal void DeriveParameters() // type name for Structured types (same as for Udt's except assign p.TypeName instead of p.UdtTypeName if (SqlDbType.Structured == p.SqlDbType) { - Debug.Assert(_activeConnection.Is2008OrNewer, "Invalid datatype token received from pre-2008 server"); + Debug.Assert(_activeConnection.IsKatmaiOrNewer, "Invalid datatype token received from pre-katmai server"); //read the type name p.TypeName = r[colNames[(int)ProcParamsColIndex.TypeCatalogName]] + "." + @@ -3742,8 +3742,8 @@ private void CheckNotificationStateAndAutoEnlist() // present. If so, auto enlist to the dependency ID given in the context data. if (NotificationAutoEnlist) { - if (_activeConnection.Is2005OrNewer) - { // Only supported for 2005... + if (_activeConnection.IsYukonOrNewer) + { // Only supported for Yukon... string notifyContext = SqlNotificationContext(); if (!ADP.IsEmpty(notifyContext)) { @@ -3944,7 +3944,7 @@ private void RunExecuteNonQuerySmi(bool sendToPipe) SqlClientEventSource.Log.TryAdvancedTraceEvent(" {0}, innerConnection={1}, transactionId=0x{2}, cmdBehavior={3}.", ObjectID, innerConnection.ObjectID, transactionId, (int)CommandBehavior.Default); - if (SmiContextFactory.Instance.NegotiatedSmiVersion >= SmiContextFactory.Sql2008Version) + if (SmiContextFactory.Instance.NegotiatedSmiVersion >= SmiContextFactory.KatmaiVersion) { eventStream = requestExecutor.Execute( innerConnection.SmiConnection, @@ -5431,7 +5431,7 @@ private SqlDataReader RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavi } else if (_execType == EXECTYPE.PREPAREPENDING) { - Debug.Assert(_activeConnection.Is2000, "Invalid attempt to call sp_prepexec on non 7.x server"); + Debug.Assert(_activeConnection.IsShiloh, "Invalid attempt to call sp_prepexec on non 7.x server"); rpc = BuildPrepExec(cmdBehavior); // next time through, only do an exec _execType = EXECTYPE.PREPARED; @@ -5446,8 +5446,8 @@ private SqlDataReader RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavi BuildExecuteSql(cmdBehavior, null, _parameters, ref rpc); } - // if 2000, then set NOMETADATA_UNLESSCHANGED flag - if (_activeConnection.Is2000) + // if shiloh, then set NOMETADATA_UNLESSCHANGED flag + if (_activeConnection.IsShiloh) rpc.options = TdsEnums.RPC_NOMETADATA; if (returnStream) { @@ -5461,10 +5461,10 @@ private SqlDataReader RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavi else { Debug.Assert(this.CommandType == System.Data.CommandType.StoredProcedure, "unknown command type!"); - // note: invalid asserts on 2000. On 8.0 (2000) and above a command is ALWAYS prepared + // note: invalid asserts on Shiloh. On 8.0 (Shiloh) and above a command is ALWAYS prepared // and IsDirty is always set if there are changes and the command is marked Prepared! - Debug.Assert(Is2000 || !IsPrepared, "RPC should not be prepared!"); - Debug.Assert(Is2000 || !IsDirty, "RPC should not be marked as dirty!"); + Debug.Assert(IsShiloh || !IsPrepared, "RPC should not be prepared!"); + Debug.Assert(IsShiloh || !IsDirty, "RPC should not be marked as dirty!"); BuildRPC(inSchema, _parameters, ref rpc); @@ -5571,7 +5571,7 @@ private SqlDataReader RunExecuteReaderSmi(CommandBehavior cmdBehavior, RunBehavi innerConnection.GetCurrentTransactionPair(out transactionId, out transaction); SqlClientEventSource.Log.TryAdvancedTraceEvent(" {0}, innerConnection={1}, transactionId=0x{2}, commandBehavior={(int)cmdBehavior}.", ObjectID, innerConnection.ObjectID, transactionId); - if (SmiContextFactory.Instance.NegotiatedSmiVersion >= SmiContextFactory.Sql2008Version) + if (SmiContextFactory.Instance.NegotiatedSmiVersion >= SmiContextFactory.KatmaiVersion) { eventStream = requestExecutor.Execute( innerConnection.SmiConnection, @@ -5915,10 +5915,10 @@ private void ValidateCommand(string method, bool async) if (ADP.IsEmpty(this.CommandText)) throw ADP.CommandTextRequired(method); - // Notification property must be null for pre-2005 connections - if ((Notification != null) && !_activeConnection.Is2005OrNewer) + // Notification property must be null for pre-Yukon connections + if ((Notification != null) && !_activeConnection.IsYukonOrNewer) { - throw SQL.NotificationsRequire2005(); + throw SQL.NotificationsRequireYukon(); } if ((async) && (_activeConnection.IsContextConnection)) @@ -6375,7 +6375,7 @@ internal void OnParameterAvailableSmi(SmiParameterMetaData metaData, ITypedGette param.CompareInfo = metaData.CompareOptions; SqlBuffer buffer = new SqlBuffer(); object result; - if (_activeConnection.Is2008OrNewer) + if (_activeConnection.IsKatmaiOrNewer) { result = ValueUtilsSmi.GetOutputParameterV200Smi( OutParamEventSink, (SmiTypedGetterSetter)parameterValues, ordinal, metaData, _smiRequestContext, buffer); @@ -6525,7 +6525,7 @@ private void SetUpRPCParameters(_SqlRPC rpc, int startCount, bool inSchema, SqlP int paramCount = GetParameterCount(parameters); int j = startCount; TdsParser parser = _activeConnection.Parser; - bool is2005OrNewer = parser.Is2005OrNewer; + bool yukonOrNewer = parser.IsYukonOrNewer; for (ii = 0; ii < paramCount; ii++) { @@ -6534,7 +6534,7 @@ private void SetUpRPCParameters(_SqlRPC rpc, int startCount, bool inSchema, SqlP // func will change type to that with a 4 byte length if the type has a two // byte length and a parameter length > than that expressable in 2 bytes - if ((!parameter.ValidateTypeLengths(is2005OrNewer).IsPlp) && (parameter.Direction != ParameterDirection.Output)) + if ((!parameter.ValidateTypeLengths(yukonOrNewer).IsPlp) && (parameter.Direction != ParameterDirection.Output)) { parameter.FixStreamDataForNonPLP(); } @@ -6910,7 +6910,7 @@ internal string BuildParamList(TdsParser parser, SqlParameterCollection paramete StringBuilder paramList = new StringBuilder(); bool fAddSeparator = false; - bool is2005OrNewer = parser.Is2005OrNewer; + bool yukonOrNewer = parser.IsYukonOrNewer; int count = 0; @@ -6961,7 +6961,7 @@ internal string BuildParamList(TdsParser parser, SqlParameterCollection paramete { // func will change type to that with a 4 byte length if the type has a two // byte length and a parameter length > than that expressable in 2 bytes - mt = sqlParam.ValidateTypeLengths(is2005OrNewer); + mt = sqlParam.ValidateTypeLengths(yukonOrNewer); if ((!mt.IsPlp) && (sqlParam.Direction != ParameterDirection.Output)) { sqlParam.FixStreamDataForNonPLP(); @@ -6980,13 +6980,13 @@ internal string BuildParamList(TdsParser parser, SqlParameterCollection paramete if (0 == precision) { - if (Is2000) + if (IsShiloh) { precision = TdsEnums.DEFAULT_NUMERIC_PRECISION; } else { - precision = TdsEnums.SQL70_DEFAULT_NUMERIC_PRECISION; + precision = TdsEnums.SPHINX_DEFAULT_NUMERIC_PRECISION; } } @@ -7474,7 +7474,7 @@ private SmiRequestExecutor SetUpSmiRequest(SqlInternalConnectionSmi innerConnect requestMetaData[index] = param.MetaDataForSmi(out peekAheadValues[index]); // Check for valid type for version negotiated - if (!innerConnection.Is2008OrNewer) + if (!innerConnection.IsKatmaiOrNewer) { MetaType mt = MetaType.GetMetaTypeFromSqlDbType(requestMetaData[index].SqlDbType, requestMetaData[index].IsMultiValued); if (!mt.Is90Supported) @@ -7604,7 +7604,7 @@ private SmiRequestExecutor SetUpSmiRequest(SqlInternalConnectionSmi innerConnect } } - if (innerConnection.Is2008OrNewer) + if (innerConnection.IsKatmaiOrNewer) { ValueUtilsSmi.SetCompatibleValueV200(EventSink, requestExecutor, index, requestMetaData[index], value, typeCode, param.Offset, param.Size, peekAheadValues[index]); } diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlConnection.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlConnection.cs index 71c9be4cbc..b6c2b5d930 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlConnection.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlConnection.cs @@ -36,7 +36,7 @@ namespace Microsoft.Data.SqlClient using System.Diagnostics.Tracing; using Microsoft.Data.Common; - /// + /// [ DefaultEvent("InfoMessage"), DesignerCategory("") @@ -88,7 +88,7 @@ static private readonly ConcurrentDictionary> _ColumnEncry capacity: 1, comparer: StringComparer.OrdinalIgnoreCase); - /// + /// [ DefaultValue(null), ResCategoryAttribute(StringsHelper.ResourceNames.DataCategory_Data), @@ -101,7 +101,7 @@ static private readonly ConcurrentDictionary> _ColumnEncry /// static private bool _ColumnEncryptionQueryMetadataCacheEnabled = true; - /// + /// [ DefaultValue(null), ResCategoryAttribute(StringsHelper.ResourceNames.DataCategory_Data), @@ -124,7 +124,7 @@ static public bool ColumnEncryptionQueryMetadataCacheEnabled /// static private TimeSpan _ColumnEncryptionKeyCacheTtl = TimeSpan.FromHours(2); - /// + /// [ DefaultValue(null), ResCategoryAttribute(StringsHelper.ResourceNames.DataCategory_Data), @@ -136,7 +136,7 @@ static public TimeSpan ColumnEncryptionKeyCacheTtl set => _ColumnEncryptionKeyCacheTtl = value; } - /// + /// static public void RegisterColumnEncryptionKeyStoreProviders(IDictionary customProviders) { ValidateCustomProviders(customProviders); @@ -340,12 +340,12 @@ public SqlRetryLogicBaseProvider RetryLogicProvider // using SqlConnection.Open() method. internal bool _applyTransientFaultHandling = false; - /// + /// public SqlConnection(string connectionString) : this(connectionString, null) { } - /// + /// public SqlConnection(string connectionString, SqlCredential credential) : this() { ConnectionString = connectionString; // setting connection string first so that ConnectionOption is available @@ -445,7 +445,7 @@ private void CacheConnectionStringProperties() // PUBLIC PROPERTIES // - /// + /// // used to start/stop collection of statistics data and do verify the current state // // devnote: start/stop should not performed using a property since it requires execution of code @@ -683,7 +683,7 @@ internal int ConnectRetryInterval } } - /// + /// override protected DbProviderFactory DbProviderFactory { get @@ -693,7 +693,7 @@ override protected DbProviderFactory DbProviderFactory } // AccessToken: To be used for token based authentication - /// + /// [ Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), @@ -734,7 +734,7 @@ public string AccessToken } } - /// + /// [ DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), ResDescriptionAttribute(StringsHelper.ResourceNames.SqlConnection_ConnectionTimeout), @@ -748,7 +748,7 @@ public int CommandTimeout } } - /// + /// [ DefaultValue(""), #pragma warning disable 618 // ignore obsolete warning about RecommendedAsConfigurable to use SettingsBindableAttribute @@ -814,7 +814,7 @@ override public string ConnectionString } } - /// + /// [ DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), ResDescriptionAttribute(StringsHelper.ResourceNames.SqlConnection_ConnectionTimeout), @@ -828,7 +828,7 @@ override public int ConnectionTimeout } } - /// + /// [ DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), ResDescriptionAttribute(StringsHelper.ResourceNames.SqlConnection_Database), @@ -904,7 +904,7 @@ internal string SQLDNSCachingSupportedStateBeforeRedirect } } - /// + /// [ Browsable(true), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), @@ -930,7 +930,7 @@ override public string DataSource } } - /// + /// [ DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), ResCategoryAttribute(StringsHelper.ResourceNames.DataCategory_Data), @@ -964,7 +964,7 @@ public int PacketSize } } - /// + /// [ DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), ResCategoryAttribute(StringsHelper.ResourceNames.DataCategory_Data), @@ -995,7 +995,7 @@ public Guid ClientConnectionId } } - /// + /// [ Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), @@ -1021,7 +1021,7 @@ public int ServerProcessId GetOpenTdsConnection().ServerProcessId : 0; } - /// + /// [ Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), @@ -1049,7 +1049,7 @@ internal SqlStatistics Statistics } } - /// + /// [ DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), ResCategoryAttribute(StringsHelper.ResourceNames.DataCategory_Data), @@ -1079,7 +1079,7 @@ public string WorkstationId } } - /// + /// // SqlCredential: Pair User Id and password in SecureString which are to be used for SQL authentication [ Browsable(false), @@ -1218,7 +1218,7 @@ private void CheckAndThrowOnInvalidCombinationOfConnectionOptionAndAccessToken(S // PUBLIC EVENTS // - /// + /// [ ResCategoryAttribute(StringsHelper.ResourceNames.DataCategory_InfoMessage), ResDescriptionAttribute(StringsHelper.ResourceNames.DbConnection_InfoMessage), @@ -1235,7 +1235,7 @@ public event SqlInfoMessageEventHandler InfoMessage } } - /// + /// public bool FireInfoMessageEventOnUserErrors { get @@ -1299,21 +1299,21 @@ internal int ReconnectCount // // PUBLIC METHODS // - /// + /// new public SqlTransaction BeginTransaction() { // this is just a delegate. The actual method tracks executiontime return BeginTransaction(IsolationLevel.Unspecified, null); } - /// + /// new public SqlTransaction BeginTransaction(IsolationLevel iso) { // this is just a delegate. The actual method tracks executiontime return BeginTransaction(iso, null); } - /// + /// public SqlTransaction BeginTransaction(string transactionName) { // Use transaction names only on the outermost pair of nested @@ -1323,7 +1323,7 @@ public SqlTransaction BeginTransaction(string transactionName) return BeginTransaction(IsolationLevel.Unspecified, transactionName); } - /// + /// // suppress this message - we cannot use SafeHandle here. Also, see notes in the code (VSTFDEVDIV# 560355) [SuppressMessage("Microsoft.Reliability", "CA2004:RemoveCallsToGCKeepAlive")] override protected DbTransaction BeginDbTransaction(IsolationLevel isolationLevel) @@ -1343,7 +1343,7 @@ override protected DbTransaction BeginDbTransaction(IsolationLevel isolationLeve } } - /// + /// public SqlTransaction BeginTransaction(IsolationLevel iso, string transactionName) { WaitForPendingReconnection(); @@ -1381,7 +1381,7 @@ public SqlTransaction BeginTransaction(IsolationLevel iso, string transactionNam } } - /// + /// override public void ChangeDatabase(string database) { SqlStatistics statistics = null; @@ -1435,14 +1435,14 @@ override public void ChangeDatabase(string database) } } - /// + /// static public void ClearAllPools() { (new SqlClientPermission(PermissionState.Unrestricted)).Demand(); SqlConnectionFactory.SingletonInstance.ClearAllPools(); } - /// + /// static public void ClearPool(SqlConnection connection) { ADP.CheckArgumentNull(connection, "connection"); @@ -1459,7 +1459,7 @@ static public void ClearPool(SqlConnection connection) } } - /// + /// object ICloneable.Clone() { SqlConnection clone = new SqlConnection(this); @@ -1477,7 +1477,7 @@ void CloseInnerConnection() InnerConnection.CloseConnection(this, ConnectionFactory); } - /// + /// override public void Close() { using (TryEventScope.Create(" {0}", ObjectID)) @@ -1573,7 +1573,7 @@ override public void Close() } } - /// + /// new public SqlCommand CreateCommand() { return new SqlCommand(null, this); @@ -1604,7 +1604,7 @@ private void DisposeMe(bool disposing) } } - /// + /// public void EnlistDistributedTransaction(System.EnterpriseServices.ITransaction transaction) { if (IsContextConnection) @@ -1615,7 +1615,7 @@ public void EnlistDistributedTransaction(System.EnterpriseServices.ITransaction EnlistDistributedTransactionHelper(transaction); } - /// + /// override public void Open() { Open(SqlConnectionOverrides.None); @@ -1881,7 +1881,7 @@ void CancelOpenAndWait() private Task InternalOpenWithRetryAsync(CancellationToken cancellationToken) => RetryLogicProvider.ExecuteAsync(this, () => InternalOpenAsync(cancellationToken), cancellationToken); - /// + /// public override Task OpenAsync(CancellationToken cancellationToken) => IsProviderRetriable ? InternalOpenWithRetryAsync(cancellationToken) : @@ -2218,39 +2218,39 @@ internal bool HasLocalTransactionFromAPI } } - internal bool Is2000 + internal bool IsShiloh { get { if (_currentReconnectionTask != null) { // holds true even if task is completed - return true; // if CR is enabled, connection, if established, will be 2008+ + return true; // if CR is enabled, connection, if established, will be Katmai+ } - return GetOpenConnection().Is2000; + return GetOpenConnection().IsShiloh; } } - internal bool Is2005OrNewer + internal bool IsYukonOrNewer { get { if (_currentReconnectionTask != null) { // holds true even if task is completed - return true; // if CR is enabled, connection, if established, will be 2008+ + return true; // if CR is enabled, connection, if established, will be Katmai+ } - return GetOpenConnection().Is2005OrNewer; + return GetOpenConnection().IsYukonOrNewer; } } - internal bool Is2008OrNewer + internal bool IsKatmaiOrNewer { get { if (_currentReconnectionTask != null) { // holds true even if task is completed - return true; // if CR is enabled, connection, if established, will be 2008+ + return true; // if CR is enabled, connection, if established, will be Katmai+ } - return GetOpenConnection().Is2008OrNewer; + return GetOpenConnection().IsKatmaiOrNewer; } } @@ -2377,8 +2377,8 @@ private void CompleteOpen() // be sure to mark as open so SqlDebugCheck can issue Query // check to see if we need to hook up sql-debugging if a debugger is attached - // We only need this check for 2000 and earlier servers. - if (!GetOpenConnection().Is2005OrNewer && + // We only need this check for Shiloh and earlier servers. + if (!GetOpenConnection().IsYukonOrNewer && System.Diagnostics.Debugger.IsAttached) { bool debugCheck = false; @@ -2613,9 +2613,9 @@ private void CheckSQLDebug(SqlDebugContext sdc) private void IssueSQLDebug(uint option, string machineName, uint pid, uint id, string sdiDllName, byte[] data) { - if (GetOpenConnection().Is2005OrNewer) + if (GetOpenConnection().IsYukonOrNewer) { - // TODO: When 2005 actually supports debugging, we need to modify this method to do the right thing(tm) + // TODO: When Yukon actually supports debugging, we need to modify this method to do the right thing(tm) return; } @@ -2664,7 +2664,7 @@ private void IssueSQLDebug(uint option, string machineName, uint pid, uint id, s c.ExecuteNonQuery(); } - /// + /// public static void ChangePassword(string connectionString, string newPassword) { using (TryEventScope.Create("")) @@ -2707,7 +2707,7 @@ public static void ChangePassword(string connectionString, string newPassword) } } - /// + /// public static void ChangePassword(string connectionString, SqlCredential credential, SecureString newSecurePassword) { using (TryEventScope.Create("")) @@ -2780,9 +2780,9 @@ private static void ChangePassword(string connectionString, SqlConnectionString // using (SqlInternalConnectionTds con = new SqlInternalConnectionTds(null, connectionOptions, credential, null, newPassword, newSecurePassword, false, null, null, null, null)) { - if (!con.Is2005OrNewer) + if (!con.IsYukonOrNewer) { - throw SQL.ChangePasswordRequires2005(); + throw SQL.ChangePasswordRequiresYukon(); } } SqlConnectionPoolKey key = new SqlConnectionPoolKey(connectionString, credential, accessToken: null, serverCertificateValidationCallback: null, clientCertificateRetrievalCallback: null, originalNetworkAddressInfo: null); @@ -2816,7 +2816,7 @@ static private void RefreshMemoryMappedData(SqlDebugContext sdc) sdc.data = memMap.rgbData; } - /// + /// public void ResetStatistics() { if (IsContextConnection) @@ -2835,7 +2835,7 @@ public void ResetStatistics() } } - /// + /// public IDictionary RetrieveStatistics() { if (IsContextConnection) @@ -2865,7 +2865,7 @@ private void UpdateStatistics() Statistics.UpdateStatistics(); } - /// + /// public IDictionary RetrieveInternalInfo() { IDictionary internalDictionary = new Dictionary(); diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlConnectionHelper.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlConnectionHelper.cs index 07d44f020c..eb41758480 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlConnectionHelper.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlConnectionHelper.cs @@ -28,7 +28,7 @@ public sealed partial class SqlConnection : DbConnection private static int _objectTypeCount; // EventSource Counter internal readonly int ObjectID = System.Threading.Interlocked.Increment(ref _objectTypeCount); - /// + /// public SqlConnection() : base() { GC.SuppressFinalize(this); @@ -197,7 +197,7 @@ internal void AddWeakReference(object value, int tag) InnerConnection.AddWeakReference(value, tag); } - /// + /// override protected DbCommand CreateDbCommand() { using (TryEventScope.Create(" {0}", ObjectID)) @@ -216,7 +216,7 @@ private static System.Security.CodeAccessPermission CreateExecutePermission() return p; } - /// + /// override protected void Dispose(bool disposing) { if (disposing) @@ -262,7 +262,7 @@ private void EnlistDistributedTransactionHelper(System.EnterpriseServices.ITrans GC.KeepAlive(this); } - /// + /// override public void EnlistTransaction(SysTx.Transaction transaction) { SqlConnection.ExecutePermission.Demand(); @@ -312,19 +312,19 @@ internal DbMetaDataFactory GetMetaDataFactoryInternal(DbConnectionInternal inter return GetMetaDataFactory(internalConnection); } - /// + /// override public DataTable GetSchema() { return this.GetSchema(DbMetaDataCollectionNames.MetaDataCollections, null); } - /// + /// override public DataTable GetSchema(string collectionName) { return this.GetSchema(collectionName, null); } - /// + /// override public DataTable GetSchema(string collectionName, string[] restrictionValues) { // NOTE: This is virtual because not all providers may choose to support diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlDataReader.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlDataReader.cs index 75f17d565f..4063f78fd7 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlDataReader.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlDataReader.cs @@ -24,9 +24,10 @@ namespace Microsoft.Data.SqlClient { - /// + /// public class SqlDataReader : DbDataReader, IDataReader { + private enum ALTROWSTATUS { Null = 0, // default and after Done @@ -143,7 +144,7 @@ internal SqlCommand Command } } - /// + /// protected SqlConnection Connection { get @@ -152,10 +153,10 @@ protected SqlConnection Connection } } - /// + /// public SensitivityClassification SensitivityClassification { get; internal set; } - /// + /// override public int Depth { get @@ -169,7 +170,7 @@ override public int Depth } } - /// + /// // fields/attributes collection override public int FieldCount { @@ -193,7 +194,7 @@ override public int FieldCount } } - /// + /// override public bool HasRows { get @@ -211,7 +212,7 @@ override public bool HasRows } } - /// + /// override public bool IsClosed { get @@ -404,7 +405,7 @@ internal virtual SmiExtendedMetaData[] GetInternalSmiMetaData() return metaDataReturn; } - /// + /// override public int RecordsAffected { get @@ -444,7 +445,7 @@ internal MultiPartTableName[] TableNames _tableNames = value; } } - /// + /// override public int VisibleFieldCount { get @@ -462,7 +463,7 @@ override public int VisibleFieldCount } } - /// + /// // this operator override public object this[int i] { @@ -472,7 +473,7 @@ override public object this[int i] } } - /// + /// override public object this[string name] { get @@ -610,7 +611,7 @@ internal DataTable BuildSchemaTable() schemaRow[NonVersionedProviderType] = (int)(col.cipherMD != null ? col.baseTI.type : col.type); // SqlDbType enum value - does not change with TypeSystem. schemaRow[DataTypeName] = GetDataTypeNameInternal(col); - if (_typeSystem <= SqlConnectionString.TypeSystem.SQLServer2005 && col.Is2008DateTimeType) + if (_typeSystem <= SqlConnectionString.TypeSystem.SQLServer2005 && col.IsNewKatmaiDateTimeType) { schemaRow[ProviderType] = SqlDbType.NVarChar; switch (col.type) @@ -653,12 +654,12 @@ internal DataTable BuildSchemaTable() if (col.type == SqlDbType.Udt) { // Additional metadata for UDTs. - Debug.Assert(Connection.Is2005OrNewer, "Invalid Column type received from the server"); + Debug.Assert(Connection.IsYukonOrNewer, "Invalid Column type received from the server"); schemaRow[UdtAssemblyQualifiedName] = col.udt?.AssemblyQualifiedName; } else if (col.type == SqlDbType.Xml) { // Additional metadata for Xml. - Debug.Assert(Connection.Is2005OrNewer, "Invalid DataType (Xml) for the column"); + Debug.Assert(Connection.IsYukonOrNewer, "Invalid DataType (Xml) for the column"); schemaRow[XmlSchemaCollectionDatabase] = col.xmlSchemaCollection?.Database; schemaRow[XmlSchemaCollectionOwningSchema] = col.xmlSchemaCollection?.OwningSchema; schemaRow[XmlSchemaCollectionName] = col.xmlSchemaCollection?.Name; @@ -693,7 +694,7 @@ internal DataTable BuildSchemaTable() schemaRow[Precision] = col.metaType.Precision; } - if (_typeSystem <= SqlConnectionString.TypeSystem.SQLServer2005 && col.Is2008DateTimeType) + if (_typeSystem <= SqlConnectionString.TypeSystem.SQLServer2005 && col.IsNewKatmaiDateTimeType) { schemaRow[Scale] = MetaType.MetaNVarChar.Scale; } @@ -950,7 +951,7 @@ protected override void Dispose(bool disposing) } } - /// + /// override public void Close() { SqlStatistics statistics = null; @@ -1381,7 +1382,7 @@ private bool TryConsumeMetaData() return true; } - /// + /// override public string GetDataTypeName(int i) { SqlStatistics statistics = null; @@ -1402,7 +1403,7 @@ private string GetDataTypeNameInternal(_SqlMetaData metaData) { string dataTypeName = null; - if (_typeSystem <= SqlConnectionString.TypeSystem.SQLServer2005 && metaData.Is2008DateTimeType) + if (_typeSystem <= SqlConnectionString.TypeSystem.SQLServer2005 && metaData.IsNewKatmaiDateTimeType) { dataTypeName = MetaType.MetaNVarChar.TypeName; } @@ -1424,7 +1425,7 @@ private string GetDataTypeNameInternal(_SqlMetaData metaData) if (metaData.type == SqlDbType.Udt) { - Debug.Assert(Connection.Is2005OrNewer, "Invalid Column type received from the server"); + Debug.Assert(Connection.IsYukonOrNewer, "Invalid Column type received from the server"); dataTypeName = metaData.udt?.DatabaseName + "." + metaData.udt?.SchemaName + "." + metaData.udt?.TypeName; } else @@ -1458,13 +1459,13 @@ virtual internal SqlBuffer.StorageType GetVariantInternalStorageType(int i) return _data[i].VariantInternalStorageType; } - /// + /// override public IEnumerator GetEnumerator() { return new DbEnumerator(this, IsCommandBehavior(CommandBehavior.CloseConnection)); } - /// + /// override public Type GetFieldType(int i) { SqlStatistics statistics = null; @@ -1485,9 +1486,9 @@ private Type GetFieldTypeInternal(_SqlMetaData metaData) { Type fieldType = null; - if (_typeSystem <= SqlConnectionString.TypeSystem.SQLServer2005 && metaData.Is2008DateTimeType) + if (_typeSystem <= SqlConnectionString.TypeSystem.SQLServer2005 && metaData.IsNewKatmaiDateTimeType) { - // Return 2008 types as string + // Return katmai types as string fieldType = MetaType.MetaNVarChar.ClassType; } else if (_typeSystem <= SqlConnectionString.TypeSystem.SQLServer2005 && metaData.IsLargeUdt) @@ -1508,7 +1509,7 @@ private Type GetFieldTypeInternal(_SqlMetaData metaData) if (metaData.type == SqlDbType.Udt) { - Debug.Assert(Connection.Is2005OrNewer, "Invalid Column type received from the server"); + Debug.Assert(Connection.IsYukonOrNewer, "Invalid Column type received from the server"); Connection.CheckGetExtendedUDTInfo(metaData, false); fieldType = metaData.udt?.Type; } @@ -1567,7 +1568,7 @@ virtual internal int GetLocaleId(int i) return lcid; } - /// + /// override public string GetName(int i) { CheckMetaDataIsReady(columnIndex: i); @@ -1576,7 +1577,7 @@ override public string GetName(int i) return _metaData[i].column; } - /// + /// override public Type GetProviderSpecificFieldType(int i) { SqlStatistics statistics = null; @@ -1597,7 +1598,7 @@ private Type GetProviderSpecificFieldTypeInternal(_SqlMetaData metaData) { Type providerSpecificFieldType = null; - if (_typeSystem <= SqlConnectionString.TypeSystem.SQLServer2005 && metaData.Is2008DateTimeType) + if (_typeSystem <= SqlConnectionString.TypeSystem.SQLServer2005 && metaData.IsNewKatmaiDateTimeType) { providerSpecificFieldType = MetaType.MetaNVarChar.SqlType; } @@ -1619,7 +1620,7 @@ private Type GetProviderSpecificFieldTypeInternal(_SqlMetaData metaData) if (metaData.type == SqlDbType.Udt) { - Debug.Assert(Connection.Is2005OrNewer, "Invalid Column type received from the server"); + Debug.Assert(Connection.IsYukonOrNewer, "Invalid Column type received from the server"); Connection.CheckGetExtendedUDTInfo(metaData, false); providerSpecificFieldType = metaData.udt?.Type; } @@ -1648,7 +1649,7 @@ private Type GetProviderSpecificFieldTypeInternal(_SqlMetaData metaData) return providerSpecificFieldType; } - /// + /// // named field access override public int GetOrdinal(string name) { @@ -1669,19 +1670,19 @@ override public int GetOrdinal(string name) } } - /// + /// override public object GetProviderSpecificValue(int i) { return GetSqlValue(i); } - /// + /// override public int GetProviderSpecificValues(object[] values) { return GetSqlValues(values); } - /// + /// override public DataTable GetSchemaTable() { SqlStatistics statistics = null; @@ -1707,14 +1708,14 @@ override public DataTable GetSchemaTable() } } - /// + /// override public bool GetBoolean(int i) { ReadColumn(i); return _data[i].Boolean; } - /// + /// virtual public XmlReader GetXmlReader(int i) { // NOTE: sql_variant can not contain a XML data type: http://msdn.microsoft.com/en-us/library/ms173829.aspx @@ -1754,7 +1755,7 @@ virtual public XmlReader GetXmlReader(int i) } } - /// + /// override public Stream GetStream(int i) { CheckDataIsReady(columnIndex: i, methodName: "GetStream"); @@ -1802,14 +1803,14 @@ override public Stream GetStream(int i) } } - /// + /// override public byte GetByte(int i) { ReadColumn(i); return _data[i].Byte; } - /// + /// override public long GetBytes(int i, long dataIndex, byte[] buffer, int bufferIndex, int length) { SqlStatistics statistics = null; @@ -2242,7 +2243,7 @@ internal bool TryGetBytesInternalSequential(int i, byte[] buffer, int index, int } } - /// + /// override public TextReader GetTextReader(int i) { CheckDataIsReady(columnIndex: i, methodName: "GetTextReader"); @@ -2312,14 +2313,14 @@ override public TextReader GetTextReader(int i) } } - /// + /// [EditorBrowsableAttribute(EditorBrowsableState.Never)] // MDAC 69508 override public char GetChar(int i) { throw ADP.NotSupported(); } - /// + /// override public long GetChars(int i, long dataIndex, char[] buffer, int bufferIndex, int length) { SqlStatistics statistics = null; @@ -2661,21 +2662,21 @@ internal long GetStreamingXmlChars(int i, long dataIndex, char[] buffer, int buf return cnt; } - /// + /// [EditorBrowsableAttribute(EditorBrowsableState.Never)] // MDAC 69508 IDataReader IDataRecord.GetData(int i) { throw ADP.NotSupported(); } - /// + /// override public DateTime GetDateTime(int i) { ReadColumn(i); DateTime dt = _data[i].DateTime; // This accessor can be called for regular DateTime column. In this case we should not throw - if (_typeSystem <= SqlConnectionString.TypeSystem.SQLServer2005 && _metaData[i].Is2008DateTimeType) + if (_typeSystem <= SqlConnectionString.TypeSystem.SQLServer2005 && _metaData[i].IsNewKatmaiDateTimeType) { // TypeSystem.SQLServer2005 or less @@ -2690,77 +2691,77 @@ override public DateTime GetDateTime(int i) return dt; } - /// + /// override public Decimal GetDecimal(int i) { ReadColumn(i); return _data[i].Decimal; } - /// + /// override public double GetDouble(int i) { ReadColumn(i); return _data[i].Double; } - /// + /// override public float GetFloat(int i) { ReadColumn(i); return _data[i].Single; } - /// + /// override public Guid GetGuid(int i) { ReadColumn(i); - return _data[i].Guid; + return _data[i].SqlGuid.Value; } - /// + /// override public Int16 GetInt16(int i) { ReadColumn(i); return _data[i].Int16; } - /// + /// override public Int32 GetInt32(int i) { ReadColumn(i); return _data[i].Int32; } - /// + /// override public Int64 GetInt64(int i) { ReadColumn(i); return _data[i].Int64; } - /// + /// virtual public SqlBoolean GetSqlBoolean(int i) { ReadColumn(i); return _data[i].SqlBoolean; } - /// + /// virtual public SqlBinary GetSqlBinary(int i) { ReadColumn(i, setTimeout: true, allowPartiallyReadColumn: true); return _data[i].SqlBinary; } - /// + /// virtual public SqlByte GetSqlByte(int i) { ReadColumn(i); return _data[i].SqlByte; } - /// + /// virtual public SqlBytes GetSqlBytes(int i) { ReadColumn(i); @@ -2768,15 +2769,15 @@ virtual public SqlBytes GetSqlBytes(int i) return new SqlBytes(data); } - /// + /// virtual public SqlChars GetSqlChars(int i) { ReadColumn(i); SqlString data; - // Convert 2008 types to string - if (_typeSystem <= SqlConnectionString.TypeSystem.SQLServer2005 && _metaData[i].Is2008DateTimeType) + // Convert Katmai types to string + if (_typeSystem <= SqlConnectionString.TypeSystem.SQLServer2005 && _metaData[i].IsNewKatmaiDateTimeType) { - data = _data[i].Sql2008DateTimeSqlString; + data = _data[i].KatmaiDateTimeSqlString; } else { @@ -2785,84 +2786,84 @@ virtual public SqlChars GetSqlChars(int i) return new SqlChars(data); } - /// + /// virtual public SqlDateTime GetSqlDateTime(int i) { ReadColumn(i); return _data[i].SqlDateTime; } - /// + /// virtual public SqlDecimal GetSqlDecimal(int i) { ReadColumn(i); return _data[i].SqlDecimal; } - /// + /// virtual public SqlGuid GetSqlGuid(int i) { ReadColumn(i); return _data[i].SqlGuid; } - /// + /// virtual public SqlDouble GetSqlDouble(int i) { ReadColumn(i); return _data[i].SqlDouble; } - /// + /// virtual public SqlInt16 GetSqlInt16(int i) { ReadColumn(i); return _data[i].SqlInt16; } - /// + /// virtual public SqlInt32 GetSqlInt32(int i) { ReadColumn(i); return _data[i].SqlInt32; } - /// + /// virtual public SqlInt64 GetSqlInt64(int i) { ReadColumn(i); return _data[i].SqlInt64; } - /// + /// virtual public SqlMoney GetSqlMoney(int i) { ReadColumn(i); return _data[i].SqlMoney; } - /// + /// virtual public SqlSingle GetSqlSingle(int i) { ReadColumn(i); return _data[i].SqlSingle; } - /// + /// // UNDONE: need non-unicode SqlString support virtual public SqlString GetSqlString(int i) { ReadColumn(i); - if (_typeSystem <= SqlConnectionString.TypeSystem.SQLServer2005 && _metaData[i].Is2008DateTimeType) + if (_typeSystem <= SqlConnectionString.TypeSystem.SQLServer2005 && _metaData[i].IsNewKatmaiDateTimeType) { - return _data[i].Sql2008DateTimeSqlString; + return _data[i].KatmaiDateTimeSqlString; } return _data[i].SqlString; } - /// + /// virtual public SqlXml GetSqlXml(int i) { ReadColumn(i); @@ -2893,7 +2894,7 @@ virtual public SqlXml GetSqlXml(int i) return sx; } - /// + /// virtual public object GetSqlValue(int i) { SqlStatistics statistics = null; @@ -2933,10 +2934,10 @@ private object GetSqlValueFromSqlBufferInternal(SqlBuffer data, _SqlMetaData met // Due to a bug in TdsParser.GetNullSqlValue, Timestamps' IsNull is not correctly set - so we need to bypass the following check Debug.Assert(!data.IsEmpty || data.IsNull || metaData.type == SqlDbType.Timestamp, "Data has been read, but the buffer is empty"); - // Convert 2008 types to string - if (_typeSystem <= SqlConnectionString.TypeSystem.SQLServer2005 && metaData.Is2008DateTimeType) + // Convert Katmai types to string + if (_typeSystem <= SqlConnectionString.TypeSystem.SQLServer2005 && metaData.IsNewKatmaiDateTimeType) { - return data.Sql2008DateTimeSqlString; + return data.KatmaiDateTimeSqlString; } else if (_typeSystem <= SqlConnectionString.TypeSystem.SQLServer2005 && metaData.IsLargeUdt) { @@ -2979,7 +2980,7 @@ private object GetSqlValueFromSqlBufferInternal(SqlBuffer data, _SqlMetaData met } } - /// + /// virtual public int GetSqlValues(object[] values) { SqlStatistics statistics = null; @@ -3008,21 +3009,21 @@ virtual public int GetSqlValues(object[] values) } } - /// + /// override public string GetString(int i) { ReadColumn(i); - // Convert 2008 value to string if type system knob is 2005 or earlier - if (_typeSystem <= SqlConnectionString.TypeSystem.SQLServer2005 && _metaData[i].Is2008DateTimeType) + // Convert katmai value to string if type system knob is 2005 or earlier + if (_typeSystem <= SqlConnectionString.TypeSystem.SQLServer2005 && _metaData[i].IsNewKatmaiDateTimeType) { - return _data[i].Sql2008DateTimeString; + return _data[i].KatmaiDateTimeString; } return _data[i].String; } - /// + /// override public T GetFieldValue(int i) { SqlStatistics statistics = null; @@ -3039,7 +3040,7 @@ override public T GetFieldValue(int i) } } - /// + /// override public object GetValue(int i) { SqlStatistics statistics = null; @@ -3056,7 +3057,7 @@ override public object GetValue(int i) } } - /// + /// virtual public TimeSpan GetTimeSpan(int i) { ReadColumn(i); @@ -3078,7 +3079,7 @@ virtual public TimeSpan GetTimeSpan(int i) return t; } - /// + /// virtual public DateTimeOffset GetDateTimeOffset(int i) { ReadColumn(i); @@ -3123,7 +3124,7 @@ private object GetValueFromSqlBufferInternal(SqlBuffer data, _SqlMetaData metaDa // Due to a bug in TdsParser.GetNullSqlValue, Timestamps' IsNull is not correctly set - so we need to bypass the following check Debug.Assert(!data.IsEmpty || data.IsNull || metaData.type == SqlDbType.Timestamp, "Data has been read, but the buffer is empty"); - if (_typeSystem <= SqlConnectionString.TypeSystem.SQLServer2005 && metaData.Is2008DateTimeType) + if (_typeSystem <= SqlConnectionString.TypeSystem.SQLServer2005 && metaData.IsNewKatmaiDateTimeType) { if (data.IsNull) { @@ -3131,7 +3132,7 @@ private object GetValueFromSqlBufferInternal(SqlBuffer data, _SqlMetaData metaDa } else { - return data.Sql2008DateTimeString; + return data.KatmaiDateTimeString; } } else if (_typeSystem <= SqlConnectionString.TypeSystem.SQLServer2005 && metaData.IsLargeUdt) @@ -3186,56 +3187,8 @@ private T GetFieldValueInternal(int i, bool isAsync) } private T GetFieldValueFromSqlBufferInternal(SqlBuffer data, _SqlMetaData metaData, bool isAsync) - { - // this block of type specific shortcuts uses RyuJIT jit behaviors to achieve fast implementations of the primitive types - // RyuJIT will be able to determine at compilation time that the typeof(T)==typeof() options are constant - // and be able to remove all implementations which cannot be reached. this will eliminate non-specialized code for - Type dataType = data.GetTypeFromStorageType(false); - if (typeof(T) == typeof(int) && dataType == typeof(int)) - { - return data.Int32As(); - } - else if (typeof(T) == typeof(byte) && dataType == typeof(byte)) - { - return data.ByteAs(); - } - else if (typeof(T) == typeof(short) && dataType == typeof(short)) - { - return data.Int16As(); - } - else if (typeof(T) == typeof(long) && dataType == typeof(long)) - { - return data.Int64As(); - } - else if (typeof(T) == typeof(bool) && dataType == typeof(bool)) - { - return data.BooleanAs(); - } - else if (typeof(T) == typeof(double) && dataType == typeof(double)) - { - return data.DoubleAs(); - } - else if (typeof(T) == typeof(float) && dataType == typeof(float)) - { - return data.SingleAs(); - } - else if (typeof(T) == typeof(Guid) && dataType == typeof(Guid)) - { - return (T)(object)data.Guid; - } - else if (typeof(T) == typeof(decimal) && dataType == typeof(decimal)) - { - return (T)(object)data.Decimal; - } - else if (typeof(T) == typeof(DateTimeOffset) && dataType == typeof(DateTimeOffset) && _typeSystem > SqlConnectionString.TypeSystem.SQLServer2005 && metaData.Is2008DateTimeType) - { - return (T)(object)data.DateTimeOffset; - } - else if (typeof(T) == typeof(DateTime) && dataType == typeof(DateTime) && _typeSystem > SqlConnectionString.TypeSystem.SQLServer2005 && metaData.Is2008DateTimeType) - { - return (T)(object)data.DateTime; - } - else if (typeof(T) == typeof(XmlReader)) + { + if (typeof(T) == typeof(XmlReader)) { // XmlReader only allowed on XML types if (metaData.metaType.SqlDbType != SqlDbType.Xml) @@ -3336,52 +3289,48 @@ private T GetFieldValueFromSqlBufferInternal(SqlBuffer data, _SqlMetaData met return (T)(object)new MemoryStream(value, writable: false); } } - else + else if (typeof(INullable).IsAssignableFrom(typeof(T))) { - if (typeof(INullable).IsAssignableFrom(typeof(T))) + // If its a SQL Type or Nullable UDT + object rawValue = GetSqlValueFromSqlBufferInternal(data, metaData); + + if (typeof(T) == typeof(SqlString)) { - // If its a SQL Type or Nullable UDT - object rawValue = GetSqlValueFromSqlBufferInternal(data, metaData); - if (typeof(T) == typeof(SqlString)) + // Special case: User wants SqlString, but we have a SqlXml + // SqlXml can not be typecast into a SqlString, but we need to support SqlString on XML Types - so do a manual conversion + SqlXml xmlValue = rawValue as SqlXml; + if (xmlValue != null) { - // Special case: User wants SqlString, but we have a SqlXml - // SqlXml can not be typecast into a SqlString, but we need to support SqlString on XML Types - so do a manual conversion - SqlXml xmlValue = rawValue as SqlXml; - if (xmlValue != null) + if (xmlValue.IsNull) { - if (xmlValue.IsNull) - { - rawValue = SqlString.Null; - } - else - { - rawValue = new SqlString(xmlValue.Value); - } + rawValue = SqlString.Null; + } + else + { + rawValue = new SqlString(xmlValue.Value); } } - return (T)rawValue; } - else - { - // the requested type is likely to be one that isn't supported so try the cast and - // unless there is a null value conversion then feedback the cast exception with - // type named to the user so they know what went wrong. Supported types are listed - // in the documentation - try - { - return (T)GetValueFromSqlBufferInternal(data, metaData); - } - catch (InvalidCastException) when (data.IsNull) - { - // If the value was actually null, then we should throw a SqlNullValue instead - throw SQL.SqlNullValue(); - } + return (T)rawValue; + } + else + { + // Otherwise Its a CLR or non-Nullable UDT + try + { + return (T)GetValueFromSqlBufferInternal(data, metaData); + } + catch (InvalidCastException) when (data.IsNull) + { + // If the value was actually null, then we should throw a SqlNullValue instead + throw SQL.SqlNullValue(); } + } } - /// + /// override public int GetValues(object[] values) { SqlStatistics statistics = null; @@ -3523,7 +3472,7 @@ private bool TryHasMoreResults(out bool moreResults) return true; // VSTFDEVDIV 926281: DONEINPROC case is missing here; we have decided to reject this bug as it would result in breaking change - // from VS2008 RTM/SP1 and Dev10 RTM. See the bug for more details. + // from Orcas RTM/SP1 and Dev10 RTM. See the bug for more details. // case TdsEnums.DONEINPROC: case TdsEnums.SQLDONE: Debug.Assert(_altRowStatus == ALTROWSTATUS.Done || _altRowStatus == ALTROWSTATUS.Null, "invalid AltRowStatus"); @@ -3668,7 +3617,7 @@ private bool IsRowToken(byte token) return TdsEnums.SQLROW == token || TdsEnums.SQLNBCROW == token; } - /// + /// override public bool IsDBNull(int i) { if ((IsCommandBehavior(CommandBehavior.SequentialAccess)) && ((_sharedState._nextColumnHeaderToRead > i + 1) || (_lastColumnWithDataChunkRead > i))) @@ -3693,13 +3642,13 @@ override public bool IsDBNull(int i) return _data[i].IsNull; } - /// + /// protected internal bool IsCommandBehavior(CommandBehavior condition) { return (condition == (condition & _commandBehavior)); } - /// + /// override public bool NextResult() { if (_currentTask != null) @@ -3905,7 +3854,7 @@ private bool TryNextResult(out bool more) } } - /// + /// // user must call Read() to position on the first row override public bool Read() { @@ -4979,7 +4928,7 @@ private void AssertReaderState(bool requireData, bool permitAsync, int? columnIn } } - /// + /// public override Task NextResultAsync(CancellationToken cancellationToken) { using (TryEventScope.Create(" {0}", ObjectID)) @@ -5316,7 +5265,7 @@ out bytesRead return null; } - /// + /// public override Task ReadAsync(CancellationToken cancellationToken) { using (TryEventScope.Create(" {0}", ObjectID)) @@ -5492,7 +5441,7 @@ private void SetCachedReadAsyncCallContext(ReadAsyncCallContext instance) Interlocked.CompareExchange(ref _cachedReadAsyncContext, instance, null); } - /// + /// override public Task IsDBNullAsync(int i, CancellationToken cancellationToken) { @@ -5630,7 +5579,7 @@ private void SetCachedIDBNullAsyncCallContext(IsDBNullAsyncCallContext instance) Interlocked.CompareExchange(ref _cachedIsDBNullContext, instance, null); } - /// + /// override public Task GetFieldValueAsync(int i, CancellationToken cancellationToken) { try @@ -5796,7 +5745,7 @@ internal void CompletePendingReadWithFailure(int errorCode, bool resetForcePendi #endif - private class Snapshot + class Snapshot { public bool _dataReady; public bool _haltRead; diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlDataReaderSmi.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlDataReaderSmi.cs index 8926b74dd8..7c8d3fe7d9 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlDataReaderSmi.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlDataReaderSmi.cs @@ -120,7 +120,7 @@ public override Object GetValue(int ordinal) { EnsureCanGetCol("GetValue", ordinal); SmiQueryMetaData metaData = _currentMetaData[ordinal]; - if (_currentConnection.Is2008OrNewer) + if (_currentConnection.IsKatmaiOrNewer) { return ValueUtilsSmi.GetValue200(_readerEventSink, (SmiTypedGetterSetter)_currentColumnValuesV3, ordinal, metaData, _currentConnection.InternalContext); } @@ -138,7 +138,7 @@ public override T GetFieldValue(int ordinal) if (typeof(INullable).IsAssignableFrom(typeof(T))) { // If its a SQL Type or Nullable UDT - if (_currentConnection.Is2008OrNewer) + if (_currentConnection.IsKatmaiOrNewer) { return (T)ValueUtilsSmi.GetSqlValue200(_readerEventSink, (SmiTypedGetterSetter)_currentColumnValuesV3, ordinal, metaData, _currentConnection.InternalContext); } @@ -150,7 +150,7 @@ public override T GetFieldValue(int ordinal) else { // Otherwise Its a CLR or non-Nullable UDT - if (_currentConnection.Is2008OrNewer) + if (_currentConnection.IsKatmaiOrNewer) { return (T)ValueUtilsSmi.GetValue200(_readerEventSink, (SmiTypedGetterSetter)_currentColumnValuesV3, ordinal, metaData, _currentConnection.InternalContext); } @@ -923,13 +923,13 @@ public override SqlXml GetSqlXml(int ordinal) public override TimeSpan GetTimeSpan(int ordinal) { EnsureCanGetCol("GetTimeSpan", ordinal); - return ValueUtilsSmi.GetTimeSpan(_readerEventSink, _currentColumnValuesV3, ordinal, _currentMetaData[ordinal], _currentConnection.Is2008OrNewer); + return ValueUtilsSmi.GetTimeSpan(_readerEventSink, _currentColumnValuesV3, ordinal, _currentMetaData[ordinal], _currentConnection.IsKatmaiOrNewer); } public override DateTimeOffset GetDateTimeOffset(int ordinal) { EnsureCanGetCol("GetDateTimeOffset", ordinal); - return ValueUtilsSmi.GetDateTimeOffset(_readerEventSink, _currentColumnValuesV3, ordinal, _currentMetaData[ordinal], _currentConnection.Is2008OrNewer); + return ValueUtilsSmi.GetDateTimeOffset(_readerEventSink, _currentColumnValuesV3, ordinal, _currentMetaData[ordinal], _currentConnection.IsKatmaiOrNewer); } public override object GetSqlValue(int ordinal) @@ -937,7 +937,7 @@ public override object GetSqlValue(int ordinal) EnsureCanGetCol("GetSqlValue", ordinal); SmiMetaData metaData = _currentMetaData[ordinal]; - if (_currentConnection.Is2008OrNewer) + if (_currentConnection.IsKatmaiOrNewer) { return ValueUtilsSmi.GetSqlValue200(_readerEventSink, (SmiTypedGetterSetter)_currentColumnValuesV3, ordinal, metaData, _currentConnection.InternalContext); } diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlError.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlError.cs new file mode 100644 index 0000000000..1a50bbe2d5 --- /dev/null +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlError.cs @@ -0,0 +1,113 @@ +// 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; + +namespace Microsoft.Data.SqlClient +{ + /// + [Serializable] + public sealed class SqlError + { + // bug fix - MDAC 48965 - missing source of exception + private readonly string _source = TdsEnums.SQL_PROVIDER_NAME; + private readonly int _number; + private readonly byte _state; + private readonly byte _errorClass; + [System.Runtime.Serialization.OptionalField(VersionAdded = 2)] + private readonly string _server; + private readonly string _message; + private readonly string _procedure; + private readonly int _lineNumber; + [System.Runtime.Serialization.OptionalField(VersionAdded = 4)] + private readonly int _win32ErrorCode; + + internal SqlError(int infoNumber, byte errorState, byte errorClass, string server, string errorMessage, string procedure, int lineNumber, uint win32ErrorCode) + : this(infoNumber, errorState, errorClass, server, errorMessage, procedure, lineNumber) + { + _win32ErrorCode = (int)win32ErrorCode; + } + + internal SqlError(int infoNumber, byte errorState, byte errorClass, string server, string errorMessage, string procedure, int lineNumber) + { + _number = infoNumber; + _state = errorState; + _errorClass = errorClass; + _server = server; + _message = errorMessage; + _procedure = procedure; + _lineNumber = lineNumber; + if (errorClass != 0) + { + SqlClientEventSource.Log.TryTraceEvent(" infoNumber={0}, errorState={1}, errorClass={2}, errorMessage='{3}', procedure='{4}', lineNumber={5}", infoNumber, (int)errorState, (int)errorClass, errorMessage, procedure, (int)lineNumber); + } + _win32ErrorCode = 0; + } + + /// + // bug fix - MDAC #49280 - SqlError does not implement ToString(); + // I did not include an exception stack because the correct exception stack is only available + // on SqlException, and to obtain that the SqlError would have to have backpointers all the + // way back to SqlException. If the user needs a call stack, they can obtain it on SqlException. + public override string ToString() + { + //return GetType().ToString() + ": " + message; + return typeof(SqlError).ToString() + ": " + _message; // since this is sealed so we can change GetType to typeof + } + + /// + // bug fix - MDAC #48965 - missing source of exception + public string Source + { + get { return _source; } + } + + /// + public int Number + { + get { return _number; } + } + + /// + public byte State + { + get { return _state; } + } + + /// + public byte Class + { + get { return _errorClass; } + } + + /// + public string Server + { + get { return _server; } + } + + /// + public string Message + { + get { return _message; } + } + + /// + public string Procedure + { + get { return _procedure; } + } + + /// + public int LineNumber + { + get { return _lineNumber; } + } + + internal int Win32ErrorCode + { + get { return _win32ErrorCode; } + } + } +} diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlInternalConnection.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlInternalConnection.cs index 71586f1adf..be0456685e 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlInternalConnection.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlInternalConnection.cs @@ -144,17 +144,17 @@ abstract internal bool IsLockedForBulkCopy get; } - abstract internal bool Is2000 + abstract internal bool IsShiloh { get; } - abstract internal bool Is2005OrNewer + abstract internal bool IsYukonOrNewer { get; } - abstract internal bool Is2008OrNewer + abstract internal bool IsKatmaiOrNewer { get; } @@ -438,11 +438,11 @@ private void EnlistNonNull(SysTx.Transaction tx) SqlClientEventSource.Log.TryAdvancedTraceEvent(" {0}, transaction {1}.", ObjectID, tx.GetHashCode()); bool hasDelegatedTransaction = false; - if (Is2005OrNewer) + if (IsYukonOrNewer) { SqlClientEventSource.Log.TryAdvancedTraceEvent(" {0}, attempting to delegate", ObjectID); - // Promotable transactions are only supported on 2005 + // Promotable transactions are only supported on Yukon // servers or newer. SqlDelegatedTransaction delegatedTransaction = new SqlDelegatedTransaction(this, tx); @@ -575,20 +575,20 @@ private void EnlistNonNull(SysTx.Transaction tx) EnlistedTransaction = tx; // Tell the base class about our enlistment - // If we're on a 2005 or newer server, and we we delegate the + // If we're on a Yukon or newer server, and we we delegate the // transaction successfully, we will have done a begin transaction, // which produces a transaction id that we should execute all requests // on. The TdsParser or SmiEventSink will store this information as // the current transaction. // - // Likewise, propagating a transaction to a 2005 or newer server will + // Likewise, propagating a transaction to a Yukon or newer server will // produce a transaction id that The TdsParser or SmiEventSink will // store as the current transaction. // - // In either case, when we're working with a 2005 or newer server + // In either case, when we're working with a Yukon or newer server // we better have a current transaction by now. - Debug.Assert(!Is2005OrNewer || null != CurrentTransaction, "delegated/enlisted transaction with null current transaction?"); + Debug.Assert(!IsYukonOrNewer || null != CurrentTransaction, "delegated/enlisted transaction with null current transaction?"); } internal void EnlistNull() @@ -617,10 +617,10 @@ internal void EnlistNull() // which causes the TdsParser or SmiEventSink should to clear the // current transaction. // - // In either case, when we're working with a 2005 or newer server + // In either case, when we're working with a Yukon or newer server // we better not have a current transaction at this point. - Debug.Assert(!Is2005OrNewer || null == CurrentTransaction, "unenlisted transaction with non-null current transaction?"); // verify it! + Debug.Assert(!IsYukonOrNewer || null == CurrentTransaction, "unenlisted transaction with non-null current transaction?"); // verify it! } override public void EnlistTransaction(SysTx.Transaction transaction) @@ -647,7 +647,7 @@ override public void EnlistTransaction(SysTx.Transaction transaction) // If a connection is already enlisted in a DTC transaction and you // try to enlist in another one, in 7.0 the existing DTC transaction // would roll back and then the connection would enlist in the new - // one. In SQL 2000 & 2005, when you enlist in a DTC transaction + // one. In SQL 2000 & Yukon, when you enlist in a DTC transaction // while the connection is already enlisted in a DTC transaction, // the connection simply switches enlistments. Regardless, simply // enlist in the user specified distributed transaction. This diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlInternalConnectionSmi.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlInternalConnectionSmi.cs index aa1a766861..e866b0c7ff 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlInternalConnectionSmi.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlInternalConnectionSmi.cs @@ -162,27 +162,27 @@ override internal bool IsLockedForBulkCopy } } - override internal bool Is2000 + override internal bool IsShiloh { get { - return false; // Can't be direct connecting to 2000. + return false; // Can't be direct connecting to Shiloh. } } - override internal bool Is2005OrNewer + override internal bool IsYukonOrNewer { get { - return true; // Must be direct connecting to 2005 or newer. + return true; // Must be direct connecting to Yukon or newer. } } - override internal bool Is2008OrNewer + override internal bool IsKatmaiOrNewer { get { - return SmiContextFactory.Instance.NegotiatedSmiVersion >= SmiContextFactory.Sql2008Version; + return SmiContextFactory.Instance.NegotiatedSmiVersion >= SmiContextFactory.KatmaiVersion; } } diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.cs index 616c44a3f4..623ce80d93 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.cs @@ -731,11 +731,11 @@ override protected internal bool IsNonPoolableTransactionRoot { get { - return IsTransactionRoot && (!Is2008OrNewer || null == Pool); + return IsTransactionRoot && (!IsKatmaiOrNewer || null == Pool); } } - override internal bool Is2000 + override internal bool IsShiloh { get { @@ -743,19 +743,19 @@ override internal bool Is2000 } } - override internal bool Is2005OrNewer + override internal bool IsYukonOrNewer { get { - return _parser.Is2005OrNewer; + return _parser.IsYukonOrNewer; } } - override internal bool Is2008OrNewer + override internal bool IsKatmaiOrNewer { get { - return _parser.Is2008OrNewer; + return _parser.IsKatmaiOrNewer; } } @@ -1075,9 +1075,9 @@ private void ResetConnection() if (_fResetConnection) { - // Ensure we are either going against 2000, or we are not enlisted in a + // Ensure we are either going against shiloh, or we are not enlisted in a // distributed transaction - otherwise don't reset! - if (Is2000) + if (IsShiloh) { // Prepare the parser for the connection reset - the next time a trip // to the server is made. @@ -1085,7 +1085,7 @@ private void ResetConnection() } else if (!IsEnlistedInTransaction) { - // If not 2000, we are going against 7.0. On 7.0, we + // If not Shiloh, we are going against Sphinx. On Sphinx, we // may only reset if not enlisted in a distributed transaction. try { @@ -1168,18 +1168,18 @@ override internal void ExecuteTransaction(TransactionRequest transactionRequest, string transactionName = (null == name) ? String.Empty : name; - if (!_parser.Is2005OrNewer) + if (!_parser.IsYukonOrNewer) { - ExecuteTransactionPre2005(transactionRequest, transactionName, iso, internalTransaction); + ExecuteTransactionPreYukon(transactionRequest, transactionName, iso, internalTransaction); } else { - ExecuteTransaction2005(transactionRequest, transactionName, iso, internalTransaction, isDelegateControlRequest); + ExecuteTransactionYukon(transactionRequest, transactionName, iso, internalTransaction, isDelegateControlRequest); } } // This function will not handle idle connection resiliency, as older servers will not support it - internal void ExecuteTransactionPre2005( + internal void ExecuteTransactionPreYukon( TransactionRequest transactionRequest, string transactionName, IsolationLevel iso, @@ -1229,7 +1229,7 @@ internal void ExecuteTransactionPre2005( sqlBatch.Append(transactionName); break; case TransactionRequest.Promote: - Debug.Assert(false, "Promote called with transaction name or on pre-2005!"); + Debug.Assert(false, "Promote called with transaction name or on pre-Yukon!"); break; case TransactionRequest.Commit: sqlBatch.Append(TdsEnums.TRANS_COMMIT); @@ -1256,7 +1256,7 @@ internal void ExecuteTransactionPre2005( Debug.Assert(executeTask == null, "Shouldn't get a task when doing sync writes"); _parser.Run(RunBehavior.UntilDone, null, null, null, _parser._physicalStateObj); - // Prior to 2005, we didn't have any transaction tokens to manage, + // Prior to Yukon, we didn't have any transaction tokens to manage, // or any feedback to know when one was created, so we just presume // that successful execution of the request caused the transaction // to be created, and we set that on the parser. @@ -1268,7 +1268,7 @@ internal void ExecuteTransactionPre2005( } - internal void ExecuteTransaction2005( + internal void ExecuteTransactionYukon( TransactionRequest transactionRequest, string transactionName, IsolationLevel iso, @@ -1330,7 +1330,7 @@ internal void ExecuteTransaction2005( requestType = TdsEnums.TransactionManagerRequestType.Commit; break; case TransactionRequest.IfRollback: - // Map IfRollback to Rollback since with 2005 and beyond we should never need + // Map IfRollback to Rollback since with Yukon and beyond we should never need // the if since the server will inform us when transactions have completed // as a result of an error on the server. case TransactionRequest.Rollback: @@ -1388,7 +1388,7 @@ internal void ExecuteTransaction2005( } if (internalTransaction.OpenResultsCount != 0) { - SqlClientEventSource.Log.TryTraceEvent(" {0}, Connection is marked to be doomed when closed. Transaction ended with OpenResultsCount {1} > 0, MARSOn {2}", + SqlClientEventSource.Log.TryTraceEvent(" {0}, Connection is marked to be doomed when closed. Transaction ended with OpenResultsCount {1} > 0, MARSOn {2}", ObjectID, internalTransaction.OpenResultsCount, _parser.MARSOn); @@ -2513,7 +2513,7 @@ internal void OnEnvChange(SqlEnvChange rec) break; case TdsEnums.ENV_TRANSACTIONMANAGERADDRESS: - // For now we skip these 2005 only env change notifications + // For now we skip these Yukon only env change notifications break; case TdsEnums.ENV_SPRESETCONNECTIONACK: diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlParameter.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlParameter.cs index 503273c317..2f34580dae 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlParameter.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlParameter.cs @@ -1620,7 +1620,7 @@ internal SmiParameterMetaData GetMetadataForTypeInfo() internal SmiParameterMetaData MetaDataForSmi(out ParameterPeekAheadValue peekAhead) { peekAhead = null; - MetaType mt = ValidateTypeLengths(true /* 2005 or newer */ ); + MetaType mt = ValidateTypeLengths(true /* Yukon or newer */ ); long actualLen = GetActualSize(); long maxLen = Size; @@ -1963,7 +1963,7 @@ internal void Validate(int index, bool isCommandProc) // func will change type to that with a 4 byte length if the type has a two // byte length and a parameter length > than that expressible in 2 bytes - internal MetaType ValidateTypeLengths(bool is2005OrNewer) + internal MetaType ValidateTypeLengths(bool yukonOrNewer) { MetaType mt = InternalMetaType; // Since the server will automatically reject any @@ -1984,7 +1984,7 @@ internal MetaType ValidateTypeLengths(bool is2005OrNewer) // 'this.Size' is in charaters; // 'sizeInCharacters' is in characters; // 'TdsEnums.TYPE_SIZE_LIMIT' is in bytes; - // For Non-NCharType and for non-2005 or greater variables, size should be maintained; + // For Non-NCharType and for non-Yukon or greater variables, size should be maintained; // Reverting changes from bug VSTFDevDiv # 479739 as it caused an regression; // Modifed variable names from 'size' to 'sizeInCharacters', 'actualSize' to 'actualSizeInBytes', and // 'maxSize' to 'maxSizeInBytes' @@ -1995,14 +1995,14 @@ internal MetaType ValidateTypeLengths(bool is2005OrNewer) // Keeping these goals in mind - the following are the changes we are making long maxSizeInBytes; - if (mt.IsNCharType && is2005OrNewer) + if (mt.IsNCharType && yukonOrNewer) { maxSizeInBytes = ((sizeInCharacters * sizeof(char)) > actualSizeInBytes) ? sizeInCharacters * sizeof(char) : actualSizeInBytes; } else { // Notes: - // Elevation from (n)(var)char (4001+) to (n)text succeeds without failure only with 2005 and greater. + // Elevation from (n)(var)char (4001+) to (n)text succeeds without failure only with Yukon and greater. // it fails in sql server 2000 maxSizeInBytes = (sizeInCharacters > actualSizeInBytes) ? sizeInCharacters : actualSizeInBytes; } @@ -2014,7 +2014,7 @@ internal MetaType ValidateTypeLengths(bool is2005OrNewer) (actualSizeInBytes == -1) ) { // is size > size able to be described by 2 bytes - if (is2005OrNewer) + if (yukonOrNewer) { // Convert the parameter to its max type mt = MetaType.GetMaxMetaTypeFromMetaType(mt); diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlTransaction.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlTransaction.cs index 6b10dc40ef..e9116df172 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlTransaction.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlTransaction.cs @@ -12,7 +12,7 @@ namespace Microsoft.Data.SqlClient { - /// + /// public sealed class SqlTransaction : DbTransaction { private static int _objectTypeCount; // EventSource Counter @@ -48,7 +48,7 @@ internal SqlTransaction(SqlInternalConnection internalConnection, SqlConnection // PROPERTIES //////////////////////////////////////////////////////////////////////////////////////// - /// + /// new public SqlConnection Connection { // MDAC 66655 get @@ -64,7 +64,7 @@ internal SqlTransaction(SqlInternalConnection internalConnection, SqlConnection } } - /// + /// override protected DbConnection DbConnection { get @@ -81,7 +81,7 @@ internal SqlInternalTransaction InternalTransaction } } - /// + /// override public IsolationLevel IsolationLevel { get @@ -91,7 +91,7 @@ override public IsolationLevel IsolationLevel } } - private bool Is2005PartialZombie + private bool IsYukonPartialZombie { get { @@ -134,7 +134,7 @@ internal SqlStatistics Statistics // PUBLIC METHODS //////////////////////////////////////////////////////////////////////////////////////// - /// + /// override public void Commit() { SqlConnection.ExecutePermission.Demand(); // MDAC 81476 @@ -211,7 +211,7 @@ override public void Commit() } } - /// + /// protected override void Dispose(bool disposing) { if (disposing) @@ -231,7 +231,7 @@ protected override void Dispose(bool disposing) { #endif //DEBUG bestEffortCleanupTarget = SqlInternalConnection.GetBestEffortCleanupTarget(_connection); - if (!IsZombied && !Is2005PartialZombie) + if (!IsZombied && !IsYukonPartialZombie) { _internalTransaction.Dispose(); } @@ -263,15 +263,15 @@ protected override void Dispose(bool disposing) base.Dispose(disposing); } - /// + /// override public void Rollback() { - if (Is2005PartialZombie) + if (IsYukonPartialZombie) { // Put something in the trace in case a customer has an issue SqlClientEventSource.Log.TryAdvancedTraceEvent(" {0} partial zombie no rollback required", ObjectID); - _internalTransaction = null; // 2005 zombification + _internalTransaction = null; // yukon zombification } else { @@ -336,7 +336,7 @@ override public void Rollback() } } - /// + /// public void Rollback(string transactionName) { SqlConnection.ExecutePermission.Demand(); // MDAC 81476 @@ -399,7 +399,7 @@ public void Rollback(string transactionName) } } - /// + /// public void Save(string savePointName) { SqlConnection.ExecutePermission.Demand(); // MDAC 81476 @@ -465,20 +465,20 @@ public void Save(string savePointName) internal void Zombie() { - // SQLBUDT #402544 For 2005, we have to defer "zombification" until + // SQLBUDT #402544 For Yukon, we have to defer "zombification" until // we get past the users' next rollback, else we'll // throw an exception there that is a breaking change. // Of course, if the connection is aready closed, // then we're free to zombify... SqlInternalConnection internalConnection = (_connection.InnerConnection as SqlInternalConnection); - if (null != internalConnection && internalConnection.Is2005OrNewer && !_isFromAPI) + if (null != internalConnection && internalConnection.IsYukonOrNewer && !_isFromAPI) { - SqlClientEventSource.Log.TryAdvancedTraceEvent(" {0} 2005 deferred zombie", ObjectID); + SqlClientEventSource.Log.TryAdvancedTraceEvent(" {0} yukon deferred zombie", ObjectID); } else { - _internalTransaction = null; // pre-2005 zombification + _internalTransaction = null; // pre-yukon zombification } } @@ -493,9 +493,9 @@ private void ZombieCheck() if (IsZombied) { - if (Is2005PartialZombie) + if (IsYukonPartialZombie) { - _internalTransaction = null; // 2005 zombification + _internalTransaction = null; // yukon zombification } throw ADP.TransactionZombied(this); diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlUtil.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlUtil.cs index 6c60e9e009..3bc5591b3e 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlUtil.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlUtil.cs @@ -553,7 +553,7 @@ static internal Exception ChangePasswordConflictsWithSSPI() { return ADP.Argument(StringsHelper.GetString(Strings.SQL_ChangePasswordConflictsWithSSPI)); } - static internal Exception ChangePasswordRequires2005() + static internal Exception ChangePasswordRequiresYukon() { return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_ChangePasswordRequiresYukon)); } @@ -657,7 +657,7 @@ static internal Exception ActiveDirectoryDeviceFlowTimeout() // // SQL.DataCommand // - static internal Exception NotificationsRequire2005() + static internal Exception NotificationsRequireYukon() { return ADP.NotSupported(StringsHelper.GetString(Strings.SQL_NotificationsRequireYukon)); } diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs index 55da5fcf83..233aec019d 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs @@ -9,6 +9,7 @@ using System.Diagnostics; using System.Globalization; using System.IO; +using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Security.Cryptography.X509Certificates; @@ -32,6 +33,7 @@ sealed internal class TdsParser { private static int _objectTypeCount; // EventSource Counter private readonly SqlClientLogger _logger = new SqlClientLogger(); + private readonly string _typeName; internal readonly int _objectID = System.Threading.Interlocked.Increment(ref _objectTypeCount); @@ -183,7 +185,7 @@ internal static void Assert(string message) private EncryptionOptions _encryptionOption = _sniSupportedEncryptionOption; private SqlInternalTransaction _currentTransaction; - private SqlInternalTransaction _pendingTransaction; // pending transaction for 2005 and beyond. + private SqlInternalTransaction _pendingTransaction; // pending transaction for Yukon and beyond. // SQLHOT 483 // need to hold on to the transaction id if distributed transaction merely rolls back without defecting. private long _retainedTransactionId = SqlInternalTransaction.NullTransactionId; @@ -205,15 +207,15 @@ internal static void Assert(string message) internal TdsParserSessionPool _sessionPool = null; // initialized only when we're a MARS parser. // Version variables - private bool _is2000 = false; // set to true if we connect to a 8.0 server (SQL 2000) or later + private bool _isShiloh = false; // set to true if we connect to a 8.0 server (SQL 2000) or later - private bool _is2000SP1 = false; // set to true if speaking to 2000 SP1 or later + private bool _isShilohSP1 = false; // set to true if speaking to Shiloh SP1 or later - private bool _is2005 = false; // set to true if speaking to 2005 or later + private bool _isYukon = false; // set to true if speaking to Yukon or later - private bool _is2008 = false; + private bool _isKatmai = false; - private bool _is2012 = false; + private bool _isDenali = false; private byte[] _sniSpnBuffer = null; @@ -249,7 +251,6 @@ internal static void Assert(string message) // size of Guid (e.g. _clientConnectionId, ActivityId.Id) private const int GUID_SIZE = 16; - private byte[] _tempGuidBytes; // NOTE: You must take the internal connection's _parserLock before modifying this internal bool _asyncWrite = false; @@ -316,9 +317,10 @@ internal bool IsDataClassificationEnabled internal TdsParser(bool MARS, bool fAsynchronous) { - _fMARS = MARS; // may change during Connect to pre 2005 servers + _fMARS = MARS; // may change during Connect to pre Yukon servers _physicalStateObj = new TdsParserStateObject(this); DataClassificationVersion = TdsEnums.DATA_CLASSIFICATION_NOT_ENABLED; + _typeName = GetType().Name; } internal SqlInternalConnectionTds Connection @@ -384,19 +386,19 @@ internal EncryptionOptions EncryptionOptions } } - internal bool Is2005OrNewer + internal bool IsYukonOrNewer { get { - return _is2005; + return _isYukon; } } - internal bool Is2008OrNewer + internal bool IsKatmaiOrNewer { get { - return _is2008; + return _isKatmai; } } @@ -457,7 +459,7 @@ private bool IncludeTraceHeader { get { - return (_is2012 && SqlClientEventSource.Log.IsEnabled()); + return (_isDenali && SqlClientEventSource.Log.IsEnabled()); } } @@ -710,8 +712,8 @@ internal void Connect(ServerInfo serverInfo, status = ConsumePreLoginHandshake(authType, encrypt, trustServerCert, integratedSecurity, serverCallback, clientCallback, out marsCapable, out _connHandler._fedAuthRequired); - // Don't need to check for 7.0 failure, since we've already consumed - // one pre-login packet and know we are connecting to 2000. + // Don't need to check for Sphinx failure, since we've already consumed + // one pre-login packet and know we are connecting to Shiloh. if (status == PreLoginHandshakeStatus.InstanceFailure) { SqlClientEventSource.Log.TryTraceEvent(" Prelogin handshake unsuccessful. Login failure"); @@ -1136,7 +1138,7 @@ private PreLoginHandshakeStatus ConsumePreLoginHandshake(SqlAuthenticationMethod marsCapable = _fMARS; fedAuthRequired = false; - bool is2005OrLater = false; + bool isYukonOrLater = false; Debug.Assert(_physicalStateObj._syncOverAsync, "Should not attempt pends in a synchronous call"); bool result = _physicalStateObj.TryReadNetworkPacket(); @@ -1190,10 +1192,10 @@ private PreLoginHandshakeStatus ConsumePreLoginHandshake(SqlAuthenticationMethod int level = (payload[payloadOffset + 2] << 8) | payload[payloadOffset + 3]; - is2005OrLater = majorVersion >= 9; - if (!is2005OrLater) + isYukonOrLater = majorVersion >= 9; + if (!isYukonOrLater) { - marsCapable = false; // If pre-2005, MARS not supported. + marsCapable = false; // If pre-Yukon, MARS not supported. } break; @@ -1276,7 +1278,7 @@ private PreLoginHandshakeStatus ConsumePreLoginHandshake(SqlAuthenticationMethod bool shouldValidateServerCert = (_encryptionOption == EncryptionOptions.ON && !trustServerCert) || ((authType != SqlAuthenticationMethod.NotSpecified || _connHandler._accessTokenInBytes != null) && !trustServerCert); UInt32 info = (shouldValidateServerCert ? TdsEnums.SNI_SSL_VALIDATE_CERTIFICATE : 0) - | (is2005OrLater && (_encryptionOption & EncryptionOptions.CLIENT_CERT) == 0 ? TdsEnums.SNI_SSL_USE_SCHANNEL_CACHE : 0); + | (isYukonOrLater && (_encryptionOption & EncryptionOptions.CLIENT_CERT) == 0 ? TdsEnums.SNI_SSL_USE_SCHANNEL_CACHE : 0); if (encrypt && !integratedSecurity) { @@ -1338,16 +1340,8 @@ private PreLoginHandshakeStatus ConsumePreLoginHandshake(SqlAuthenticationMethod string warningMessage = SslProtocolsHelper.GetProtocolWarning(protocolVersion); if (!string.IsNullOrEmpty(warningMessage)) { - if (!encrypt && LocalAppContextSwitches.SuppressInsecureTLSWarning) - { - // Skip console warning - SqlClientEventSource.Log.TryTraceEvent("{3}", nameof(TdsParser), nameof(ConsumePreLoginHandshake), SqlClientLogger.LogLevel.Warning, warningMessage); - } - else - { - // This logs console warning of insecure protocol in use. - _logger.LogWarning(nameof(TdsParser), nameof(ConsumePreLoginHandshake), warningMessage); - } + // This logs console warning of insecure protocol in use. + _logger.LogWarning(_typeName, MethodBase.GetCurrentMethod().Name, warningMessage); } // Validate server certificate @@ -1873,7 +1867,7 @@ internal void CheckResetConnection(TdsParserStateObject stateObj) // Check again to see if we need to send reset. Debug.Assert(!stateObj._fResetConnectionSent, "Unexpected state for sending reset connection"); - Debug.Assert(_is2000, "TdsParser.cs: Error! _fResetConnection true when not going against 2000 or later!"); + Debug.Assert(_isShiloh, "TdsParser.cs: Error! _fResetConnection true when not going against Shiloh or later!"); if (_fPreserveTransaction) { @@ -1900,7 +1894,7 @@ internal void CheckResetConnection(TdsParserStateObject stateObj) { Debug.Assert(!stateObj._fResetConnectionSent, "Unexpected state on WritePacket ResetConnection"); - // Otherwise if 2005 and we grabbed the event, free it. Another execute grabbed the event and + // Otherwise if Yukon and we grabbed the event, free it. Another execute grabbed the event and // took care of sending the reset. stateObj._fResetEventOwned = !_resetConnectionEvent.Set(); Debug.Assert(!stateObj._fResetEventOwned, "Invalid AutoResetEvent state!"); @@ -1910,7 +1904,7 @@ internal void CheckResetConnection(TdsParserStateObject stateObj) { if (_fMARS && stateObj._fResetEventOwned) { - // If exception thrown, and we are on 2005 and own the event, release it! + // If exception thrown, and we are on Yukon and own the event, release it! stateObj._fResetConnectionSent = false; stateObj._fResetEventOwned = !_resetConnectionEvent.Set(); Debug.Assert(!stateObj._fResetEventOwned, "Invalid AutoResetEvent state!"); @@ -2182,7 +2176,7 @@ internal void WriteDouble(double v, TdsParserStateObject stateObj) internal void PrepareResetConnection(bool preserveTransaction) { - // Set flag to reset connection upon next use - only for use on 2000! + // Set flag to reset connection upon next use - only for use on shiloh! _fResetConnection = true; _fPreserveTransaction = preserveTransaction; } @@ -2994,7 +2988,7 @@ private bool TryProcessEnvChange(int tokenLength, TdsParserStateObject stateObj, case TdsEnums.ENV_CHARSET: // we copied this behavior directly from luxor - see charset envchange // section from sqlctokn.c - Debug.Assert(!_is2000, "Received ENV_CHARSET on non 7.0 server!"); + Debug.Assert(!_isShiloh, "Received ENV_CHARSET on non 7.0 server!"); if (!TryReadTwoStringFields(env, stateObj)) { return false; @@ -3124,7 +3118,7 @@ private bool TryProcessEnvChange(int tokenLength, TdsParserStateObject stateObj, case TdsEnums.ENV_ENLISTDTC: case TdsEnums.ENV_DEFECTDTC: case TdsEnums.ENV_TRANSACTIONENDED: - Debug.Assert(_is2005, "Received new ENVCHANGE transaction/DTC token on pre 9.0 server!"); + Debug.Assert(_isYukon, "Received new ENVCHANGE transaction/DTC token on pre 9.0 server!"); if (!stateObj.TryReadByte(out byteLength)) { @@ -3180,7 +3174,7 @@ private bool TryProcessEnvChange(int tokenLength, TdsParserStateObject stateObj, break; case TdsEnums.ENV_PROMOTETRANSACTION: - Debug.Assert(_is2005, "Received new ENVCHANGE tokens on pre 9.0 server!"); + Debug.Assert(_isYukon, "Received new ENVCHANGE tokens on pre 9.0 server!"); if (!stateObj.TryReadInt32(out env.newLength)) { // new value has 4 byte length @@ -3206,7 +3200,7 @@ private bool TryProcessEnvChange(int tokenLength, TdsParserStateObject stateObj, case TdsEnums.ENV_TRANSACTIONMANAGERADDRESS: case TdsEnums.ENV_SPRESETCONNECTIONACK: // TODO UNDONE BUGBUG - need to implement support for these env changes - Debug.Assert(_is2005, "Received new ENVCHANGE tokens on pre 9.0 server!"); + Debug.Assert(_isYukon, "Received new ENVCHANGE tokens on pre 9.0 server!"); if (!TryReadTwoBinaryFields(env, stateObj)) { return false; @@ -3214,7 +3208,7 @@ private bool TryProcessEnvChange(int tokenLength, TdsParserStateObject stateObj, break; case TdsEnums.ENV_USERINSTANCE: - Debug.Assert(!_is2005, "Received ENV_USERINSTANCE on non 9.0 server!"); + Debug.Assert(!_isYukon, "Received ENV_USERINSTANCE on non 9.0 server!"); if (!TryReadTwoStringFields(env, stateObj)) { return false; @@ -3358,7 +3352,7 @@ private bool TryProcessDone(SqlCommand cmd, SqlDataReader reader, ref RunBehavio return false; } - if (_is2005) + if (_isYukon) { long longCount; if (!stateObj.TryReadInt64(out longCount)) @@ -3374,12 +3368,12 @@ private bool TryProcessDone(SqlCommand cmd, SqlDataReader reader, ref RunBehavio return false; } - // If we haven't yet completed processing login token stream yet, we may be talking to a 2005 server + // If we haven't yet completed processing login token stream yet, we may be talking to a Yukon server // In that case we still have to read another 4 bytes // But don't try to read beyond the TDS stream in this case, because it generates errors if login failed. if (_state == TdsParserState.OpenNotLoggedIn) { - // Login incomplete, if we are reading from 2005 we need to read another int + // Login incomplete, if we are reading from Yukon we need to read another int if (stateObj._inBytesRead > stateObj._inBytesUsed) { byte b; @@ -4049,57 +4043,57 @@ private bool TryProcessLoginAck(TdsParserStateObject stateObj, out SqlLoginAck s UInt32 increment = (a.tdsVersion >> 16) & 0xff; // Server responds: - // 0x07000000 -> 7.0 // Notice server response format is different for bwd compat - // 0x07010000 -> 2000 RTM // Notice server response format is different for bwd compat - // 0x71000001 -> 2000 SP1 - // 0x72xx0002 -> 2005 RTM + // 0x07000000 -> Sphinx // Notice server response format is different for bwd compat + // 0x07010000 -> Shiloh RTM // Notice server response format is different for bwd compat + // 0x71000001 -> Shiloh SP1 + // 0x72xx0002 -> Yukon RTM // information provided by S. Ashwin switch (majorMinor) { - case TdsEnums.SQL70OR2000_MAJOR << 24 | TdsEnums.DEFAULT_MINOR: // 7.0 & 2000 RTM - // note that 7.0 and 2000 can only be distinguished by the increment + case TdsEnums.SPHINXORSHILOH_MAJOR << 24 | TdsEnums.DEFAULT_MINOR: // Sphinx & Shiloh RTM + // note that sphinx and shiloh_rtm can only be distinguished by the increment switch (increment) { - case TdsEnums.SQL2000_INCREMENT: - _is2000 = true; + case TdsEnums.SHILOH_INCREMENT: + _isShiloh = true; break; - case TdsEnums.SQL70_INCREMENT: + case TdsEnums.SPHINX_INCREMENT: // no flag will be set break; default: throw SQL.InvalidTDSVersion(); } break; - case TdsEnums.SQL2000SP1_MAJOR << 24 | TdsEnums.SQL2000SP1_MINOR: // 2000 SP1 - if (increment != TdsEnums.SQL2000SP1_INCREMENT) + case TdsEnums.SHILOHSP1_MAJOR << 24 | TdsEnums.SHILOHSP1_MINOR: // Shiloh SP1 + if (increment != TdsEnums.SHILOHSP1_INCREMENT) { throw SQL.InvalidTDSVersion(); } - _is2000SP1 = true; + _isShilohSP1 = true; break; - case TdsEnums.SQL2005_MAJOR << 24 | TdsEnums.SQL2005_RTM_MINOR: // 2005 - if (increment != TdsEnums.SQL2005_INCREMENT) + case TdsEnums.YUKON_MAJOR << 24 | TdsEnums.YUKON_RTM_MINOR: // Yukon + if (increment != TdsEnums.YUKON_INCREMENT) { throw SQL.InvalidTDSVersion(); } - _is2005 = true; + _isYukon = true; break; - case TdsEnums.SQL2008_MAJOR << 24 | TdsEnums.SQL2008_MINOR: - if (increment != TdsEnums.SQL2008_INCREMENT) + case TdsEnums.KATMAI_MAJOR << 24 | TdsEnums.KATMAI_MINOR: + if (increment != TdsEnums.KATMAI_INCREMENT) { throw SQL.InvalidTDSVersion(); } - _is2008 = true; + _isKatmai = true; break; - case TdsEnums.SQL2012_MAJOR << 24 | TdsEnums.SQL2012_MINOR: - if (increment != TdsEnums.SQL2012_INCREMENT) + case TdsEnums.DENALI_MAJOR << 24 | TdsEnums.DENALI_MINOR: + if (increment != TdsEnums.DENALI_INCREMENT) { throw SQL.InvalidTDSVersion(); } - _is2012 = true; + _isDenali = true; break; default: throw SQL.InvalidTDSVersion(); } - _is2008 |= _is2012; - _is2005 |= _is2008; - _is2000SP1 |= _is2005; // includes all lower versions - _is2000 |= _is2000SP1; // + _isKatmai |= _isDenali; + _isYukon |= _isKatmai; + _isShilohSP1 |= _isYukon; // includes all lower versions + _isShiloh |= _isShilohSP1; // - a.isVersion8 = _is2000; + a.isVersion8 = _isShiloh; stateObj._outBytesUsed = stateObj._outputHeaderLen; byte len; @@ -4135,7 +4129,7 @@ private bool TryProcessLoginAck(TdsParserStateObject stateObj, out SqlLoginAck s Debug.Assert(_state == TdsParserState.OpenNotLoggedIn, "ProcessLoginAck called with state not TdsParserState.OpenNotLoggedIn"); _state = TdsParserState.OpenLoggedIn; - if (_is2005) + if (_isYukon) { if (_fMARS) { @@ -4355,7 +4349,7 @@ internal bool TryProcessError(byte token, TdsParserStateObject stateObj, out Sql } int line; - if (_is2005) + if (_isYukon) { if (!stateObj.TryReadInt32(out line)) { @@ -4371,7 +4365,7 @@ internal bool TryProcessError(byte token, TdsParserStateObject stateObj, out Sql } line = shortLine; - // If we haven't yet completed processing login token stream yet, we may be talking to a 2005 server + // If we haven't yet completed processing login token stream yet, we may be talking to a Yukon server // In that case we still have to read another 2 bytes if (_state == TdsParserState.OpenNotLoggedIn) { @@ -4406,8 +4400,8 @@ internal bool TryProcessReturnValue(int length, { returnValue = null; SqlReturnValue rec = new SqlReturnValue(); - rec.length = length; // In 2005 this length is -1 - if (_is2005) + rec.length = length; // In Yukon this length is -1 + if (_isYukon) { if (!stateObj.TryReadUInt16(out rec.parmIndex)) { @@ -4438,8 +4432,8 @@ internal bool TryProcessReturnValue(int length, UInt32 userType; - // read user type - 4 bytes 2005, 2 backwards - if (Is2005OrNewer) + // read user type - 4 bytes Yukon, 2 backwards + if (IsYukonOrNewer) { if (!stateObj.TryReadUInt32(out userType)) { @@ -4507,20 +4501,20 @@ internal bool TryProcessReturnValue(int length, rec.metaType = MetaType.GetSqlDataType(tdsType, userType, tdsLen); rec.type = rec.metaType.SqlDbType; - // always use the nullable type for parameters if 2000 or later - // 7.0 sometimes sends fixed length return values - if (_is2000) + // always use the nullable type for parameters if Shiloh or later + // Sphinx sometimes sends fixed length return values + if (_isShiloh) { rec.tdsType = rec.metaType.NullableType; rec.IsNullable = true; if (tdsLen == TdsEnums.SQL_USHORTVARMAXLEN) { - Debug.Assert(_is2005, "plp data from pre-2005 server"); + Debug.Assert(_isYukon, "plp data from pre-Yukon server"); rec.metaType = MetaType.GetMaxMetaTypeFromMetaType(rec.metaType); } } else - { // For 7.0, keep the fixed type if that is what is returned + { // For sphinx, keep the fixed type if that is what is returned if (rec.metaType.NullableType == tdsType) rec.IsNullable = true; @@ -4610,7 +4604,7 @@ internal bool TryProcessReturnValue(int length, } } - else if (_is2000 && rec.metaType.IsCharType) + else if (_isShiloh && rec.metaType.IsCharType) { // read the collation for 8.x servers if (!TryProcessCollation(stateObj, out rec.collation)) @@ -5387,13 +5381,13 @@ private bool TryProcessTypeInfo(TdsParserStateObject stateObj, SqlMetaDataPriv c col.metaType = MetaType.GetSqlDataType(tdsType, userType, col.length); col.type = col.metaType.SqlDbType; - // If 7.0, do not change to nullable type - if (_is2000) + // If sphinx, do not change to nullable type + if (_isShiloh) col.tdsType = (col.IsNullable ? col.metaType.NullableType : col.metaType.TDSType); else col.tdsType = tdsType; - if (_is2005) + if (_isYukon) { if (TdsEnums.SQLUDT == tdsType) { @@ -5513,7 +5507,7 @@ private bool TryProcessTypeInfo(TdsParserStateObject stateObj, SqlMetaDataPriv c } // read the collation for 7.x servers - if (_is2000 && col.metaType.IsCharType && (tdsType != TdsEnums.SQLXMLTYPE)) + if (_isShiloh && col.metaType.IsCharType && (tdsType != TdsEnums.SQLXMLTYPE)) { if (!TryProcessCollation(stateObj, out col.collation)) { @@ -5549,8 +5543,8 @@ private bool TryCommonProcessMetaData(TdsParserStateObject stateObj, _SqlMetaDat byte byteLen; UInt32 userType; - // read user type - 4 bytes 2005, 2 backwards - if (Is2005OrNewer) + // read user type - 4 bytes Yukon, 2 backwards + if (IsYukonOrNewer) { if (!stateObj.TryReadUInt32(out userType)) { @@ -5599,7 +5593,7 @@ private bool TryCommonProcessMetaData(TdsParserStateObject stateObj, _SqlMetaDat // Read tablename if present if (col.metaType.IsLong && !col.metaType.IsPlp) { - if (_is2005) + if (_isYukon) { int unusedLen = 0xFFFF; //We ignore this value if (!TryProcessOneTable(stateObj, ref unusedLen, out col.multiPartTableName)) @@ -5802,7 +5796,7 @@ private bool TryProcessOneTable(TdsParserStateObject stateObj, ref int length, o multiPartTableName = default(MultiPartTableName); - if (_is2000SP1) + if (_isShilohSP1) { mpt = new MultiPartTableName(); @@ -7067,19 +7061,15 @@ internal bool TryReadSqlValueInternal(SqlBuffer value, byte tdsType, int length, case TdsEnums.SQLUNIQUEID: { - Debug.Assert(length == GUID_SIZE, "invalid length for SqlGuid type!"); + Debug.Assert(length == 16, "invalid length for SqlGuid type!"); + + byte[] b = new byte[length]; - byte[] b = _tempGuidBytes; - if (b is null) - { - b = new byte[GUID_SIZE]; - } if (!stateObj.TryReadByteArray(b, 0, length)) { return false; } - value.Guid = new Guid(b); - _tempGuidBytes = b; + value.SqlGuid = SqlTypeWorkarounds.SqlGuidCtor(b, true); // doesn't copy the byte array break; } @@ -7129,7 +7119,7 @@ internal bool TryReadSqlValueInternal(SqlBuffer value, byte tdsType, int length, // } internal bool TryReadSqlVariant(SqlBuffer value, int lenTotal, TdsParserStateObject stateObj) { - Debug.Assert(_is2000 == true, "Shouldn't be dealing with sql_variaint in pre-SQL2000 server!"); + Debug.Assert(_isShiloh == true, "Shouldn't be dealing with sql_variaint in pre-SQL2000 server!"); // get the SQLVariant type byte type; if (!stateObj.TryReadByte(out type)) @@ -7316,7 +7306,7 @@ internal bool TryReadSqlVariant(SqlBuffer value, int lenTotal, TdsParserStateObj // internal Task WriteSqlVariantValue(object value, int length, int offset, TdsParserStateObject stateObj, bool canAccumulate = true) { - Debug.Assert(_is2000 == true, "Shouldn't be dealing with sql_variant in pre-SQL2000 server!"); + Debug.Assert(_isShiloh == true, "Shouldn't be dealing with sql_variant in pre-SQL2000 server!"); // handle null values if (ADP.IsNull(value)) @@ -7485,7 +7475,7 @@ internal Task WriteSqlVariantValue(object value, int length, int offset, TdsPars // internal Task WriteSqlVariantDataRowValue(object value, TdsParserStateObject stateObj, bool canAccumulate = true) { - Debug.Assert(_is2000 == true, "Shouldn't be dealing with sql_variant in pre-SQL2000 server!"); + Debug.Assert(_isShiloh == true, "Shouldn't be dealing with sql_variant in pre-SQL2000 server!"); // handle null values if ((null == value) || (DBNull.Value == value)) @@ -8279,8 +8269,8 @@ internal int GetEncodingCharLength(string value, int numChars, int charOffset, E // internal bool TryGetDataLength(SqlMetaDataPriv colmeta, TdsParserStateObject stateObj, out ulong length) { - // Handle 2005 specific tokens - if (_is2005 && colmeta.metaType.IsPlp) + // Handle Yukon specific tokens + if (_isYukon && colmeta.metaType.IsPlp) { Debug.Assert(colmeta.tdsType == TdsEnums.SQLXMLTYPE || colmeta.tdsType == TdsEnums.SQLBIGVARCHAR || @@ -8324,8 +8314,8 @@ internal bool TryGetTokenLength(byte token, TdsParserStateObject stateObj, out i return stateObj.TryReadInt32(out tokenLength); } - if (_is2005) - { // Handle 2005 specific exceptions + if (_isYukon) + { // Handle Yukon specific exceptions if (token == TdsEnums.SQLUDT) { // special case for UDTs tokenLength = -1; // Should we return -1 or not call GetTokenLength for UDTs? @@ -8333,7 +8323,7 @@ internal bool TryGetTokenLength(byte token, TdsParserStateObject stateObj, out i } else if (token == TdsEnums.SQLRETURNVALUE) { - tokenLength = -1; // In 2005, the RETURNVALUE token stream no longer has length + tokenLength = -1; // In Yukon, the RETURNVALUE token stream no longer has length return true; } else if (token == TdsEnums.SQLXMLTYPE) @@ -8845,7 +8835,7 @@ internal void TdsLogin(SqlLogin rec, _physicalStateObj._outputMessageType = TdsEnums.MT_LOGIN7; // length in bytes - int length = TdsEnums.SQL2005_LOG_REC_FIXED_LEN; + int length = TdsEnums.YUKON_LOG_REC_FIXED_LEN; string clientInterfaceName = TdsEnums.SQL_PROVIDER_NAME; Debug.Assert(TdsEnums.MAXLEN_CLIENTINTERFACE >= clientInterfaceName.Length, "cchCltIntName can specify at most 128 unicode characters. See Tds spec"); @@ -8954,7 +8944,7 @@ internal void TdsLogin(SqlLogin rec, WriteInt(length, _physicalStateObj); if (recoverySessionData == null) { - WriteInt((TdsEnums.SQL2012_MAJOR << 24) | (TdsEnums.SQL2012_INCREMENT << 16) | TdsEnums.SQL2012_MINOR, _physicalStateObj); + WriteInt((TdsEnums.DENALI_MAJOR << 24) | (TdsEnums.DENALI_INCREMENT << 16) | TdsEnums.DENALI_MINOR, _physicalStateObj); } else { @@ -9039,7 +9029,7 @@ internal void TdsLogin(SqlLogin rec, WriteInt(0, _physicalStateObj); // LCID is unused by server // Start writing offset and length of variable length portions - int offset = TdsEnums.SQL2005_LOG_REC_FIXED_LEN; + int offset = TdsEnums.YUKON_LOG_REC_FIXED_LEN; // write offset/length pairs @@ -9494,7 +9484,7 @@ internal SqlDataReader TdsExecuteTransactionManagerRequest( stateObj.SniContext = SniContext.Snix_Execute; - if (_is2005) + if (_isYukon) { const int marsHeaderSize = 18; // 4 + 2 + 8 + 4 const int totalHeaderLength = 22; // 4 + 4 + 2 + 8 + 4 @@ -9529,7 +9519,7 @@ internal SqlDataReader TdsExecuteTransactionManagerRequest( } break; case TdsEnums.TransactionManagerRequestType.Begin: - Debug.Assert(Is2005OrNewer, "Should not be calling TdsExecuteTransactionManagerRequest on pre-2005 clients for BeginTransaction!"); + Debug.Assert(IsYukonOrNewer, "Should not be calling TdsExecuteTransactionManagerRequest on pre-Yukon clients for BeginTransaction!"); Debug.Assert(null != transaction, "Should have specified an internalTransaction when doing a BeginTransaction request!"); // Only assign the passed in transaction if it is not equal to the current transaction. @@ -9558,13 +9548,13 @@ internal SqlDataReader TdsExecuteTransactionManagerRequest( WriteString(transactionName, stateObj); break; case TdsEnums.TransactionManagerRequestType.Promote: - Debug.Assert(Is2005OrNewer, "Should not be calling TdsExecuteTransactionManagerRequest on pre-2005 clients for PromoteTransaction!"); + Debug.Assert(IsYukonOrNewer, "Should not be calling TdsExecuteTransactionManagerRequest on pre-Yukon clients for PromoteTransaction!"); // No payload - except current transaction in header // Promote returns a DTC cookie. However, the transaction cookie we use for the // connection does not change after a promote. break; case TdsEnums.TransactionManagerRequestType.Commit: - Debug.Assert(Is2005OrNewer, "Should not be calling TdsExecuteTransactionManagerRequest on pre-2005 clients for CommitTransaction!"); + Debug.Assert(IsYukonOrNewer, "Should not be calling TdsExecuteTransactionManagerRequest on pre-Yukon clients for CommitTransaction!"); Debug.Assert(transactionName.Length == 0, "Should not have a transaction name on Commit"); stateObj.WriteByte((byte)0); // No xact name @@ -9576,7 +9566,7 @@ internal SqlDataReader TdsExecuteTransactionManagerRequest( // WriteByte((byte) 0, stateObj); // No begin xact name break; case TdsEnums.TransactionManagerRequestType.Rollback: - Debug.Assert(Is2005OrNewer, "Should not be calling TdsExecuteTransactionManagerRequest on pre-2005 clients for RollbackTransaction!"); + Debug.Assert(IsYukonOrNewer, "Should not be calling TdsExecuteTransactionManagerRequest on pre-Yukon clients for RollbackTransaction!"); stateObj.WriteByte((byte)(transactionName.Length * 2)); // Write number of bytes (unicode string). WriteString(transactionName, stateObj); @@ -9588,7 +9578,7 @@ internal SqlDataReader TdsExecuteTransactionManagerRequest( // WriteByte((byte) 0, stateObj); // No begin xact name break; case TdsEnums.TransactionManagerRequestType.Save: - Debug.Assert(Is2005OrNewer, "Should not be calling TdsExecuteTransactionManagerRequest on pre-2005 clients for SaveTransaction!"); + Debug.Assert(IsYukonOrNewer, "Should not be calling TdsExecuteTransactionManagerRequest on pre-Yukon clients for SaveTransaction!"); stateObj.WriteByte((byte)(transactionName.Length * 2)); // Write number of bytes (unicode string). WriteString(transactionName, stateObj); @@ -9755,7 +9745,7 @@ internal Task TdsExecuteSQLBatch(string text, int timeout, SqlNotificationReques } stateObj.SniContext = SniContext.Snix_Execute; - if (_is2005) + if (_isYukon) { WriteRPCBatchHeaders(stateObj, notificationRequest); @@ -9884,7 +9874,7 @@ internal Task TdsExecuteRPC(SqlCommand cmd, _SqlRPC[] rpcArray, int timeout, boo } stateObj.SniContext = SniContext.Snix_Execute; - if (_is2005) + if (_isYukon) { WriteRPCBatchHeaders(stateObj, notificationRequest); @@ -9899,9 +9889,9 @@ internal Task TdsExecuteRPC(SqlCommand cmd, _SqlRPC[] rpcArray, int timeout, boo if (startParam == 0 || ii > startRpc) { - if (rpcext.ProcID != 0 && _is2000) + if (rpcext.ProcID != 0 && _isShiloh) { - // Perf optimization for 2000 and later, + // Perf optimization for Shiloh and later, Debug.Assert(rpcext.ProcID < 255, "rpcExec:ProcID can't be larger than 255"); WriteShort(0xffff, stateObj); WriteShort((short)(rpcext.ProcID), stateObj); @@ -9967,15 +9957,15 @@ internal Task TdsExecuteRPC(SqlCommand cmd, _SqlRPC[] rpcArray, int timeout, boo // type (parameter record stores the MetaType class which is a helper that encapsulates all the type information we need here) MetaType mt = param.InternalMetaType; - if (mt.Is2008Type) + if (mt.IsNewKatmaiType) { WriteSmiParameter(param, i, 0 != (rpcext.paramoptions[i] & TdsEnums.RPC_PARAM_DEFAULT), stateObj, enableOptimizedParameterBinding, isAdvancedTraceOn); continue; } - if ((!_is2000 && !mt.Is70Supported) || - (!_is2005 && !mt.Is80Supported) || - (!_is2008 && !mt.Is90Supported)) + if ((!_isShiloh && !mt.Is70Supported) || + (!_isYukon && !mt.Is80Supported) || + (!_isKatmai && !mt.Is90Supported)) { throw ADP.VersionDoesNotSupportDataType(mt.TypeName); } @@ -10194,7 +10184,7 @@ internal Task TdsExecuteRPC(SqlCommand cmd, _SqlRPC[] rpcArray, int timeout, boo maxsize = (size > codePageByteSize) ? size : codePageByteSize; if (maxsize == 0) { - // 2005 doesn't like 0 as MaxSize. Change it to 2 for unicode types (SQL9 - 682322) + // Yukon doesn't like 0 as MaxSize. Change it to 2 for unicode types (SQL9 - 682322) if (mt.IsNCharType) maxsize = 2; else @@ -10222,9 +10212,9 @@ internal Task TdsExecuteRPC(SqlCommand cmd, _SqlRPC[] rpcArray, int timeout, boo byte[] udtVal = null; Format format = Format.Native; - Debug.Assert(_is2005, "Invalid DataType UDT for non-2005 or later server!"); + Debug.Assert(_isYukon, "Invalid DataType UDT for non-Yukon or later server!"); - int maxSupportedSize = Is2008OrNewer ? int.MaxValue : short.MaxValue; + int maxSupportedSize = IsKatmaiOrNewer ? int.MaxValue : short.MaxValue; if (!isNull) { @@ -10310,9 +10300,9 @@ internal Task TdsExecuteRPC(SqlCommand cmd, _SqlRPC[] rpcArray, int timeout, boo else if ((!mt.IsVarTime) && (mt.SqlDbType != SqlDbType.Date)) { // Time, Date, DateTime2, DateTimeoffset do not have the size written out maxsize = (size > actualSize) ? size : actualSize; - if (maxsize == 0 && Is2005OrNewer) + if (maxsize == 0 && IsYukonOrNewer) { - // 2005 doesn't like 0 as MaxSize. Change it to 2 for unicode types (SQL9 - 682322) + // Yukon doesn't like 0 as MaxSize. Change it to 2 for unicode types (SQL9 - 682322) if (mt.IsNCharType) maxsize = 2; else @@ -10328,10 +10318,10 @@ internal Task TdsExecuteRPC(SqlCommand cmd, _SqlRPC[] rpcArray, int timeout, boo { if (0 == precision) { - if (_is2000) + if (_isShiloh) stateObj.WriteByte(TdsEnums.DEFAULT_NUMERIC_PRECISION); else - stateObj.WriteByte(TdsEnums.SQL70_DEFAULT_NUMERIC_PRECISION); + stateObj.WriteByte(TdsEnums.SPHINX_DEFAULT_NUMERIC_PRECISION); } else stateObj.WriteByte(precision); @@ -10345,7 +10335,7 @@ internal Task TdsExecuteRPC(SqlCommand cmd, _SqlRPC[] rpcArray, int timeout, boo // write out collation or xml metadata - if (_is2005 && (mt.SqlDbType == SqlDbType.Xml)) + if (_isYukon && (mt.SqlDbType == SqlDbType.Xml)) { if (!string.IsNullOrEmpty(param.XmlSchemaCollectionDatabase) || !string.IsNullOrEmpty(param.XmlSchemaCollectionOwningSchema) || @@ -10391,7 +10381,7 @@ internal Task TdsExecuteRPC(SqlCommand cmd, _SqlRPC[] rpcArray, int timeout, boo stateObj.WriteByte(0); // No schema } } - else if (_is2000 && mt.IsCharType) + else if (_isShiloh && mt.IsCharType) { // if it is not supplied, simply write out our default collation, otherwise, write out the one attached to the parameter SqlCollation outCollation = (param.Collation != null) ? param.Collation : _defaultCollation; @@ -10480,14 +10470,14 @@ internal Task TdsExecuteRPC(SqlCommand cmd, _SqlRPC[] rpcArray, int timeout, boo // If this is not the last RPC we are sending, add the batch flag if (ii < (rpcArray.Length - 1)) { - if (_is2005) + if (_isYukon) { - stateObj.WriteByte(TdsEnums.SQL2005_RPCBATCHFLAG); + stateObj.WriteByte(TdsEnums.YUKON_RPCBATCHFLAG); } else { - stateObj.WriteByte(TdsEnums.SQL2000_RPCBATCHFLAG); + stateObj.WriteByte(TdsEnums.SHILOH_RPCBATCHFLAG); } } } // rpc for loop @@ -10709,7 +10699,7 @@ private void WriteSmiParameter(SqlParameter param, int paramIndex, bool sendDefa ParameterPeekAheadValue peekAhead; SmiParameterMetaData metaData = param.MetaDataForSmi(out peekAhead); - if (!_is2008) + if (!_isKatmai) { MetaType mt = MetaType.GetMetaTypeFromSqlDbType(metaData.SqlDbType, metaData.IsMultiValued); throw ADP.VersionDoesNotSupportDataType(mt.TypeName); @@ -10749,7 +10739,7 @@ private void WriteSmiParameter(SqlParameter param, int paramIndex, bool sendDefa { value = param.GetCoercedValue(); typeCode = MetaDataUtilsSmi.DetermineExtendedTypeCodeForUseWithSqlDbType( - metaData.SqlDbType, metaData.IsMultiValued, value, null, SmiContextFactory.Sql2008Version); + metaData.SqlDbType, metaData.IsMultiValued, value, null, SmiContextFactory.KatmaiVersion); } var sendDefaultValue = sendDefault ? 1 : 0; @@ -11237,7 +11227,7 @@ internal void WriteTceUserTypeAndTypeInfo(SqlMetaDataPriv mdPriv, TdsParserState break; default: WriteTokenLength(mdPriv.tdsType, mdPriv.length, stateObj); - if (mdPriv.metaType.IsCharType && _is2000) + if (mdPriv.metaType.IsCharType && _isShiloh) { WriteUnsignedInt(mdPriv.collation._info, stateObj); stateObj.WriteByte(mdPriv.collation._sortId); @@ -11302,8 +11292,8 @@ internal void WriteBulkCopyMetaData(_SqlMetaDataSet metadataCollection, int coun { _SqlMetaData md = metadataCollection[i]; - // read user type - 4 bytes 2005, 2 backwards - if (Is2005OrNewer) + // read user type - 4 bytes Yukon, 2 backwards + if (IsYukonOrNewer) { WriteInt(0x0, stateObj); } @@ -11362,7 +11352,7 @@ internal void WriteBulkCopyMetaData(_SqlMetaDataSet metadataCollection, int coun default: stateObj.WriteByte(md.tdsType); WriteTokenLength(md.tdsType, md.length, stateObj); - if (md.metaType.IsCharType && _is2000) + if (md.metaType.IsCharType && _isShiloh) { WriteUnsignedInt(md.collation._info, stateObj); stateObj.WriteByte(md.collation._sortId); @@ -11716,8 +11706,8 @@ private Task WriteBulkCopyValueSetupContinuation(Task internalWriteTask, Encodin // Write mars header data, not including the mars header length private void WriteMarsHeaderData(TdsParserStateObject stateObj, SqlInternalTransaction transaction) { - // Function to send over additional payload header data for 2005 and beyond only. - Debug.Assert(_is2005, "WriteMarsHeaderData called on a non-2005 server"); + // Function to send over additional payload header data for Yukon and beyond only. + Debug.Assert(_isYukon, "WriteMarsHeaderData called on a non-Yukon server"); // These are not necessary - can have local started in distributed. // Debug.Assert(!(null != sqlTransaction && null != distributedTransaction), "Error to have local (api started) and distributed transaction at the same time!"); @@ -11795,7 +11785,7 @@ private int GetNotificationHeaderSize(SqlNotificationRequest notificationRequest // Write query notificaiton header data, not including the notificaiton header length private void WriteQueryNotificationHeaderData(SqlNotificationRequest notificationRequest, TdsParserStateObject stateObj) { - Debug.Assert(_is2005, "WriteQueryNotificationHeaderData called on a non-2005 server"); + Debug.Assert(_isYukon, "WriteQueryNotificationHeaderData called on a non-Yukon server"); // We may need to update the notification header length if the header is changed in the future @@ -11829,7 +11819,7 @@ private void WriteQueryNotificationHeaderData(SqlNotificationRequest notificatio // Write the trace header data, not including the trace header length private void WriteTraceHeaderData(TdsParserStateObject stateObj) { - Debug.Assert(this.IncludeTraceHeader, "WriteTraceHeaderData can only be called on a 2012 or higher version server and bid trace with the control bit are on"); + Debug.Assert(this.IncludeTraceHeader, "WriteTraceHeaderData can only be called on a Denali or higher version server and bid trace with the control bit are on"); // We may need to update the trace header length if trace header is changed in the future @@ -11845,7 +11835,7 @@ private void WriteTraceHeaderData(TdsParserStateObject stateObj) private void WriteRPCBatchHeaders(TdsParserStateObject stateObj, SqlNotificationRequest notificationRequest) { - Debug.Assert(_is2005, "WriteRPCBatchHeaders can only be called on 2005 or higher version servers"); + Debug.Assert(_isYukon, "WriteRPCBatchHeaders can only be called on Yukon or higher version servers"); /* Header: TotalLength - DWORD - including all headers and lengths, including itself @@ -11909,8 +11899,8 @@ private void WriteTokenLength(byte token, int length, TdsParserStateObject state // For Plp fields, this should only be used when writing to metadata header. // For actual data length, WriteDataLength should be used. // For Xml fields, there is no token length field. For MAX fields it is 0xffff. - if (_is2005) - { // Handle 2005 specific exceptions + if (_isYukon) + { // Handle Yukon specific exceptions if (TdsEnums.SQLUDT == token) { tokenLength = 8; @@ -12083,15 +12073,7 @@ private Task WriteUnterminatedSqlValue(object value, MetaType type, int actualLe case TdsEnums.SQLUNIQUEID: { - byte[] b; - if (value is Guid guid) - { - b = guid.ToByteArray(); - } - else - { - b = ((SqlGuid)value).ToByteArray(); - } + byte[] b = ((SqlGuid)value).ToByteArray(); Debug.Assert((actualLength == b.Length) && (actualLength == 16), "Invalid length for guid type in com+ object"); stateObj.WriteByteArray(b, actualLength, 0); @@ -13758,9 +13740,9 @@ internal ulong PlpBytesTotalLength(TdsParserStateObject stateObj) + " _connHandler = {14}\n\t" + " _fMARS = {15}\n\t" + " _sessionPool = {16}\n\t" - + " _is2000 = {17}\n\t" - + " _is2000SP1 = {18}\n\t" - + " _is2005 = {19}\n\t" + + " _isShiloh = {17}\n\t" + + " _isShilohSP1 = {18}\n\t" + + " _isYukon = {19}\n\t" + " _sniSpnBuffer = {20}\n\t" + " _errors = {21}\n\t" + " _warnings = {22}\n\t" @@ -13792,9 +13774,9 @@ internal string TraceString() null == _connHandler ? "(null)" : _connHandler.ObjectID.ToString((IFormatProvider)null), _fMARS ? bool.TrueString : bool.FalseString, null == _sessionPool ? "(null)" : _sessionPool.TraceString(), - _is2000 ? bool.TrueString : bool.FalseString, - _is2000SP1 ? bool.TrueString : bool.FalseString, - _is2005 ? bool.TrueString : bool.FalseString, + _isShiloh ? bool.TrueString : bool.FalseString, + _isShilohSP1 ? bool.TrueString : bool.FalseString, + _isYukon ? bool.TrueString : bool.FalseString, null == _sniSpnBuffer ? "(null)" : _sniSpnBuffer.Length.ToString((IFormatProvider)null), _physicalStateObj != null ? "(null)" : _physicalStateObj.ErrorCount.ToString((IFormatProvider)null), _physicalStateObj != null ? "(null)" : _physicalStateObj.WarningCount.ToString((IFormatProvider)null), diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParserHelperClasses.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParserHelperClasses.cs index 3c289ba0e3..017b616cb6 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParserHelperClasses.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParserHelperClasses.cs @@ -497,7 +497,7 @@ private void Set(_SqlMetadataFlags flag, bool value) flags = value ? flags | flag : flags & ~flag; } - internal bool Is2008DateTimeType + internal bool IsNewKatmaiDateTimeType { get { @@ -1152,7 +1152,7 @@ internal string GetCommandTextOrRpcName() sealed internal class SqlReturnValue : SqlMetaDataPriv { - internal ushort parmIndex; //2005 or later only + internal ushort parmIndex; //Yukon or later only internal string parameter; internal readonly SqlBuffer value; diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParserStateObject.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParserStateObject.cs index b22faacb58..6f8c1c8776 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParserStateObject.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParserStateObject.cs @@ -171,7 +171,7 @@ internal int ObjectID internal ulong _longlen; // plp data length indicator internal ulong _longlenleft; // Length of data left to read (64 bit lengths) internal int[] _decimalBits = null; // scratch buffer for decimal/numeric data - internal byte[] _bTmp = new byte[TdsEnums.SQL2005_HEADER_LEN]; // Scratch buffer for misc use + internal byte[] _bTmp = new byte[TdsEnums.YUKON_HEADER_LEN]; // Scratch buffer for misc use internal int _bTmpRead = 0; // Counter for number of temporary bytes read internal Decoder _plpdecoder = null; // Decoder object to process plp character data internal bool _accumulateInfoEvents = false; // TRUE - accumulate info messages during TdsParser.Run, FALSE - fire them @@ -515,8 +515,8 @@ internal bool TryStartNewRow(bool isNullCompressed, int nullBitmapColumnsCount = // initialize or unset null bitmap information for the current row if (isNullCompressed) { - // assert that NBCROW is not in use by 2005 or before - Debug.Assert(_parser.Is2008OrNewer, "NBCROW is sent by pre-2008 server"); + // assert that NBCROW is not in use by Yukon or before + Debug.Assert(_parser.IsKatmaiOrNewer, "NBCROW is sent by pre-Katmai server"); if (!_nullBitmapInfo.TryInitialize(this, nullBitmapColumnsCount)) { @@ -1306,7 +1306,7 @@ internal bool SetPacketSize(int size) "SetPacketSize should only be called on a stateObj with null buffers on the physicalStateObj!"); Debug.Assert(_inBuff == null || - (_parser.Is2005OrNewer && + (_parser.IsYukonOrNewer && _outBytesUsed == (_outputHeaderLen + BitConverter.ToInt32(_outBuff, _outputHeaderLen)) && _outputPacketNumber == 1) || @@ -3373,9 +3373,9 @@ internal Task WritePacket(byte flushMode, bool canAccumulate = false) } if ( - // This appears to be an optimization to avoid writing empty packets in 2005 - // However, since we don't know the version prior to login Is2005OrNewer was always false prior to login - // So removing the Is2005OrNewer check causes issues since the login packet happens to meet the rest of the conditions below + // This appears to be an optimization to avoid writing empty packets in Yukon + // However, since we don't know the version prior to login IsYukonOrNewer was always false prior to login + // So removing the IsYukonOrNewer check causes issues since the login packet happens to meet the rest of the conditions below // So we need to avoid this check prior to login completing state == TdsParserState.OpenLoggedIn && !_bulkCopyOpperationInProgress // ignore the condition checking for bulk copy (SQL BU 414551) diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/sqlinternaltransaction.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/sqlinternaltransaction.cs index df63fef962..f1f929da7b 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/sqlinternaltransaction.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/sqlinternaltransaction.cs @@ -284,9 +284,9 @@ internal void CloseFromConnection() TdsParser.ReliabilitySection.Assert("unreliable call to CloseFromConnection"); // you need to setup for a thread abort somewhere before you call this method if (processFinallyBlock) { - // Always ensure we're zombied; 2005 will send an EnvChange that + // Always ensure we're zombied; Yukon will send an EnvChange that // will cause the zombie, but only if we actually go to the wire; - // 7.0 and 2000 won't send the env change, so we have to handle + // Sphinx and Shiloh won't send the env change, so we have to handle // them ourselves. Zombie(); } @@ -311,10 +311,10 @@ internal void Commit() // simply commits the transaction from the most recent BEGIN, nested or otherwise. _innerConnection.ExecuteTransaction(SqlInternalConnection.TransactionRequest.Commit, null, IsolationLevel.Unspecified, null, false); - // SQL BU DT 291159 - perform full Zombie on pre-2005, but do not actually - // complete internal transaction until informed by server in the case of 2005 + // SQL BU DT 291159 - perform full Zombie on pre-Yukon, but do not actually + // complete internal transaction until informed by server in the case of Yukon // or later. - if (!IsZombied && !_innerConnection.Is2005OrNewer) + if (!IsZombied && !_innerConnection.IsYukonOrNewer) { // Since nested transactions are no longer allowed, set flag to false. // This transaction has been completed. @@ -483,10 +483,10 @@ internal void Rollback(string transactionName) { _innerConnection.ExecuteTransaction(SqlInternalConnection.TransactionRequest.Rollback, transactionName, IsolationLevel.Unspecified, null, false); - if (!IsZombied && !_innerConnection.Is2005OrNewer) + if (!IsZombied && !_innerConnection.IsYukonOrNewer) { // Check if Zombied before making round-trip to server. - // Against 2005 we receive an envchange on the ExecuteTransaction above on the + // Against Yukon we receive an envchange on the ExecuteTransaction above on the // parser that calls back into SqlTransaction for the Zombie() call. CheckTransactionLevelAndZombie(); } @@ -545,7 +545,7 @@ internal void Zombie() // NOTE: we'll be called from the TdsParser when it gets appropriate // ENVCHANGE events that indicate the transaction has completed, however - // we cannot rely upon those events occuring in the case of pre-2005 + // we cannot rely upon those events occuring in the case of pre-Yukon // servers (and when we don't go to the wire because the connection // is broken) so we can also be called from the Commit/Rollback/Save // methods to handle that case as well. diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Resources/Strings.es.resx b/src/Microsoft.Data.SqlClient/netfx/src/Resources/Strings.es.resx index 2bd80b50ef..b46712282b 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Resources/Strings.es.resx +++ b/src/Microsoft.Data.SqlClient/netfx/src/Resources/Strings.es.resx @@ -2494,7 +2494,7 @@ No se puede usar 'Authentication' con 'Integrated Security'. - No se puede usar "Authentication=Active Directory Integrated" con las palabras clave de cadena de conexión "Password" o "PWD". + Cannot use 'Authentication=Active Directory Integrated' with 'Password' or 'PWD' connection string keywords. No se puede usar "Authentication=Active Directory Interactive" con las palabras clave de cadena de conexión "Password" ni "PWD". diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Resources/Strings.ko.resx b/src/Microsoft.Data.SqlClient/netfx/src/Resources/Strings.ko.resx index 2dff8da10f..7349b37c6b 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Resources/Strings.ko.resx +++ b/src/Microsoft.Data.SqlClient/netfx/src/Resources/Strings.ko.resx @@ -2494,7 +2494,7 @@ 'Authentication'을 'Integrated Security'와 함께 사용할 수 없습니다. - 'Password' 또는 'PWD' 연결 문자열 키워드와 함께 'Authentication=Active Directory Integrated'를 사용할 수 없습니다. + Cannot use 'Authentication=Active Directory Integrated' with 'Password' or 'PWD' connection string keywords. 'Authentication=Active Directory Interactive'를 'Password' 또는 'PWD' 연결 문자열 키워드와 함께 사용할 수 없습니다. diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Resources/Strings.zh-Hans.resx b/src/Microsoft.Data.SqlClient/netfx/src/Resources/Strings.zh-Hans.resx index 691824651b..46736198f7 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Resources/Strings.zh-Hans.resx +++ b/src/Microsoft.Data.SqlClient/netfx/src/Resources/Strings.zh-Hans.resx @@ -2494,7 +2494,7 @@ 无法对“Integrated Security”使用“Authentication”。 - 无法将 “Authentication=Active Directory Integrated” 与 “Password” 或 “PWD” 连接字符串关键字配合使用。 + Cannot use 'Authentication=Active Directory Integrated' with 'Password' or 'PWD' connection string keywords. 无法对 "Password" 或 "PWD" 连接字符串关键字使用 "Authentication=Active Directory Interactive"。 diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/AzureAttestationBasedEnclaveProvider.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/AzureAttestationBasedEnclaveProvider.cs index 0e891924fb..d08db25036 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/AzureAttestationBasedEnclaveProvider.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/AzureAttestationBasedEnclaveProvider.cs @@ -49,7 +49,7 @@ internal class AzureAttestationEnclaveProvider : EnclaveProviderBase { #region Constants private const int DiffieHellmanKeySize = 384; - private const int AzureBasedAttestationProtocolId = (int)SqlConnectionAttestationProtocol.AAS; + private const int AzureBasedAttestationProtocolId = 1; private const int SigningKeyRetryInSec = 3; #endregion diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/EnclaveDelegate.Crypto.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/EnclaveDelegate.Crypto.cs index fdd2812d1b..241c6aaf58 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/EnclaveDelegate.Crypto.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/EnclaveDelegate.Crypto.cs @@ -10,7 +10,7 @@ namespace Microsoft.Data.SqlClient { internal sealed partial class EnclaveDelegate { - private static readonly ConcurrentDictionary s_enclaveProviders = new(); + private static readonly Dictionary s_enclaveProviders = new Dictionary(); /// /// Create a new enclave session @@ -103,8 +103,8 @@ private SqlColumnEncryptionEnclaveProvider GetEnclaveProvider(SqlConnectionAttes #if ENCLAVE_SIMULATOR case SqlConnectionAttestationProtocol.SIM: - NoneAttestationEnclaveProvider noneAttestationEnclaveProvider = new NoneAttestationEnclaveProvider(); - s_enclaveProviders[attestationProtocol] = (SqlColumnEncryptionEnclaveProvider)noneAttestationEnclaveProvider; + SimulatorEnclaveProvider simulatorEnclaveProvider = new SimulatorEnclaveProvider(); + s_enclaveProviders[attestationProtocol] = (SqlColumnEncryptionEnclaveProvider)simulatorEnclaveProvider; sqlColumnEncryptionEnclaveProvider = s_enclaveProviders[attestationProtocol]; break; #endif diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/EnclaveProviderBase.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/EnclaveProviderBase.cs index 0c72beac9d..a32e46f581 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/EnclaveProviderBase.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/EnclaveProviderBase.cs @@ -151,7 +151,7 @@ protected void GetEnclaveSessionHelper(EnclaveSessionParameters enclaveSessionPa { if (shouldGenerateNonce) { - using (RandomNumberGenerator rng = RandomNumberGenerator.Create()) + using (RandomNumberGenerator rng = new RNGCryptoServiceProvider()) { // Client decides to initiate the process of attesting the enclave and to establish a secure session with the enclave. // To ensure that server send new attestation request instead of replaying / re-sending the old token, we will create a nonce for current attestation request. diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/LocalAppContextSwitches.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/LocalAppContextSwitches.cs index 8e390b21d6..c0d7295944 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/LocalAppContextSwitches.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/LocalAppContextSwitches.cs @@ -14,12 +14,10 @@ internal static partial class LocalAppContextSwitches internal const string MakeReadAsyncBlockingString = @"Switch.Microsoft.Data.SqlClient.MakeReadAsyncBlocking"; internal const string LegacyRowVersionNullString = @"Switch.Microsoft.Data.SqlClient.LegacyRowVersionNullBehavior"; internal const string UseSystemDefaultSecureProtocolsString = @"Switch.Microsoft.Data.SqlClient.UseSystemDefaultSecureProtocols"; - internal const string SuppressInsecureTLSWarningString = @"Switch.Microsoft.Data.SqlClient.SuppressInsecureTLSWarning"; - private static bool s_makeReadAsyncBlocking; + private static bool _makeReadAsyncBlocking; private static bool? s_LegacyRowVersionNullBehavior; private static bool? s_UseSystemDefaultSecureProtocols; - private static bool? s_SuppressInsecureTLSWarning; #if !NETFRAMEWORK static LocalAppContextSwitches() @@ -37,26 +35,12 @@ static LocalAppContextSwitches() } #endif - public static bool SuppressInsecureTLSWarning - { - get - { - if (s_SuppressInsecureTLSWarning is null) - { - bool result; - result = AppContext.TryGetSwitch(SuppressInsecureTLSWarningString, out result) ? result : false; - s_SuppressInsecureTLSWarning = result; - } - return s_SuppressInsecureTLSWarning.Value; - } - } - public static bool MakeReadAsyncBlocking { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { - return AppContext.TryGetSwitch(MakeReadAsyncBlockingString, out s_makeReadAsyncBlocking) ? s_makeReadAsyncBlocking : false; + return AppContext.TryGetSwitch(MakeReadAsyncBlockingString, out _makeReadAsyncBlocking) ? _makeReadAsyncBlocking : false; } } diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Server/SqlDataRecord.netfx.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Server/SqlDataRecord.netfx.cs index 29e2bf9305..8d65b63921 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Server/SqlDataRecord.netfx.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Server/SqlDataRecord.netfx.cs @@ -30,7 +30,7 @@ private Type GetFieldTypeFrameworkSpecific(int ordinal) private object GetValueFrameworkSpecific(int ordinal) { SmiMetaData metaData = GetSmiMetaData(ordinal); - if (SmiVersion >= SmiContextFactory.Sql2008Version) + if (SmiVersion >= SmiContextFactory.KatmaiVersion) { return ValueUtilsSmi.GetValue200(_eventSink, _recordBuffer, ordinal, metaData, _recordContext); } @@ -43,7 +43,7 @@ private object GetValueFrameworkSpecific(int ordinal) private object GetSqlValueFrameworkSpecific(int ordinal) { SmiMetaData metaData = GetSmiMetaData(ordinal); - if (SmiVersion >= SmiContextFactory.Sql2008Version) + if (SmiVersion >= SmiContextFactory.KatmaiVersion) { return ValueUtilsSmi.GetSqlValue200(_eventSink, _recordBuffer, ordinal, metaData, _recordContext); } @@ -89,7 +89,7 @@ private int SetValuesFrameworkSpecific(params object[] values) // the validation loop and here, or if an invalid UDT was sent). for (int i = 0; i < copyLength; i++) { - if (SmiVersion >= SmiContextFactory.Sql2008Version) + if (SmiVersion >= SmiContextFactory.KatmaiVersion) { ValueUtilsSmi.SetCompatibleValueV200(_eventSink, _recordBuffer, i, GetSmiMetaData(i), values[i], typeCodes[i], offset: 0, length: 0, peekAhead: null); } @@ -117,7 +117,7 @@ private void SetValueFrameworkSpecific(int ordinal, object value) throw ADP.InvalidCast(); } - if (SmiVersion >= SmiContextFactory.Sql2008Version) + if (SmiVersion >= SmiContextFactory.KatmaiVersion) { ValueUtilsSmi.SetCompatibleValueV200(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), value, typeCode, offset: 0, length: 0, peekAhead: null); } @@ -127,8 +127,8 @@ private void SetValueFrameworkSpecific(int ordinal, object value) } } - private void SetTimeSpanFrameworkSpecific(int ordinal, TimeSpan value) => ValueUtilsSmi.SetTimeSpan(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), value, SmiVersion >= SmiContextFactory.Sql2008Version); - private void SetDateTimeOffsetFrameworkSpecific(int ordinal, DateTimeOffset value) => ValueUtilsSmi.SetDateTimeOffset(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), value, SmiVersion >= SmiContextFactory.Sql2008Version); + private void SetTimeSpanFrameworkSpecific(int ordinal, TimeSpan value) => ValueUtilsSmi.SetTimeSpan(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), value, SmiVersion >= SmiContextFactory.KatmaiVersion); + private void SetDateTimeOffsetFrameworkSpecific(int ordinal, DateTimeOffset value) => ValueUtilsSmi.SetDateTimeOffset(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), value, SmiVersion >= SmiContextFactory.KatmaiVersion); private ulong SmiVersion => InOutOfProcHelper.InProc ? SmiContextFactory.Instance.NegotiatedSmiVersion : SmiContextFactory.LatestVersion; } diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Server/SqlMetaData.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Server/SqlMetaData.cs index e5bb5b0047..051b31d79b 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Server/SqlMetaData.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Server/SqlMetaData.cs @@ -428,7 +428,8 @@ int sortOrdinal Construct(name, dbType, userDefinedType, string.Empty, useServerDefault, isUniqueKey, columnSortOrder, sortOrdinal); break; default: - throw SQL.InvalidSqlDbTypeForConstructor(dbType); + SQL.InvalidSqlDbTypeForConstructor(dbType); + break; } } @@ -812,7 +813,7 @@ int sortOrdinal _sortOrdinal = sortOrdinal; } - // Construction for Decimal type and new 2008 Date/Time types + // Construction for Decimal type and new Katmai Date/Time types private void Construct( string name, SqlDbType dbType, diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Server/SqlUserDefinedTypeAttribute.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Server/SqlUserDefinedTypeAttribute.cs index 1a399d2749..ffdcec4f2a 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Server/SqlUserDefinedTypeAttribute.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Server/SqlUserDefinedTypeAttribute.cs @@ -33,7 +33,7 @@ public sealed class SqlUserDefinedTypeAttribute : Attribute private string _name; // The maximum value for the maxbytesize field, in bytes. - internal const int Sql2005MaxByteSizeValue = 8000; + internal const int YukonMaxByteSizeValue = 8000; private string _validationMethodName = null; /// diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Server/ValueUtilsSmi.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Server/ValueUtilsSmi.cs index 553377e005..f53396cdaa 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Server/ValueUtilsSmi.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Server/ValueUtilsSmi.cs @@ -248,9 +248,9 @@ internal static DateTime GetDateTime(SmiEventSink_Default sink, ITypedGettersV3 } // calling GetDateTimeOffset on possibly v100 SMI - internal static DateTimeOffset GetDateTimeOffset(SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal, SmiMetaData metaData, bool gettersSupport2008DateTime) + internal static DateTimeOffset GetDateTimeOffset(SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal, SmiMetaData metaData, bool gettersSupportKatmaiDateTime) { - if (gettersSupport2008DateTime) + if (gettersSupportKatmaiDateTime) { return GetDateTimeOffset(sink, (SmiTypedGetterSetter)getters, ordinal, metaData); } @@ -1032,7 +1032,7 @@ internal static TimeSpan GetTimeSpan(SmiEventSink_Default sink, SmiTypedGetterSe ); } - // GetValue() for v200 SMI (2008 Date/Time types) + // GetValue() for v200 SMI (new Katmai Date/Time types) internal static object GetValue200( SmiEventSink_Default sink, SmiTypedGetterSetter getters, @@ -1521,12 +1521,12 @@ internal static void SetDateTime(SmiEventSink_Default sink, ITypedSettersV3 sett internal static void SetDateTimeOffset(SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SmiMetaData metaData, DateTimeOffset value #if NETFRAMEWORK - , bool settersSupport2008DateTime + , bool settersSupportKatmaiDateTime #endif ) { #if NETFRAMEWORK - if (!settersSupport2008DateTime) + if (!settersSupportKatmaiDateTime) { throw ADP.InvalidCast(); } @@ -1702,12 +1702,12 @@ internal static void SetString(SmiEventSink_Default sink, ITypedSettersV3 setter internal static void SetTimeSpan(SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SmiMetaData metaData, TimeSpan value #if NETFRAMEWORK - , bool settersSupport2008DateTime + , bool settersSupportKatmaiDateTime #endif ) { #if NETFRAMEWORK - if (!settersSupport2008DateTime) + if (!settersSupportKatmaiDateTime) { throw ADP.InvalidCast(); } @@ -1870,7 +1870,7 @@ int offset } } - // VSTFDevDiv#479681 - Data corruption when sending 2008 Date types to the server via TVP + // VSTFDevDiv#479681 - Data corruption when sending Katmai Date types to the server via TVP // Ensures proper handling on DateTime2 sub type for Sql_Variants and TVPs. internal static void SetCompatibleValueV200( SmiEventSink_Default sink, @@ -1906,7 +1906,7 @@ SqlBuffer.StorageType storageType } } - // Implements SqlClient 2.0-compatible SetValue() semantics + VS2008 extensions + // Implements SqlClient 2.0-compatible SetValue() semantics + Orcas extensions // Assumes caller already validated basic type against the metadata, other than trimming lengths and // checking individual field values (TVPs) internal static void SetCompatibleValueV200( @@ -2218,9 +2218,9 @@ internal static void FillCompatibleSettersFromReader(SmiEventSink_Default sink, } ExtendedClrTypeCode typeCode = MetaDataUtilsSmi.DetermineExtendedTypeCodeForUseWithSqlDbType(metaData[i].SqlDbType, metaData[i].IsMultiValued, o, null #if NETFRAMEWORK - ,// TODO: this version works for shipping VS2008, since only 2008 (TVP) codepath calls this method at this time. - // Need a better story for smi versioning of ValueUtilsSmi post-VS2008 - SmiContextFactory.Sql2008Version + ,// TODO: this version works for shipping Orcas, since only Katmai (TVP) codepath calls this method at this time. + // Need a better story for smi versioning of ValueUtilsSmi post-Orcas + SmiContextFactory.KatmaiVersion #endif ); if ((storageType == SqlBuffer.StorageType.DateTime2) || (storageType == SqlBuffer.StorageType.Date)) @@ -4087,9 +4087,9 @@ DataTable value cellTypes[i] = MetaDataUtilsSmi.DetermineExtendedTypeCodeForUseWithSqlDbType( fieldMetaData.SqlDbType, fieldMetaData.IsMultiValued, cellValue, fieldMetaData.Type #if NETFRAMEWORK - ,// TODO: this version works for shipping VS2008, since only 2008 supports TVPs at this time. - // Need a better story for smi versioning of ValueUtilsSmi post-VS2008 - SmiContextFactory.Sql2008Version + ,// TODO: this version works for shipping Orcas, since only Katmai supports TVPs at this time. + // Need a better story for smi versioning of ValueUtilsSmi post-Orcas + SmiContextFactory.KatmaiVersion #endif ); } diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Server/ValueUtilsSmi.netfx.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Server/ValueUtilsSmi.netfx.cs index 86d83dd45d..d48a8df2e1 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Server/ValueUtilsSmi.netfx.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Server/ValueUtilsSmi.netfx.cs @@ -116,9 +116,9 @@ internal static TextReader GetTextReader(SmiEventSink_Default sink, ITypedGetter } // calling GetTimeSpan on possibly v100 SMI - internal static TimeSpan GetTimeSpan(SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal, SmiMetaData metaData, bool gettersSupport2008DateTime) + internal static TimeSpan GetTimeSpan(SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal, SmiMetaData metaData, bool gettersSupportKatmaiDateTime) { - if (gettersSupport2008DateTime) + if (gettersSupportKatmaiDateTime) { return GetTimeSpan(sink, (SmiTypedGetterSetter)getters, ordinal, metaData); } diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCollation.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCollation.cs index ab2e314228..83a8c8cc58 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCollation.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCollation.cs @@ -216,7 +216,7 @@ public static SqlCollation FromLCIDAndSort(int lcid, SqlCompareOptions sqlCompar int lcidValue = lcid & (int)MaskLcid; Debug.Assert(lcidValue == lcid, "invalid set_LCID value"); - // Some 2008 LCIDs do not have collation with version = 0 + // Some new Katmai LCIDs do not have collation with version = 0 // since user has no way to specify collation version, we set the first (minimal) supported version for these collations int versionBits = FirstSupportedCollationVersion(lcidValue) << LcidVersionBitOffset; Debug.Assert((versionBits & MaskLcidVersion) == versionBits, "invalid version returned by FirstSupportedCollationVersion"); diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommandBuilder.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommandBuilder.cs index 07f834a749..cfac55e028 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommandBuilder.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommandBuilder.cs @@ -16,7 +16,7 @@ namespace Microsoft.Data.SqlClient { /// - [DesignerCategory("")] + [DesignerCategory()] public sealed class SqlCommandBuilder : DbCommandBuilder { /// diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlDependencyListener.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlDependencyListener.cs index ce266f7fb9..5867bc3327 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlDependencyListener.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlDependencyListener.cs @@ -1131,25 +1131,37 @@ internal static SqlNotification ProcessMessage(SqlXml xmlMessage) messageAttributes |= MessageAttributes.Source; break; case InfoAttribute: - string value = xmlReader.Value; - // 3 of the server info values do not match client values - map. - switch (value) + try { - case "set options": - info = SqlNotificationInfo.Options; - break; - case "previous invalid": - info = SqlNotificationInfo.PreviousFire; - break; - case "query template limit": - info = SqlNotificationInfo.TemplateLimit; - break; - default: - if (Enum.TryParse(value, true, out SqlNotificationInfo temp) && Enum.IsDefined(typeof(SqlNotificationInfo), temp)) - { - info = temp; - } - break; + string value = xmlReader.Value; + // 3 of the server info values do not match client values - map. + switch (value) + { + case "set options": + info = SqlNotificationInfo.Options; + break; + case "previous invalid": + info = SqlNotificationInfo.PreviousFire; + break; + case "query template limit": + info = SqlNotificationInfo.TemplateLimit; + break; + default: + SqlNotificationInfo temp = (SqlNotificationInfo)Enum.Parse(typeof(SqlNotificationInfo), value, true); + if (Enum.IsDefined(typeof(SqlNotificationInfo), temp)) + { + info = temp; + } + break; + } + } + catch (Exception e) + { + if (!ADP.IsCatchableExceptionType(e)) + { + throw; + } + ADP.TraceExceptionWithoutRethrow(e); // Discard failure, if it should occur. } messageAttributes |= MessageAttributes.Info; break; diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlEnclaveAttestationParameters.Crypto.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlEnclaveAttestationParameters.Crypto.cs index c2e9739237..06262b364f 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlEnclaveAttestationParameters.Crypto.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlEnclaveAttestationParameters.Crypto.cs @@ -7,12 +7,12 @@ namespace Microsoft.Data.SqlClient { - /// + /// internal class SqlEnclaveAttestationParameters { private readonly byte[] _input; - /// + /// internal SqlEnclaveAttestationParameters(int protocol, byte[] input, ECDiffieHellman clientDiffieHellmanKey) { if (input == null) @@ -29,13 +29,13 @@ internal SqlEnclaveAttestationParameters(int protocol, byte[] input, ECDiffieHel ClientDiffieHellmanKey = clientDiffieHellmanKey; } - /// + /// internal int Protocol { get; private set; } - /// + /// internal ECDiffieHellman ClientDiffieHellmanKey { get; private set; } - /// + /// internal byte[] GetInput() { // return a new array for safety so the caller cannot mutate the original diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlEnums.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlEnums.cs index 2037fe57c7..6cc1bcaf35 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlEnums.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlEnums.cs @@ -47,7 +47,7 @@ internal sealed class MetaType internal readonly bool IsCharType; internal readonly bool IsNCharType; internal readonly bool IsSizeInCharacters; - internal readonly bool Is2008Type; + internal readonly bool IsNewKatmaiType; internal readonly bool IsVarTime; internal readonly bool Is70Supported; @@ -79,7 +79,7 @@ public MetaType(byte precision, byte scale, int fixedLength, bool isFixed, bool IsCharType = _IsCharType(sqldbType); IsNCharType = _IsNCharType(sqldbType); IsSizeInCharacters = _IsSizeInCharacters(sqldbType); - Is2008Type = _Is2008Type(sqldbType); + IsNewKatmaiType = _IsNewKatmaiType(sqldbType); IsVarTime = _IsVarTime(sqldbType); Is70Supported = _Is70Supported(SqlDbType); @@ -145,7 +145,7 @@ private static bool _Is100Supported(SqlDbType type) => SqlDbType.DateTime2 == type || SqlDbType.DateTimeOffset == type; - private static bool _Is2008Type(SqlDbType type) => SqlDbType.Structured == type; + private static bool _IsNewKatmaiType(SqlDbType type) => SqlDbType.Structured == type; internal static bool _IsVarTime(SqlDbType type) => type == SqlDbType.Time || type == SqlDbType.DateTime2 || type == SqlDbType.DateTimeOffset; diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlError.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlError.cs deleted file mode 100644 index 2fc7dd605e..0000000000 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlError.cs +++ /dev/null @@ -1,91 +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. - -using System; - -namespace Microsoft.Data.SqlClient -{ - /// - [Serializable] - public sealed class SqlError - { - // bug fix - MDAC 48965 - missing source of exception - private readonly string _source = TdsEnums.SQL_PROVIDER_NAME; - private readonly int _number; - private readonly byte _state; - private readonly byte _errorClass; - [System.Runtime.Serialization.OptionalField(VersionAdded = 2)] - private readonly string _server; - private readonly string _message; - private readonly string _procedure; - private readonly int _lineNumber; - [System.Runtime.Serialization.OptionalField(VersionAdded = 4)] - private readonly int _win32ErrorCode; - [System.Runtime.Serialization.OptionalField(VersionAdded = 5)] - private readonly Exception _exception; - - internal SqlError(int infoNumber, byte errorState, byte errorClass, string server, string errorMessage, string procedure, int lineNumber, uint win32ErrorCode, Exception exception = null) - : this(infoNumber, errorState, errorClass, server, errorMessage, procedure, lineNumber, exception) - { - _server = server; - _win32ErrorCode = (int)win32ErrorCode; - } - - internal SqlError(int infoNumber, byte errorState, byte errorClass, string server, string errorMessage, string procedure, int lineNumber, Exception exception = null) - { - _number = infoNumber; - _state = errorState; - _errorClass = errorClass; - _server = server; - _message = errorMessage; - _procedure = procedure; - _lineNumber = lineNumber; - _win32ErrorCode = 0; - _exception = exception; - if (errorClass != 0) - { - SqlClientEventSource.Log.TryTraceEvent("SqlError.ctor | ERR | Info Number {0}, Error State {1}, Error Class {2}, Error Message '{3}', Procedure '{4}', Line Number {5}", infoNumber, (int)errorState, (int)errorClass, errorMessage, procedure ?? "None", (int)lineNumber); - } - } - - /// - // bug fix - MDAC #49280 - SqlError does not implement ToString(); - // There is no exception stack included because the correct exception stack is only available - // on SqlException, and to obtain that the SqlError would have to have backpointers all the - // way back to SqlException. If the user needs a call stack, they can obtain it on SqlException. - public override string ToString() - { - return typeof(SqlError).ToString() + ": " + Message; // since this is sealed so we can change GetType to typeof - } - - /// - // bug fix - MDAC #48965 - missing source of exception - public string Source => _source; - - /// - public int Number => _number; - - /// - public byte State => _state; - - /// - public byte Class => _errorClass; - - /// - public string Server => _server; - - /// - public string Message => _message; - - /// - public string Procedure => _procedure; - - /// - public int LineNumber => _lineNumber; - - internal int Win32ErrorCode => _win32ErrorCode; - - internal Exception Exception => _exception; - } -} diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlMetadataFactory.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlMetadataFactory.cs index ce56192b92..52aac76b7d 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlMetadataFactory.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlMetadataFactory.cs @@ -43,7 +43,7 @@ private void addUDTsToDataTypesTable(DataTable dataTypesTable, SqlConnection con "from sys.assemblies as assemblies join sys.assembly_types as types " + "on assemblies.assembly_id = types.assembly_id "; - // pre 9.0/2005 servers do not have UDTs + // pre 9.0/Yukon servers do not have UDTs if (0 > string.Compare(ServerVersion, ServerVersionNormalized90, StringComparison.OrdinalIgnoreCase)) { return; @@ -176,7 +176,7 @@ private void AddTVPsToDataTypesTable(DataTable dataTypesTable, SqlConnection con "where is_table_type = 1"; // TODO: update this check once the server upgrades major version number!!! - // pre 9.0/2005 servers do not have Table types + // pre 9.0/Yukon servers do not have Table types if (0 > string.Compare(ServerVersion, ServerVersionNormalized10, StringComparison.OrdinalIgnoreCase)) { return; diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlSecurityUtility.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlSecurityUtility.cs index 4dabe4351d..67535743af 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlSecurityUtility.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlSecurityUtility.cs @@ -59,14 +59,15 @@ internal static string GetSHA256Hash(byte[] input) } /// - /// Generates cryptographically random bytes + /// Generates cryptographicall random bytes /// /// No of cryptographically random bytes to be generated /// A byte array containing cryptographically generated random bytes internal static void GenerateRandomBytes(byte[] randomBytes) { - RandomNumberGenerator rng = RandomNumberGenerator.Create(); - rng.GetBytes(randomBytes); + // Generate random bytes cryptographically. + RNGCryptoServiceProvider rngCsp = new RNGCryptoServiceProvider(); + rngCsp.GetBytes(randomBytes); } /// diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsEnums.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsEnums.cs index ee281f22c7..0ee8e617f3 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsEnums.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsEnums.cs @@ -70,7 +70,7 @@ internal static class TdsEnums public const int HEADER_LEN = 8; public const int HEADER_LEN_FIELD_OFFSET = 2; public const int SPID_OFFSET = 4; - public const int SQL2005_HEADER_LEN = 12; //2005 headers also include a MARS session id + public const int YUKON_HEADER_LEN = 12; //Yukon headers also include a MARS session id public const int MARS_ID_OFFSET = 8; public const int HEADERTYPE_QNOTIFICATION = 1; public const int HEADERTYPE_MARS = 2; @@ -99,7 +99,7 @@ internal static class TdsEnums // Message types public const byte MT_SQL = 1; // SQL command batch - public const byte MT_LOGIN = 2; // Login message for pre-7.0 + public const byte MT_LOGIN = 2; // Login message for pre-Sphinx (before version 7.0) public const byte MT_RPC = 3; // Remote procedure call public const byte MT_TOKENS = 4; // Table response data stream public const byte MT_BINARY = 5; // Unformatted binary response data (UNUSED) @@ -113,7 +113,7 @@ internal static class TdsEnums public const byte MT_LOGOUT = 13; // Logout message (UNUSED) public const byte MT_TRANS = 14; // Transaction Manager Interface public const byte MT_OLEDB = 15; // ? (UNUSED) - public const byte MT_LOGIN7 = 16; // Login message for 7.0 or later + public const byte MT_LOGIN7 = 16; // Login message for Sphinx (version 7) or later public const byte MT_SSPI = 17; // SSPI message public const byte MT_PRELOGIN = 18; // Pre-login handshake @@ -171,7 +171,7 @@ internal static class TdsEnums public const byte ENV_LOCALEID = 5; // Unicode data sorting locale id public const byte ENV_COMPFLAGS = 6; // Unicode data sorting comparison flags public const byte ENV_COLLATION = 7; // SQL Collation - // The following are environment change tokens valid for 2005 or later. + // The following are environment change tokens valid for Yukon or later. public const byte ENV_BEGINTRAN = 8; // Transaction began public const byte ENV_COMMITTRAN = 9; // Transaction committed public const byte ENV_ROLLBACKTRAN = 10; // Transaction rolled back @@ -294,7 +294,7 @@ public enum ActiveDirectoryWorkflow : byte public const byte SQLVARIANT_SIZE = 2; // size of the fixed portion of a sql variant (type, cbPropBytes) public const byte VERSION_SIZE = 4; // size of the tds version (4 unsigned bytes) public const int CLIENT_PROG_VER = 0x06000000; // Client interface version - public const int SQL2005_LOG_REC_FIXED_LEN = 0x5e; + public const int YUKON_LOG_REC_FIXED_LEN = 0x5e; // misc public const int TEXT_TIME_STAMP_LEN = 8; public const int COLLATION_INFO_LEN = 4; @@ -322,16 +322,16 @@ public enum ActiveDirectoryWorkflow : byte /* Versioning scheme table: Client sends: - 0x70000000 -> 7.0 - 0x71000000 -> 2000 RTM - 0x71000001 -> 2000 SP1 - 0x72xx0002 -> 2005 RTM + 0x70000000 -> Sphinx + 0x71000000 -> Shiloh RTM + 0x71000001 -> Shiloh SP1 + 0x72xx0002 -> Yukon RTM Server responds: - 0x07000000 -> 7.0 // Notice server response format is different for bwd compat - 0x07010000 -> 2000 RTM // Notice server response format is different for bwd compat - 0x71000001 -> 2000 SP1 - 0x72xx0002 -> 2005 RTM + 0x07000000 -> Sphinx // Notice server response format is different for bwd compat + 0x07010000 -> Shiloh RTM // Notice server response format is different for bwd compat + 0x71000001 -> Shiloh SP1 + 0x72xx0002 -> Yukon RTM */ // Pre Shiloh SP1 versioning scheme: @@ -340,7 +340,7 @@ public enum ActiveDirectoryWorkflow : byte public const int SHILOH_INCREMENT = 0x01; // So we need to look at the high-mid byte (b2) as well public const int DEFAULT_MINOR = 0x0000; - // 2000 SP1 and beyond versioning scheme: + // Shiloh SP1 and beyond versioning scheme: // Majors: public const int SHILOHSP1_MAJOR = 0x71; // For Shiloh SP1 and later the versioning schema changed and @@ -458,20 +458,20 @@ public enum ActiveDirectoryWorkflow : byte public const int MAX_NUMERIC_LEN = 0x11; // 17 bytes of data for max numeric/decimal length public const int DEFAULT_NUMERIC_PRECISION = 0x1D; // 29 is the default max numeric precision(Decimal.MaxValue) if not user set - public const int SQL70_DEFAULT_NUMERIC_PRECISION = 0x1C; // 28 is the default max numeric precision for 7.0 (Decimal.MaxValue doesn't work for 7.0) + public const int SPHINX_DEFAULT_NUMERIC_PRECISION = 0x1C; // 28 is the default max numeric precision for Sphinx(Decimal.MaxValue doesn't work for sphinx) public const int MAX_NUMERIC_PRECISION = 0x26; // 38 is max numeric precision; public const byte UNKNOWN_PRECISION_SCALE = 0xff; // -1 is value for unknown precision or scale - // The following datatypes are specific to 2000 (version 8) and later. + // The following datatypes are specific to SHILOH (version 8) and later. public const int SQLINT8 = 0x7f; public const int SQLVARIANT = 0x62; - // The following datatypes are specific to 2005 (version 9) or later + // The following datatypes are specific to Yukon (version 9) or later public const int SQLXMLTYPE = 0xf1; public const int XMLUNICODEBOM = 0xfeff; public static readonly byte[] XMLUNICODEBOMBYTES = { 0xff, 0xfe }; - // The following datatypes are specific to 2008 (version 10) or later + // The following datatypes are specific to Katmai (version 10) or later public const int SQLTABLE = 0xf3; public const int SQLDATE = 0x28; public const int SQLTIME = 0x29; @@ -481,7 +481,7 @@ public enum ActiveDirectoryWorkflow : byte public const int DEFAULT_VARTIME_SCALE = 7; //Partially length prefixed datatypes constants. These apply to XMLTYPE, BIGVARCHRTYPE, - // NVARCHARTYPE, and BIGVARBINTYPE. Valid for 2005 or later + // NVARCHARTYPE, and BIGVARBINTYPE. Valid for Yukon or later public const ulong SQL_PLP_NULL = 0xffffffffffffffff; // Represents null value public const ulong SQL_PLP_UNKNOWNLEN = 0xfffffffffffffffe; // Data coming in chunks, total length unknown @@ -552,8 +552,8 @@ public enum ActiveDirectoryWorkflow : byte public const string TRANS_SNAPSHOT = "SET TRANSACTION ISOLATION LEVEL SNAPSHOT"; // Batch RPC flags - public const byte SQL2000_RPCBATCHFLAG = 0x80; - public const byte SQL2005_RPCBATCHFLAG = 0xFF; + public const byte SHILOH_RPCBATCHFLAG = 0x80; + public const byte YUKON_RPCBATCHFLAG = 0xFF; // RPC flags public const byte RPC_RECOMPILE = 0x1; diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/VirtualSecureModeEnclaveProviderBase.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/VirtualSecureModeEnclaveProviderBase.cs index 6c940e3749..f71047d965 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/VirtualSecureModeEnclaveProviderBase.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/VirtualSecureModeEnclaveProviderBase.cs @@ -22,7 +22,7 @@ internal abstract class VirtualizationBasedSecurityEnclaveProviderBase : Enclave #region Constants private const int DiffieHellmanKeySize = 384; - private const int VsmHGSProtocolId = (int)SqlConnectionAttestationProtocol.HGS; + private const int VsmHGSProtocolId = 3; // ENCLAVE_IDENTITY related constants private static readonly EnclaveIdentity ExpectedPolicy = new EnclaveIdentity() @@ -95,7 +95,7 @@ internal override void GetEnclaveSession(EnclaveSessionParameters enclaveSession internal override SqlEnclaveAttestationParameters GetAttestationParameters(string attestationUrl, byte[] customData, int customDataLength) { ECDiffieHellman clientDHKey = KeyConverter.CreateECDiffieHellman(DiffieHellmanKeySize); - return new SqlEnclaveAttestationParameters(VsmHGSProtocolId, Array.Empty(), clientDHKey); + return new SqlEnclaveAttestationParameters(VsmHGSProtocolId, new byte[] { }, clientDHKey); } // When overridden in a derived class, performs enclave attestation, generates a symmetric key for the session, creates a an enclave session and stores the session information in the cache. diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/AlwaysEncryptedTests/ExceptionRegisterKeyStoreProvider.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/AlwaysEncryptedTests/ExceptionRegisterKeyStoreProvider.cs index 4c62013843..dfec766011 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/AlwaysEncryptedTests/ExceptionRegisterKeyStoreProvider.cs +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/AlwaysEncryptedTests/ExceptionRegisterKeyStoreProvider.cs @@ -85,24 +85,21 @@ public void TestEmptyProviderName() [Fact] public void TestCanSetGlobalProvidersOnlyOnce() { - lock (Utility.ClearSqlConnectionGlobalProvidersLock) - { - Utility.ClearSqlConnectionGlobalProviders(); + Utility.ClearSqlConnectionGlobalProviders(); - IDictionary customProviders = - new Dictionary() - { + IDictionary customProviders = + new Dictionary() + { { DummyKeyStoreProvider.Name, new DummyKeyStoreProvider() } - }; - SqlConnection.RegisterColumnEncryptionKeyStoreProviders(customProviders); + }; + SqlConnection.RegisterColumnEncryptionKeyStoreProviders(customProviders); - InvalidOperationException e = Assert.Throws( - () => SqlConnection.RegisterColumnEncryptionKeyStoreProviders(customProviders)); - string expectedMessage = SystemDataResourceManager.Instance.TCE_CanOnlyCallOnce; - Assert.Contains(expectedMessage, e.Message); + InvalidOperationException e = Assert.Throws( + () => SqlConnection.RegisterColumnEncryptionKeyStoreProviders(customProviders)); + string expectedMessage = SystemDataResourceManager.Instance.TCE_CanOnlyCallOnce; + Assert.Contains(expectedMessage, e.Message); - Utility.ClearSqlConnectionGlobalProviders(); - } + Utility.ClearSqlConnectionGlobalProviders(); } [Fact] diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/AlwaysEncryptedTests/ExceptionsAlgorithmErrors.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/AlwaysEncryptedTests/ExceptionsAlgorithmErrors.cs index e2d8e02b0b..7395816fb1 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/AlwaysEncryptedTests/ExceptionsAlgorithmErrors.cs +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/AlwaysEncryptedTests/ExceptionsAlgorithmErrors.cs @@ -82,7 +82,7 @@ public void TestInvalidCipherText() [PlatformSpecific(TestPlatforms.Windows)] public void TestInvalidAlgorithmVersion() { - string expectedMessage = string.Format(SystemDataResourceManager.Instance.TCE_InvalidAlgorithmVersion, + string expectedMessage = string.Format(SystemDataResourceManager.Instance.TCE_InvalidAlgorithmVersion, 40, "01"); byte[] plainText = Encoding.Unicode.GetBytes("Hello World"); byte[] cipherText = EncryptDataUsingAED(plainText, CertFixture.cek, CColumnEncryptionType.Deterministic); @@ -112,7 +112,7 @@ public void TestInvalidAuthenticationTag() [PlatformSpecific(TestPlatforms.Windows)] public void TestNullColumnEncryptionAlgorithm() { - string expectedMessage = string.Format(SystemDataResourceManager.Instance.TCE_NullColumnEncryptionAlgorithm, + string expectedMessage = string.Format(SystemDataResourceManager.Instance.TCE_NullColumnEncryptionAlgorithm, "'AEAD_AES_256_CBC_HMAC_SHA256'"); Object cipherMD = GetSqlCipherMetadata(0, 0, null, 1, 0x01); AddEncryptionKeyToCipherMD(cipherMD, CertFixture.encryptedCek, 0, 0, 0, new byte[] { 0x01, 0x02, 0x03 }, CertFixture.certificatePath, "MSSQL_CERTIFICATE_STORE", "RSA_OAEP"); @@ -148,27 +148,24 @@ public void TestUnknownEncryptionAlgorithmId() [PlatformSpecific(TestPlatforms.Windows)] public void TestUnknownCustomKeyStoreProvider() { - lock (Utility.ClearSqlConnectionGlobalProvidersLock) - { - // Clear out the existing providers (to ensure test reliability) - ClearSqlConnectionGlobalProviders(); - - const string invalidProviderName = "Dummy_Provider"; - string expectedMessage = string.Format(SystemDataResourceManager.Instance.TCE_UnrecognizedKeyStoreProviderName, - invalidProviderName, "'MSSQL_CERTIFICATE_STORE', 'MSSQL_CNG_STORE', 'MSSQL_CSP_PROVIDER'", ""); - Object cipherMD = GetSqlCipherMetadata(0, 1, null, 1, 0x03); - AddEncryptionKeyToCipherMD(cipherMD, CertFixture.encryptedCek, 0, 0, 0, new byte[] { 0x01, 0x02, 0x03 }, CertFixture.certificatePath, invalidProviderName, "RSA_OAEP"); - byte[] plainText = Encoding.Unicode.GetBytes("HelloWorld"); - byte[] cipherText = EncryptDataUsingAED(plainText, CertFixture.cek, CColumnEncryptionType.Deterministic); + // Clear out the existing providers (to ensure test reliability) + ClearSqlConnectionGlobalProviders(); + + const string invalidProviderName = "Dummy_Provider"; + string expectedMessage = string.Format(SystemDataResourceManager.Instance.TCE_UnrecognizedKeyStoreProviderName, + invalidProviderName, "'MSSQL_CERTIFICATE_STORE', 'MSSQL_CNG_STORE', 'MSSQL_CSP_PROVIDER'", ""); + Object cipherMD = GetSqlCipherMetadata(0, 1, null, 1, 0x03); + AddEncryptionKeyToCipherMD(cipherMD, CertFixture.encryptedCek, 0, 0, 0, new byte[] { 0x01, 0x02, 0x03 }, CertFixture.certificatePath, invalidProviderName, "RSA_OAEP"); + byte[] plainText = Encoding.Unicode.GetBytes("HelloWorld"); + byte[] cipherText = EncryptDataUsingAED(plainText, CertFixture.cek, CColumnEncryptionType.Deterministic); - Exception decryptEx = Assert.Throws(() => DecryptWithKey(plainText, cipherMD)); - Assert.Contains(expectedMessage, decryptEx.InnerException.Message); + Exception decryptEx = Assert.Throws(() => DecryptWithKey(plainText, cipherMD)); + Assert.Contains(expectedMessage, decryptEx.InnerException.Message); - Exception encryptEx = Assert.Throws(() => EncryptWithKey(plainText, cipherMD)); - Assert.Contains(expectedMessage, encryptEx.InnerException.Message); + Exception encryptEx = Assert.Throws(() => EncryptWithKey(plainText, cipherMD)); + Assert.Contains(expectedMessage, encryptEx.InnerException.Message); - ClearSqlConnectionGlobalProviders(); - } + ClearSqlConnectionGlobalProviders(); } [Fact] @@ -176,7 +173,7 @@ public void TestUnknownCustomKeyStoreProvider() public void TestTceUnknownEncryptionAlgorithm() { const string unknownEncryptionAlgorithm = "Dummy"; - string expectedMessage = string.Format(SystemDataResourceManager.Instance.TCE_UnknownColumnEncryptionAlgorithm, + string expectedMessage = string.Format(SystemDataResourceManager.Instance.TCE_UnknownColumnEncryptionAlgorithm, unknownEncryptionAlgorithm, "'AEAD_AES_256_CBC_HMAC_SHA256'"); Object cipherMD = GetSqlCipherMetadata(0, 0, "Dummy", 1, 0x01); AddEncryptionKeyToCipherMD(cipherMD, CertFixture.encryptedCek, 0, 0, 0, new byte[] { 0x01, 0x02, 0x03 }, CertFixture.certificatePath, "MSSQL_CERTIFICATE_STORE", "RSA_OAEP"); @@ -196,7 +193,7 @@ public void TestExceptionsFromCertStore() { byte[] corruptedCek = GenerateInvalidEncryptedCek(CertFixture.cek, ECEKCorruption.SIGNATURE); - string expectedMessage = string.Format(SystemDataResourceManager.Instance.TCE_KeyDecryptionFailedCertStore, + string expectedMessage = string.Format(SystemDataResourceManager.Instance.TCE_KeyDecryptionFailedCertStore, "MSSQL_CERTIFICATE_STORE", BitConverter.ToString(corruptedCek, corruptedCek.Length - 10, 10)); Object cipherMD = GetSqlCipherMetadata(0, 1, null, 1, 0x01); @@ -212,30 +209,27 @@ public void TestExceptionsFromCertStore() [PlatformSpecific(TestPlatforms.Windows)] public void TestExceptionsFromCustomKeyStore() { - lock (Utility.ClearSqlConnectionGlobalProvidersLock) - { - string expectedMessage = "Failed to decrypt a column encryption key"; + string expectedMessage = "Failed to decrypt a column encryption key"; - // Clear out the existing providers (to ensure test reliability) - ClearSqlConnectionGlobalProviders(); + // Clear out the existing providers (to ensure test reliability) + ClearSqlConnectionGlobalProviders(); - IDictionary customProviders = new Dictionary(); - customProviders.Add(DummyKeyStoreProvider.Name, new DummyKeyStoreProvider()); - SqlConnection.RegisterColumnEncryptionKeyStoreProviders(customProviders); + IDictionary customProviders = new Dictionary(); + customProviders.Add(DummyKeyStoreProvider.Name, new DummyKeyStoreProvider()); + SqlConnection.RegisterColumnEncryptionKeyStoreProviders(customProviders); - object cipherMD = GetSqlCipherMetadata(0, 1, null, 1, 0x01); - AddEncryptionKeyToCipherMD(cipherMD, CertFixture.encryptedCek, 0, 0, 0, new byte[] { 0x01, 0x02, 0x03 }, CertFixture.certificatePath, "DummyProvider", "DummyAlgo"); - byte[] plainText = Encoding.Unicode.GetBytes("HelloWorld"); - byte[] cipherText = EncryptDataUsingAED(plainText, CertFixture.cek, CColumnEncryptionType.Deterministic); + object cipherMD = GetSqlCipherMetadata(0, 1, null, 1, 0x01); + AddEncryptionKeyToCipherMD(cipherMD, CertFixture.encryptedCek, 0, 0, 0, new byte[] { 0x01, 0x02, 0x03 }, CertFixture.certificatePath, "DummyProvider", "DummyAlgo"); + byte[] plainText = Encoding.Unicode.GetBytes("HelloWorld"); + byte[] cipherText = EncryptDataUsingAED(plainText, CertFixture.cek, CColumnEncryptionType.Deterministic); - Exception decryptEx = Assert.Throws(() => DecryptWithKey(cipherText, cipherMD)); - Assert.Contains(expectedMessage, decryptEx.InnerException.Message); + Exception decryptEx = Assert.Throws(() => DecryptWithKey(cipherText, cipherMD)); + Assert.Contains(expectedMessage, decryptEx.InnerException.Message); - Exception encryptEx = Assert.Throws(() => EncryptWithKey(cipherText, cipherMD)); - Assert.Contains(expectedMessage, encryptEx.InnerException.Message); + Exception encryptEx = Assert.Throws(() => EncryptWithKey(cipherText, cipherMD)); + Assert.Contains(expectedMessage, encryptEx.InnerException.Message); - ClearSqlConnectionGlobalProviders(); - } + ClearSqlConnectionGlobalProviders(); } } diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/AlwaysEncryptedTests/SqlColumnEncryptionCertificateStoreProviderShould.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/AlwaysEncryptedTests/SqlColumnEncryptionCertificateStoreProviderShould.cs index b0c6297cda..54dd6bc6be 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/AlwaysEncryptedTests/SqlColumnEncryptionCertificateStoreProviderShould.cs +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/AlwaysEncryptedTests/SqlColumnEncryptionCertificateStoreProviderShould.cs @@ -92,6 +92,11 @@ public class SqlColumnEncryptionCertificateStoreProviderWindowsShould : IClassFi /// private const int CipherTextStartIndex = IVStartIndex + IVLengthInBytes; + /// + /// SetCustomColumnEncryptionKeyStoreProvider can be called only once in a process. To workaround that, we use this flag. + /// + private static bool s_testCustomEncryptioKeyStoreProviderExecutedOnce = false; + [Theory] [InvalidDecryptionParameters] [PlatformSpecific(TestPlatforms.Windows)] @@ -321,51 +326,55 @@ public void TestAeadEncryptionReversal(string dataType, object data, Utility.CCo [PlatformSpecific(TestPlatforms.Windows)] public void TestCustomKeyProviderListSetter() { - lock (Utility.ClearSqlConnectionGlobalProvidersLock) + // SqlConnection.RegisterColumnEncryptionKeyStoreProviders can be called only once in a process. + // This is a workaround to ensure re-runnability of the test. + if (s_testCustomEncryptioKeyStoreProviderExecutedOnce) { - string expectedMessage1 = "Column encryption key store provider dictionary cannot be null. Expecting a non-null value."; - // Verify that we are able to set it to null. - ArgumentException e1 = Assert.Throws(() => SqlConnection.RegisterColumnEncryptionKeyStoreProviders(null)); - Assert.Contains(expectedMessage1, e1.Message); - - // A dictionary holding custom providers. - IDictionary customProviders = new Dictionary(); - customProviders.Add(new KeyValuePair(@"DummyProvider", new DummyKeyStoreProvider())); - - // Verify that setting a provider in the list with null value throws an exception. - customProviders.Add(new KeyValuePair(@"CustomProvider", null)); - string expectedMessage2 = "Null reference specified for key store provider 'CustomProvider'. Expecting a non-null value."; - ArgumentNullException e2 = Assert.Throws(() => SqlConnection.RegisterColumnEncryptionKeyStoreProviders(customProviders)); - Assert.Contains(expectedMessage2, e2.Message); - customProviders.Remove(@"CustomProvider"); - - // Verify that setting a provider in the list with an empty provider name throws an exception. - customProviders.Add(new KeyValuePair(@"", new DummyKeyStoreProvider())); - string expectedMessage3 = "Invalid key store provider name specified. Key store provider names cannot be null or empty"; - ArgumentNullException e3 = Assert.Throws(() => SqlConnection.RegisterColumnEncryptionKeyStoreProviders(customProviders)); - Assert.Contains(expectedMessage3, e3.Message); - - customProviders.Remove(@""); - - // Verify that setting a provider in the list with name that starts with 'MSSQL_' throws an exception. - customProviders.Add(new KeyValuePair(@"MSSQL_MyStore", new SqlColumnEncryptionCertificateStoreProvider())); - string expectedMessage4 = "Invalid key store provider name 'MSSQL_MyStore'. 'MSSQL_' prefix is reserved for system key store providers."; - ArgumentException e4 = Assert.Throws(() => SqlConnection.RegisterColumnEncryptionKeyStoreProviders(customProviders)); - Assert.Contains(expectedMessage4, e4.Message); - - customProviders.Remove(@"MSSQL_MyStore"); - - // Verify that setting a provider in the list with name that starts with 'MSSQL_' but different case throws an exception. - customProviders.Add(new KeyValuePair(@"MsSqL_MyStore", new SqlColumnEncryptionCertificateStoreProvider())); - string expectedMessage5 = "Invalid key store provider name 'MsSqL_MyStore'. 'MSSQL_' prefix is reserved for system key store providers."; - ArgumentException e5 = Assert.Throws(() => SqlConnection.RegisterColumnEncryptionKeyStoreProviders(customProviders)); - Assert.Contains(expectedMessage5, e5.Message); - - customProviders.Remove(@"MsSqL_MyStore"); - - // Clear any providers set by other tests. - Utility.ClearSqlConnectionGlobalProviders(); + return; } + + string expectedMessage1 = "Column encryption key store provider dictionary cannot be null. Expecting a non-null value."; + // Verify that we are able to set it to null. + ArgumentException e1 = Assert.Throws(() => SqlConnection.RegisterColumnEncryptionKeyStoreProviders(null)); + Assert.Contains(expectedMessage1, e1.Message); + + // A dictionary holding custom providers. + IDictionary customProviders = new Dictionary(); + customProviders.Add(new KeyValuePair(@"DummyProvider", new DummyKeyStoreProvider())); + + // Verify that setting a provider in the list with null value throws an exception. + customProviders.Add(new KeyValuePair(@"CustomProvider", null)); + string expectedMessage2 = "Null reference specified for key store provider 'CustomProvider'. Expecting a non-null value."; + ArgumentNullException e2 = Assert.Throws(() => SqlConnection.RegisterColumnEncryptionKeyStoreProviders(customProviders)); + Assert.Contains(expectedMessage2, e2.Message); + customProviders.Remove(@"CustomProvider"); + + // Verify that setting a provider in the list with an empty provider name throws an exception. + customProviders.Add(new KeyValuePair(@"", new DummyKeyStoreProvider())); + string expectedMessage3 = "Invalid key store provider name specified. Key store provider names cannot be null or empty"; + ArgumentNullException e3 = Assert.Throws(() => SqlConnection.RegisterColumnEncryptionKeyStoreProviders(customProviders)); + Assert.Contains(expectedMessage3, e3.Message); + + customProviders.Remove(@""); + + // Verify that setting a provider in the list with name that starts with 'MSSQL_' throws an exception. + customProviders.Add(new KeyValuePair(@"MSSQL_MyStore", new SqlColumnEncryptionCertificateStoreProvider())); + string expectedMessage4 = "Invalid key store provider name 'MSSQL_MyStore'. 'MSSQL_' prefix is reserved for system key store providers."; + ArgumentException e4 = Assert.Throws(() => SqlConnection.RegisterColumnEncryptionKeyStoreProviders(customProviders)); + Assert.Contains(expectedMessage4, e4.Message); + + customProviders.Remove(@"MSSQL_MyStore"); + + // Verify that setting a provider in the list with name that starts with 'MSSQL_' but different case throws an exception. + customProviders.Add(new KeyValuePair(@"MsSqL_MyStore", new SqlColumnEncryptionCertificateStoreProvider())); + string expectedMessage5 = "Invalid key store provider name 'MsSqL_MyStore'. 'MSSQL_' prefix is reserved for system key store providers."; + ArgumentException e5 = Assert.Throws(() => SqlConnection.RegisterColumnEncryptionKeyStoreProviders(customProviders)); + Assert.Contains(expectedMessage5, e5.Message); + + customProviders.Remove(@"MsSqL_MyStore"); + + // Clear any providers set by other tests. + Utility.ClearSqlConnectionGlobalProviders(); } [Theory] @@ -493,7 +502,7 @@ public class CEKEncryptionReversalParameters : DataAttribute { public override IEnumerable GetData(MethodInfo testMethod) { - yield return new object[2] { StoreLocation.CurrentUser, CurrentUserMyPathPrefix }; + yield return new object[2] { StoreLocation.CurrentUser , CurrentUserMyPathPrefix }; // use localmachine cert path only when current user is Admin. if (CertificateFixture.IsAdmin) { diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/AlwaysEncryptedTests/Utility.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/AlwaysEncryptedTests/Utility.cs index 9f858a0fca..07e9e93146 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/AlwaysEncryptedTests/Utility.cs +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/AlwaysEncryptedTests/Utility.cs @@ -95,8 +95,8 @@ internal static byte[] GenerateRandomBytes(int length) { // Generate random bytes cryptographically. byte[] randomBytes = new byte[length]; - RandomNumberGenerator rng = RandomNumberGenerator.Create(); - rng.GetBytes(randomBytes); + RNGCryptoServiceProvider rngCsp = new RNGCryptoServiceProvider(); + rngCsp.GetBytes(randomBytes); return randomBytes; } @@ -348,9 +348,8 @@ internal static byte[] DecryptDataUsingAED(byte[] encryptedCellBlob, byte[] key, return decryptedData; } -#if NETFRAMEWORK /// - /// Create a self-signed certificate without private key. + /// Create a self-signed certificate without private key. NET461 only. /// internal static X509Certificate2 CreateCertificateWithNoPrivateKey() { @@ -377,7 +376,6 @@ internal static X509Certificate2 CreateCertificateWithNoPrivateKey() return certificate; } -#endif /// /// Gets hex representation of byte array. @@ -402,11 +400,9 @@ internal static string GetHexString(byte[] input, bool addLeadingZeroX = false) return str.ToString(); } - internal static object ClearSqlConnectionGlobalProvidersLock = new(); - /// /// Through reflection, clear the static provider list set on SqlConnection. - /// Note- Any test using this method should be wrapped in a lock statement using ClearSqlConnectionGlobalProvidersLock + /// Note- This API doesn't use locks for synchronization. /// internal static void ClearSqlConnectionGlobalProviders() { diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.Tests.csproj b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.Tests.csproj index 721d8a5c91..bc3e64f9f1 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.Tests.csproj +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.Tests.csproj @@ -28,8 +28,6 @@ - - @@ -46,11 +44,8 @@ - - - diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlClientFactoryTest.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlClientFactoryTest.cs index f0e8d39173..15b7222df9 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlClientFactoryTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlClientFactoryTest.cs @@ -3,8 +3,6 @@ // See the LICENSE file in the project root for more information. using System; -using System.Data.Sql; -using System.Reflection; using Xunit; namespace Microsoft.Data.SqlClient.Tests @@ -22,7 +20,6 @@ public void InstanceTest() public static readonly object[][] FactoryMethodTestData = { new object[] { new Func(SqlClientFactory.Instance.CreateCommand), typeof(SqlCommand) }, - new object[] { new Func(SqlClientFactory.Instance.CreateCommandBuilder), typeof(SqlCommandBuilder) }, new object[] { new Func(SqlClientFactory.Instance.CreateConnection), typeof(SqlConnection) }, new object[] { new Func(SqlClientFactory.Instance.CreateConnectionStringBuilder), typeof(SqlConnectionStringBuilder) }, new object[] { new Func(SqlClientFactory.Instance.CreateDataAdapter), typeof(SqlDataAdapter) }, @@ -43,26 +40,5 @@ public void FactoryMethodTest(Func factory, Type expectedType) Assert.NotSame(value1, value2); } - -#if NETFRAMEWORK - [Fact] - public void FactoryCreateDataSourceEnumerator() - { - // Unable to cover the in the FactoryMethodTest because the SqlDataSourceEnumerator is a singleton so, it's always the same. - object instance = SqlClientFactory.Instance.CreateDataSourceEnumerator(); - // SqlDataSourceEnumerator is not available for .NET core 3.1 and above, so the type check is only for .NET Framework. - Assert.IsType(instance); - Assert.NotNull(instance); - } - - [Fact] - public void FactoryGetService() - { - Type type = typeof(SqlClientFactory); - MethodInfo method = type.GetMethod("System.IServiceProvider.GetService", BindingFlags.NonPublic | BindingFlags.Instance); - object res = method.Invoke(SqlClientFactory.Instance, new object[] { null }); - Assert.Null(res); - } -#endif } } diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlClientLoggerTest.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlClientLoggerTest.cs deleted file mode 100644 index 3617882b42..0000000000 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlClientLoggerTest.cs +++ /dev/null @@ -1,40 +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. - -using Xunit; - -namespace Microsoft.Data.SqlClient.Tests -{ - public class SqlClientLoggerTest - { - [Fact] - public void LogWarning() - { - // There is not much to test here but to add the code coverage. - SqlClientLogger logger = new(); - logger.LogWarning("test type", "test method", "test message"); - } - - [Fact] - public void LogAssert() - { - SqlClientLogger logger = new(); - logger.LogAssert(true, "test type", "test method", "test message"); - } - - [Fact] - public void LogError() - { - SqlClientLogger logger = new(); - logger.LogError("test type", "test method", "test message"); - } - - [Fact] - public void LogInfo() - { - SqlClientLogger logger = new(); - logger.LogInfo("test type", "test method", "test message"); - } - } -} diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlCommandBuilderTest.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlCommandBuilderTest.cs index a237c1579b..75e6dadf29 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlCommandBuilderTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlCommandBuilderTest.cs @@ -3,11 +3,8 @@ // See the LICENSE file in the project root for more information. using System; -using System.Collections.Generic; using System.Data; using System.Data.Common; -using System.Reflection; -using System.Threading; using Xunit; namespace Microsoft.Data.SqlClient.Tests @@ -67,8 +64,6 @@ public void CatalogSeparator() { SqlCommandBuilder cb = new SqlCommandBuilder(); Assert.Equal(".", cb.CatalogSeparator); - cb.CatalogSeparator = "."; - Assert.Equal(".", cb.CatalogSeparator); } [Theory] @@ -129,23 +124,6 @@ public void ConflictOption_Value_Invalid() Assert.Equal(ConflictOption.CompareRowVersion, cb.ConflictOption); } - [Fact] - public void DataAdapter() - { - SqlCommandBuilder cb = new SqlCommandBuilder(); - Assert.Null(cb.DataAdapter); - - cb.DataAdapter = new SqlDataAdapter(); - Assert.NotNull(cb.DataAdapter); - } - - [Theory] - [MemberData(nameof(SqlTestCommands))] - public void DeriveParameters_Throws(Type ex, SqlCommand command) - { - Assert.Throws(ex, () => SqlCommandBuilder.DeriveParameters(command)); - } - [Fact] public void QuoteIdentifier() { @@ -345,19 +323,5 @@ public void SchemaSeparator_Value_Invalid(string separator) Assert.Null(ex.ParamName); } } - - #region member data - public static IEnumerable SqlTestCommands => - new List - { - new object[] { typeof(ArgumentNullException), null }, - /* TODO: may need a MOQ class for DbCommand to override the DeriveParameters to throw these exceptions - new object[] { typeof(OutOfMemoryException), new SqlCommand() }, - new object[] { typeof(StackOverflowException), new SqlCommand() }, - new object[] { typeof(ThreadAbortException), new SqlCommand() }, - new object[] { typeof(Exception), new SqlCommand() } - */ - }; - #endregion } } diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlCommandSetTest.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlCommandSetTest.cs deleted file mode 100644 index 1428bcc3e8..0000000000 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlCommandSetTest.cs +++ /dev/null @@ -1,182 +0,0 @@ -using System; -using System.Data; -using System.Reflection; -using Xunit; - -namespace Microsoft.Data.SqlClient.Tests -{ - public class SqlCommandSetTest - { - private static Assembly mds = Assembly.GetAssembly(typeof(SqlConnection)); - - [Theory] - [InlineData("BatchCommand")] - [InlineData("CommandList")] - public void GetDisposedProperty_Throws(string propertyName) - { - var cmdSet = CreateInstance(); - CallMethod(cmdSet, "Dispose"); - Exception ex = GetProperty_Throws(cmdSet, propertyName); - VerifyException(ex, "disposed"); - } - - [Fact] - public void AppendCommandWithEmptyString_Throws() - { - var cmdSet = CreateInstance(); - SqlCommand cmd = new SqlCommand(""); - Exception ex = CallMethod_Throws(cmdSet, "Append", cmd); - VerifyException(ex, "CommandText property has not been initialized"); - } - - [Theory] - [InlineData(CommandType.TableDirect)] - [InlineData((CommandType)5)] - public void AppendBadCommandType_Throws(CommandType commandType) - { - var cmdSet = CreateInstance(); - SqlCommand cmd = GenerateBadCommand(commandType); - Exception ex = CallMethod_Throws(cmdSet, "Append", cmd); - VerifyException(ex, "CommandType"); - } - - [Fact] - public void AppendBadParameterName_Throws() - { - var cmdSet = CreateInstance(); - SqlCommand cmd = new SqlCommand("Test"); - cmd.CommandType = CommandType.Text; - cmd.Parameters.Add(new SqlParameter("Test1;=", "1")); - Exception ex = CallMethod_Throws(cmdSet, "Append", cmd); - VerifyException(ex, "not valid"); - } - - [Theory] - [InlineData(new byte[] { 1, 2, 3 })] - [InlineData(new char[] { '1', '2', '3' })] - public void AppendParameterArrayWithSize(object array) - { - var cmdSet = CreateInstance(); - SqlCommand cmd = new SqlCommand("Test"); - cmd.CommandType = CommandType.StoredProcedure; - SqlParameter parameter = new SqlParameter("@array", array); - parameter.Size = 2; - cmd.Parameters.Add(parameter); - CallMethod(cmdSet, "Append", cmd); - object p = CallMethod(cmdSet, "GetParameter", 0, 0); - SqlParameter result = p as SqlParameter; - Assert.NotNull(result); - Assert.Equal("@array", result.ParameterName); - Assert.Equal(2, result.Size); - } - - [Fact] - public void GetParameter() - { - var cmdSet = CreateInstance(); - SqlCommand cmd = new SqlCommand("Test"); - cmd.CommandType = CommandType.Text; - cmd.Parameters.Add(new SqlParameter("@text", "value")); - CallMethod(cmdSet, "Append", cmd); - object p = CallMethod(cmdSet, "GetParameter", 0, 0); - SqlParameter result = p as SqlParameter; - Assert.NotNull(result); - Assert.Equal("@text", result.ParameterName); - Assert.Equal("value", (string)result.Value); - } - - [Fact] - public void GetParameterCount() - { - var commandSetType = mds.GetType("Microsoft.Data.SqlClient.SqlCommandSet"); - var cmdSet = Activator.CreateInstance(commandSetType, true); - SqlCommand cmd = new SqlCommand("Test"); - cmd.CommandType = CommandType.Text; - cmd.Parameters.Add(new SqlParameter("@abc", "1")); - cmd.Parameters.Add(new SqlParameter("@test", "2")); - commandSetType.GetMethod("Append", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).Invoke(cmdSet, new object[] { cmd }); - int index = 0; - int count = (int)commandSetType.GetMethod("GetParameterCount", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).Invoke(cmdSet, new object[] { index }); - Assert.Equal(2, count); - } - - [Fact] - public void InvalidCommandBehaviorValidateCommandBehavior_Throws() - { - var cmdSet = CreateInstance(); - Exception ex = CallMethod_Throws(cmdSet, "ValidateCommandBehavior", "ExecuteNonQuery", (CommandBehavior)64); - VerifyException(ex, "CommandBehavior"); - } - - [Fact] - public void NotSupportedCommandBehaviorValidateCommandBehavior_Throws() - { - var cmdSet = CreateInstance(); - Exception ex = CallMethod_Throws(cmdSet, "ValidateCommandBehavior", "ExecuteNonQuery", CommandBehavior.KeyInfo); - VerifyException(ex, "not supported"); - } - - #region private methods - - private object CallMethod(object instance, string methodName, params object[] values) - { - var commandSetType = mds.GetType("Microsoft.Data.SqlClient.SqlCommandSet"); - object returnValue = commandSetType.GetMethod(methodName, System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).Invoke(instance, values); - return returnValue; - } - - private object CallMethod(object instance, string methodName) - { - var commandSetType = mds.GetType("Microsoft.Data.SqlClient.SqlCommandSet"); - object returnValue = commandSetType.GetMethod(methodName, System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).Invoke(instance, new object[] { }); - return returnValue; - } - - private Exception CallMethod_Throws(object instance, string methodName, params object[] values) - { - var commandSetType = mds.GetType("Microsoft.Data.SqlClient.SqlCommandSet"); - Exception ex = Assert.ThrowsAny(() => - { - commandSetType.GetMethod(methodName, System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).Invoke(instance, values); - }); - return ex; - } - - private object CreateInstance() - { - var commandSetType = mds.GetType("Microsoft.Data.SqlClient.SqlCommandSet"); - object cmdSet = Activator.CreateInstance(commandSetType, true); - return cmdSet; - } - - private Exception GetProperty_Throws(object instance, string propertyName) - { - var commandSetType = mds.GetType("Microsoft.Data.SqlClient.SqlCommandSet"); - var cmdSet = instance; - Exception ex = Assert.ThrowsAny(() => - { - commandSetType.GetProperty(propertyName, System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).GetGetMethod(true).Invoke(cmdSet, new object[] { }); - }); - - return ex; - } - - private SqlCommand GenerateBadCommand(CommandType cType) - { - SqlCommand cmd = new SqlCommand("Test"); - Type sqlCommandType = cmd.GetType(); - // There's validation done on the CommandType property, but we need to create one that avoids the check for the test case. - sqlCommandType.GetField("_commandType", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(cmd, cType); - - return cmd; - } - - private void VerifyException(Exception ex, string contains) - { - Assert.NotNull(ex); - Assert.IsType(ex.InnerException); - Assert.Contains(contains, ex.InnerException.Message, StringComparison.OrdinalIgnoreCase); - } - #endregion - } -} diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionStringBuilderTest.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionStringBuilderTest.cs index d80875af80..bf08250e83 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionStringBuilderTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionStringBuilderTest.cs @@ -101,166 +101,6 @@ public void ConnectionStringTestsNetFx(string connectionString) ExecuteConnectionStringTests(connectionString); } - [Fact] - public void SetInvalidApplicationIntent_Throws() - { - SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(); - - ApplicationIntent invalid = (ApplicationIntent)Enum.GetValues(typeof(ApplicationIntent)).Length + 1; - ArgumentOutOfRangeException ex = Assert.Throws(() => builder.ApplicationIntent = invalid); - Assert.Contains("ApplicationIntent", ex.Message, StringComparison.OrdinalIgnoreCase); - } - - [Fact] - public void SetInvalidAttestationProtocol_Throws() - { - SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(); - - SqlConnectionAttestationProtocol invalid = (SqlConnectionAttestationProtocol)Enum.GetValues(typeof(SqlConnectionAttestationProtocol)).Length + 1; - ArgumentOutOfRangeException ex = Assert.Throws(() => builder.AttestationProtocol = invalid); - Assert.Contains("SqlConnectionAttestationProtocol", ex.Message, StringComparison.OrdinalIgnoreCase); - } - - [Fact] - public void SetInvalidAuthentication_Throws() - { - SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(); - - SqlAuthenticationMethod invalid = (SqlAuthenticationMethod)Enum.GetValues(typeof(SqlAuthenticationMethod)).Length + 1; - ArgumentOutOfRangeException ex = Assert.Throws(() => builder.Authentication = invalid); - Assert.Contains("SqlAuthenticationMethod", ex.Message, StringComparison.OrdinalIgnoreCase); - } - - [Fact] - public void SetInvalidColumnEncryptionSetting_Throws() - { - SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(); - - SqlConnectionColumnEncryptionSetting invalid = (SqlConnectionColumnEncryptionSetting)Enum.GetValues(typeof(SqlConnectionColumnEncryptionSetting)).Length + 1; - ArgumentOutOfRangeException ex = Assert.Throws(() => builder.ColumnEncryptionSetting = invalid); - Assert.Contains("SqlConnectionColumnEncryptionSetting", ex.Message, StringComparison.OrdinalIgnoreCase); - } - - [Fact] - public void SetInvalidConnectTimeout_Throws() - { - SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(); - - ArgumentException ex = Assert.Throws(() => builder.ConnectTimeout = -1); - Assert.Contains("connect timeout", ex.Message, StringComparison.OrdinalIgnoreCase); - } - - [Fact] - public void SetInvalidCommandTimeout_Throws() - { - SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(); - - ArgumentException ex = Assert.Throws(() => builder.CommandTimeout = -1); - Assert.Contains("command timeout", ex.Message, StringComparison.OrdinalIgnoreCase); - } - - [Theory] - [InlineData(-1)] - [InlineData(256)] - public void SetInvalidConnectRetryCount_Throws(int invalid) - { - SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(); - - ArgumentException ex = Assert.Throws(() => builder.ConnectRetryCount = invalid); - Assert.Contains("connect retry count", ex.Message, StringComparison.OrdinalIgnoreCase); - } - - [Theory] - [InlineData(-1)] - [InlineData(256)] - public void SetInvalidConnectRetryInterval_Throws(int invalid) - { - SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(); - - ArgumentException ex = Assert.Throws(() => builder.ConnectRetryInterval = invalid); - Assert.Contains("connect retry interval", ex.Message, StringComparison.OrdinalIgnoreCase); - } - - [Fact] - public void SetInvalidIPAddressPreference_Throws() - { - SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(); - - SqlConnectionIPAddressPreference invalid = (SqlConnectionIPAddressPreference)Enum.GetValues(typeof(SqlConnectionIPAddressPreference)).Length + 1; - ArgumentOutOfRangeException ex = Assert.Throws(() => builder.IPAddressPreference = invalid); - Assert.Contains("SqlConnectionIPAddressPreference", ex.Message, StringComparison.OrdinalIgnoreCase); - } - - [Fact] - public void SetInvalidPoolBlockingPeriod_Throws() - { - SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(); - - PoolBlockingPeriod invalid = (PoolBlockingPeriod)Enum.GetValues(typeof(PoolBlockingPeriod)).Length + 1; - ArgumentOutOfRangeException ex = Assert.Throws(() => builder.PoolBlockingPeriod = invalid); - Assert.Contains("PoolBlockingPeriod", ex.Message, StringComparison.OrdinalIgnoreCase); - } - - [Fact] - public void SetInvalidLoadBalanceTimeout_Throws() - { - SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(); - - ArgumentException ex = Assert.Throws(() => builder.LoadBalanceTimeout = -1); - Assert.Contains("load balance timeout", ex.Message, StringComparison.OrdinalIgnoreCase); - } - - [Fact] - public void SetInvalidMaxPoolSize_Throws() - { - SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(); - - ArgumentException ex = Assert.Throws(() => builder.MaxPoolSize = 0); - Assert.Contains("max pool size", ex.Message, StringComparison.OrdinalIgnoreCase); - } - - [Fact] - public void SetInvalidMinPoolSize_Throws() - { - SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(); - - ArgumentException ex = Assert.Throws(() => builder.MinPoolSize = -1); - Assert.Contains("min pool size", ex.Message, StringComparison.OrdinalIgnoreCase); - } - - [Theory] - [InlineData(0)] - [InlineData(511)] - [InlineData(32769)] - [InlineData(int.MaxValue)] - public void SetInvalidPacketSize_Throws(int invalid) - { - SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(); - - ArgumentException ex = Assert.Throws(() => builder.PacketSize = invalid); - Assert.Contains("packet size", ex.Message, StringComparison.OrdinalIgnoreCase); - } - - [Theory] - [InlineData("AttachDBFilename","somefile.db")] - public void SetKeyword(string keyword, string value) - { - SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(); - builder[keyword] = value; - Assert.Equal(builder[keyword], value); - } - - [Fact] - public void SetNotSupportedKeyword_Throws() - { - // We may want to remove the unreachable code path for default in the GetIndex(keyword) method already throws UnsupportedKeyword - // so default: throw UnsupportedKeyword(keyword) is never reached unless it's a supported keyword, but it's not handled in the switch case. - - SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(); - ArgumentException ex = Assert.Throws(() => builder["NotSupported"] = "not important"); - Assert.Contains("not supported", ex.Message, StringComparison.OrdinalIgnoreCase); - } - [Fact] public void UnexpectedKeywordRetrieval() { diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlErrorTest.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlErrorTest.cs deleted file mode 100644 index 7c9208ac2a..0000000000 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlErrorTest.cs +++ /dev/null @@ -1,71 +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. - -using System; -using System.IO; -using System.Reflection; -using System.Runtime.Serialization.Formatters.Binary; -using Xunit; - -namespace Microsoft.Data.SqlClient.Tests -{ - public class SqlErrorTest - { - private const string SQLMSF_FailoverPartnerNotSupported = - "Connecting to a mirrored SQL Server instance using the MultiSubnetFailover connection option is not supported."; - private const byte FATAL_ERROR_CLASS = 20; - -#if !NET50_OR_LATER - [Fact] - public static void SqlErrorSerializationTest() - { - var formatter = new BinaryFormatter(); - SqlError expected = CreateError(); - SqlError actual = null; - using (var stream = new MemoryStream()) - { - try - { - formatter.Serialize(stream, expected); - stream.Position = 0; - actual = (SqlError)formatter.Deserialize(stream); - } - catch (Exception ex) - { - Assert.False(true, $"Unexpected Exception occurred: {ex.Message}"); - } - } - - Assert.Equal(expected.Message, actual.Message); - Assert.Equal(expected.Number, actual.Number); - Assert.Equal(expected.State, actual.State); - Assert.Equal(expected.Class, actual.Class); - Assert.Equal(expected.Server, actual.Server); - Assert.Equal(expected.Procedure, actual.Procedure); - Assert.Equal(expected.LineNumber, actual.LineNumber); - Assert.Equal(expected.Source, actual.Source); - } -#endif - - - private static SqlError CreateError() - { - string msg = SQLMSF_FailoverPartnerNotSupported; - - Type sqlErrorType = typeof(SqlError); - - // SqlError only has internal constructors, in order to instantiate this, we use reflection - SqlError sqlError = (SqlError)sqlErrorType.Assembly.CreateInstance( - sqlErrorType.FullName, - false, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new object[] { 100, (byte)0x00, FATAL_ERROR_CLASS, "ServerName", msg, "ProcedureName", 10, null }, - null, - null); - - return sqlError; - } - } -} diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlMetaDataTest.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlMetaDataTest.cs index d2306431f4..ae2e46da74 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlMetaDataTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlMetaDataTest.cs @@ -2,11 +2,7 @@ // 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; using System.Data; -using System.Data.SqlTypes; -using System.Globalization; -using System.Reflection; using Microsoft.Data.SqlClient.Server; using Xunit; @@ -14,687 +10,6 @@ namespace Microsoft.Data.SqlClient.Tests { public class SqlMetaDataTest { - [Theory] - [MemberData(nameof(SqlMetaDataAdjustValues))] - [MemberData(nameof(SqlMetaDataDateTimeValues))] - public void Adjust(SqlDbType dbType, object expected) - { - SqlMetaData metaData = new SqlMetaData( - "col1", - dbType, - 4, - 2, - 2, - 0, - SqlCompareOptions.IgnoreCase, - null, - true, - true, - SortOrder.Ascending, - 0); - object actual = metaData.Adjust(expected); - Assert.Equal(expected, actual); - } - - [Theory] - [MemberData(nameof(SqlMetaDataMaxLengthTrimValues))] - public void AdjustWithGreaterThanMaxLengthValues(SqlDbType dbType, object value) - { - int maxLength = 4; - SqlMetaData metaData = new SqlMetaData( - "col1", - dbType, - maxLength, - 2, - 2, - 0, - SqlCompareOptions.IgnoreCase, - null, - true, - true, - SortOrder.Ascending, - 0); - object actual = metaData.Adjust(value); - Assert.NotEqual(value, actual); - } - - [Theory] - [MemberData(nameof(SqlMetaDataInvalidValues))] - public void AdjustWithInvalidType_Throws(SqlDbType dbType, object expected) - { - SqlMetaData metaData = new SqlMetaData( - "col1", - dbType, - 4, - 2, - 2, - 0, - SqlCompareOptions.IgnoreCase, - null, - true, - true, - SortOrder.Ascending, - 0); - ArgumentException ex = Assert.ThrowsAny(() => - { - object actual = metaData.Adjust(expected); - }); - Assert.Contains("invalid", ex.Message, StringComparison.OrdinalIgnoreCase); - } - - - [Fact] - public void AdjustWithNullBytes() - { - SqlMetaData metaData = new SqlMetaData( - "col1", - SqlDbType.Binary, - 4, - 2, - 2, - 0, - SqlCompareOptions.IgnoreCase, - null, - true, - true, - SortOrder.Ascending, - 0); - - byte[] array = null; - object actual = metaData.Adjust(array); - Assert.Null(actual); - } - - [Fact] - public void AdjustWithNullChars() - { - SqlMetaData metaData = new SqlMetaData( - "col1", - SqlDbType.VarChar, - 4, - 2, - 2, - 0, - SqlCompareOptions.IgnoreCase, - null, - true, - true, - SortOrder.Ascending, - 0); - - char[] array = null; - object actual = metaData.Adjust(array); - Assert.Null(actual); - } - - [Fact] - public void AdjustWithNullString() - { - SqlMetaData metaData = new SqlMetaData( - "col1", - SqlDbType.VarChar, - 4, - 2, - 2, - 0, - SqlCompareOptions.IgnoreCase, - null, - true, - true, - SortOrder.Ascending, - 0); - string value = null; - string ret = metaData.Adjust(value); - Assert.Null(ret); - } - - [Fact] - public void AdjustWithOutOfRangeDateTime() - { - SqlMetaData metaData = new SqlMetaData( - "col1", - SqlDbType.SmallDateTime, - 4, - 2, - 2, - 0, - SqlCompareOptions.IgnoreCase, - null, - true, - true, - SortOrder.Ascending, - 0); - - DateTime date = new DateTime(2080, 06, 06, 23, 59, 29, 999); - ArgumentException ex = Assert.ThrowsAny(() => - { - object actual = metaData.Adjust(date); - }); - Assert.Contains("invalid", ex.Message, StringComparison.OrdinalIgnoreCase); - } - - [Fact] - public void AdjustWithOutOfRangeTimeSpan_Throws() - { - SqlMetaData metaData = new SqlMetaData( - "col1", - SqlDbType.Time, - 4, - 2, - 2, - 0, - SqlCompareOptions.IgnoreCase, - null, - true, - true, - SortOrder.Ascending, - 0); - - TimeSpan outOfRangeTimespan = new TimeSpan(TimeSpan.TicksPerDay); - ArgumentException ex = Assert.Throws(() => - { - object actual = metaData.Adjust(outOfRangeTimespan); - }); - Assert.Contains("invalid", ex.Message, StringComparison.OrdinalIgnoreCase); - } - - [Fact] - public void AdjustXml() - { - SqlMetaData metaData = new SqlMetaData("col1", SqlDbType.Xml, "NorthWindDb", "Schema", "ObjectName"); - SqlXml xml = metaData.Adjust(SqlXml.Null); - Assert.True(xml.IsNull); - } - - [Fact] - public void ConstructorWithDefaultLocale() - { - SqlMetaData metaData = new SqlMetaData("col1", SqlDbType.NText, true, true, SortOrder.Ascending, 0); - Assert.Equal("col1", metaData.Name); - Assert.Equal(CultureInfo.CurrentCulture.LCID, metaData.LocaleId); - Assert.True(metaData.UseServerDefault); - Assert.True(metaData.IsUniqueKey); - Assert.Equal(SortOrder.Ascending, metaData.SortOrder); - Assert.Equal(0, metaData.SortOrdinal); - } - - [Fact] - public void ConstructorWithDefaultLocaleInvalidType_Throws() - { - SqlDbType invalidType = SqlDbType.Structured; - ArgumentException ex = Assert.Throws(() => - { - SqlMetaData metaData = new SqlMetaData("col1", invalidType, true, true, SortOrder.Ascending, 0); - }); - Assert.Contains("dbType", ex.Message, StringComparison.OrdinalIgnoreCase); - } - - [Theory] - [InlineData(SqlDbType.Char)] - [InlineData(SqlDbType.VarChar)] - [InlineData(SqlDbType.NChar)] - [InlineData(SqlDbType.NVarChar)] - public void ConstructorWithMaxLengthAndDefaultLocale(SqlDbType dbType) - { - const int maxLength = 5; - SqlMetaData metaData = new SqlMetaData("col1", dbType, maxLength, true, true, SortOrder.Ascending, 0); - Assert.Equal("col1", metaData.Name); - Assert.Equal(CultureInfo.CurrentCulture.LCID, metaData.LocaleId); - Assert.True(metaData.UseServerDefault); - Assert.True(metaData.IsUniqueKey); - Assert.Equal(SortOrder.Ascending, metaData.SortOrder); - Assert.Equal(0, metaData.SortOrdinal); - } - - [Fact] - public void ConstructorWithMaxLengthAndDefaultLocaleInvalidType_Throws() - { - ArgumentException ex = Assert.Throws(() => - { - SqlMetaData metaData = new SqlMetaData("col1", SqlDbType.Int, 5, true, true, SortOrder.Ascending, 0); - }); - Assert.Contains("dbType", ex.Message, StringComparison.OrdinalIgnoreCase); - } - - [Theory] - [InlineData(SqlDbType.Char)] - [InlineData(SqlDbType.VarChar)] - [InlineData(SqlDbType.NChar)] - [InlineData(SqlDbType.NVarChar)] - public void ConstructorWithMaxLengthAndLocale(SqlDbType dbType) - { - long maxLength = 5L; - long locale = 0L; - SqlMetaData metaData = new SqlMetaData("col1", dbType, maxLength, locale, SqlCompareOptions.IgnoreCase, true, true, SortOrder.Ascending, 0); - Assert.Equal("col1", metaData.Name); - Assert.Equal(locale, metaData.LocaleId); - Assert.Equal(maxLength, metaData.MaxLength); - Assert.True(metaData.UseServerDefault); - Assert.True(metaData.IsUniqueKey); - Assert.Equal(SortOrder.Ascending, metaData.SortOrder); - Assert.Equal(0, metaData.SortOrdinal); - } - - [Fact] - public void ConstructorWithMaxLengthAndLocaleInvalidType_Throws() - { - long locale = 0L; - ArgumentException ex = Assert.Throws(() => - { - SqlMetaData metaData = new SqlMetaData("col1", SqlDbType.Int, 5, locale, SqlCompareOptions.IgnoreCase, true, true, SortOrder.Ascending, 0); - }); - Assert.Contains("dbType", ex.Message, StringComparison.OrdinalIgnoreCase); - } - - [Theory] - [InlineData(SqlDbType.NText)] - [InlineData(SqlDbType.Text)] - public void ConstructorWithMaxLengthTextAndDefaultLocale(SqlDbType dbType) - { - long maxLength = SqlMetaData.Max; - SqlMetaData metaData = new SqlMetaData("col1", dbType, maxLength, true, true, SortOrder.Ascending, 0); - Assert.Equal("col1", metaData.Name); - Assert.Equal(CultureInfo.CurrentCulture.LCID, metaData.LocaleId); - Assert.True(metaData.UseServerDefault); - Assert.True(metaData.IsUniqueKey); - Assert.Equal(SortOrder.Ascending, metaData.SortOrder); - Assert.Equal(0, metaData.SortOrdinal); - } - - [Theory] - [InlineData(SqlDbType.NText)] - [InlineData(SqlDbType.Text)] - public void ConstructorWithMaxLengthTextAndLocale(SqlDbType dbType) - { - long maxLength = SqlMetaData.Max; - long locale = 0L; - SqlMetaData metaData = new SqlMetaData("col1", dbType, maxLength, locale, SqlCompareOptions.IgnoreCase, true, true, SortOrder.Ascending, 0); - Assert.Equal("col1", metaData.Name); - Assert.Equal(locale, metaData.LocaleId); - Assert.Equal(maxLength, metaData.MaxLength); - Assert.True(metaData.UseServerDefault); - Assert.True(metaData.IsUniqueKey); - Assert.Equal(SortOrder.Ascending, metaData.SortOrder); - Assert.Equal(0, metaData.SortOrdinal); - } - - [Theory] - [InlineData(SqlDbType.Char)] - [InlineData(SqlDbType.VarChar)] - [InlineData(SqlDbType.NChar)] - [InlineData(SqlDbType.NVarChar)] - [InlineData(SqlDbType.NText)] - public void ConstructorWithInvalidMaxLengthAndLocale_Throws(SqlDbType dbType) - { - int invalidMaxLength = -2; - long locale = 0L; - ArgumentException ex = Assert.Throws(() => - { - SqlMetaData metaData = new SqlMetaData("col1", dbType, invalidMaxLength, locale, SqlCompareOptions.IgnoreCase, true, true, SortOrder.Ascending, 0); - }); - Assert.Contains("out of range", ex.Message, StringComparison.OrdinalIgnoreCase); - } - - [Fact] - public void ConstructorWithInvalidMaxLengthAndLocaleCompareOptionsBinarySortAndIgnoreCase_Throws() - { - long maxLength = SqlMetaData.Max; - long locale = 0L; - SqlCompareOptions invalidCompareOptions = SqlCompareOptions.BinarySort | SqlCompareOptions.IgnoreCase; - ArgumentOutOfRangeException ex = Assert.Throws(() => - { - SqlMetaData metaData = new SqlMetaData("col1", SqlDbType.NText, maxLength, locale, invalidCompareOptions, true, true, SortOrder.Ascending, 0); - }); - Assert.Contains("invalid", ex.Message, StringComparison.OrdinalIgnoreCase); - } - - [Theory] - [InlineData(SqlDbType.Char)] - [InlineData(SqlDbType.VarChar)] - [InlineData(SqlDbType.NChar)] - [InlineData(SqlDbType.NVarChar)] - [InlineData(SqlDbType.NText)] - [InlineData(SqlDbType.Binary)] - [InlineData(SqlDbType.VarBinary)] - [InlineData(SqlDbType.Image)] - public void ConstructorWithInvalidMaxLengthDefaultLocale_Throws(SqlDbType dbType) - { - int invalidMaxLength = -2; - ArgumentException ex = Assert.Throws(() => - { - SqlMetaData metaData = new SqlMetaData("col1", dbType, invalidMaxLength, true, true, SortOrder.Ascending, 0); - }); - Assert.Contains("out of range", ex.Message, StringComparison.OrdinalIgnoreCase); - } - - [Fact] - public void ConstructorWithLongName_Throws() - { - string invalidName = new string('c', 256); - - ArgumentException ex = Assert.Throws(() => - { - SqlMetaData metaData = new SqlMetaData(invalidName, SqlDbType.Decimal, 2, 2, true, true, SortOrder.Ascending, 0); - }); - Assert.Contains("long", ex.Message, StringComparison.OrdinalIgnoreCase); - } - - [Fact] - public void ConstructorWithNullName_Throws() - { - string invalidName = null; - - ArgumentNullException ex = Assert.Throws(() => - { - SqlMetaData metaData = new SqlMetaData(invalidName, SqlDbType.Decimal, 2, 2, true, true, SortOrder.Ascending, 0); - }); - Assert.Contains("null", ex.Message, StringComparison.OrdinalIgnoreCase); - } - - [Fact] - public void ConstructorWithInvalidSortOrder_Throws() - { - SortOrder invalidSortOrder = (SortOrder)5; - ArgumentOutOfRangeException ex = Assert.Throws(() => - { - SqlMetaData metaData = new SqlMetaData("col1", SqlDbType.Int, true, true, invalidSortOrder, 0); - }); - Assert.Contains("SortOrder", ex.Message, StringComparison.OrdinalIgnoreCase); - } - - [Fact] - public void ConstructorWithInvalidSortOrderSortOrdinal_Throws() - { - SortOrder invalidSortOrder = SortOrder.Unspecified; - int invalidMatchToSortOrdinal = 0; - InvalidOperationException ex = Assert.Throws(() => - { - SqlMetaData metaData = new SqlMetaData("col1", SqlDbType.Int, true, true, invalidSortOrder, invalidMatchToSortOrdinal); - }); - Assert.Contains("sort order and ordinal", ex.Message, StringComparison.OrdinalIgnoreCase); - } - - [Fact] - public void DbTypeDatabaseOwningSchemaObjectNameConstructorWithInvalidDbTypeName_Throws() - { - ArgumentException ex = Assert.ThrowsAny(() => - { - SqlMetaData metaData = new SqlMetaData("col2", SqlDbType.Int, "NorthWindDb", "schema", "name"); - }); - Assert.Contains("dbType", ex.Message, StringComparison.OrdinalIgnoreCase); - } - - [Fact] - public void DecimalConstructor() - { - SqlMetaData metaData = new SqlMetaData("col2", SqlDbType.Decimal, 2, 2, true, true, SortOrder.Ascending, 1); - Assert.Equal("col2", metaData.Name); - Assert.Equal(SqlDbType.Decimal, metaData.SqlDbType); - Assert.Null(metaData.Type); - Assert.Equal(2, metaData.Precision); - Assert.Equal(2, metaData.Scale); - Assert.True(metaData.UseServerDefault); - Assert.True(metaData.IsUniqueKey); - Assert.Equal(SortOrder.Ascending, metaData.SortOrder); - Assert.Equal(1, metaData.SortOrdinal); - } - - [Fact] - public void DecimalConstructorWithPrecisionScale() - { - SqlMetaData metaData = new SqlMetaData("col2", SqlDbType.Decimal, 2, 2); - Assert.Equal("col2", metaData.Name); - Assert.Equal(SqlDbType.Decimal, metaData.SqlDbType); - Assert.Null(metaData.Type); - Assert.Equal(2, metaData.Precision); - Assert.Equal(2, metaData.Scale); - } - - [Fact] - public void DecimalConstructorWithNullUdt() - { - SqlMetaData metaData = new SqlMetaData("col1", SqlDbType.Decimal, 5, 2, 2, 0, SqlCompareOptions.BinarySort, null); - Assert.Equal("col1", metaData.Name); - Assert.Equal(SqlDbType.Decimal, metaData.SqlDbType); - Assert.Equal(5, metaData.MaxLength); - Assert.Equal(2, metaData.Precision); - Assert.Equal(2, metaData.Scale); - Assert.Equal(0, metaData.LocaleId); - Assert.Null(metaData.Type); - } - - [Fact] - public void DecimalConstructorWithPrecisionOutOfRange_Throws() - { - byte precision = 1; - byte scale = 2; - ArgumentException ex = Assert.Throws(() => - { - SqlMetaData metaData = new SqlMetaData("col1", SqlDbType.Decimal, precision, scale, true, true, SortOrder.Ascending, 0); - }); - Assert.Contains("precision", ex.Message, StringComparison.OrdinalIgnoreCase); - } - - [Fact] - public void DecimalConstructorWithPrecisionOutofRange2_Throws() - { - byte precision = SqlDecimal.MaxPrecision; - precision += 1; - byte scale = 2; - ArgumentException ex = Assert.Throws(() => - { - SqlMetaData metaData = new SqlMetaData("col1", SqlDbType.Decimal, precision, scale, true, true, SortOrder.Ascending, 0); - }); - Assert.Contains("precision", ex.Message, StringComparison.OrdinalIgnoreCase); - } - - // TODO: This condition can never be met because SqlDecimal.MaxPrecision == SqlDecimal.MaxScale - // and there's a check that scale cannot exceed precision, so we cannot test this exception. - //[Fact] - //public void DecimalConstructorWithScaleOutOfRange_Throws() - //{ - // byte precision = SqlDecimal.MaxPrecision; - // byte scale = SqlDecimal.MaxScale; - // scale += 1; - - // ArgumentException ex = Assert.Throws(() => - // { - // SqlMetaData metaData = new SqlMetaData("col1", SqlDbType.Decimal, precision, scale, true, true, SortOrder.Ascending, 0); - // }); - // Assert.NotNull(ex); - // Assert.NotEmpty(ex.Message); - // Assert.Contains("scale", ex.Message, StringComparison.OrdinalIgnoreCase); - //} - - [Theory] - [InlineData(SqlDbType.Variant, null)] - [InlineData(SqlDbType.Udt, typeof(Address))] - public void GenericConstructorWithoutXmlSchema(SqlDbType dbType, Type udt) - { - SqlMetaData metaData = new SqlMetaData("col2", dbType, 16, 2, 2, 2, SqlCompareOptions.IgnoreCase, udt, true, true, SortOrder.Ascending, 0); - Assert.Equal(dbType, metaData.SqlDbType); - Assert.True(metaData.UseServerDefault); - Assert.True(metaData.IsUniqueKey); - Assert.Equal(SortOrder.Ascending, metaData.SortOrder); - Assert.Equal(0, metaData.SortOrdinal); - } - - [Fact] - public void GenericConstructorWithoutXmlSchemaWithInvalidDbType_Throws() - { - ArgumentException ex = Assert.Throws(() => - { - SqlMetaData metaData = new SqlMetaData("col2", (SqlDbType)999, 16, 2, 2, 2, SqlCompareOptions.IgnoreCase, null, true, true, SortOrder.Ascending, 0); - }); - Assert.Contains("dbType", ex.Message, StringComparison.OrdinalIgnoreCase); - } - - [Fact] - public void GetPartialLengthWithXmlSqlMetaDataType_Throws() - { - Type sqlMetaDataType = typeof(SqlMetaData); - SqlMetaData exampleMetaData = new SqlMetaData("col2", SqlDbType.Xml); - MethodInfo method = sqlMetaDataType.GetMethod("GetPartialLengthMetaData", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static); - Exception ex = Assert.ThrowsAny(() => - { - SqlMetaData metaData = (SqlMetaData)method.Invoke(exampleMetaData, new object[] { exampleMetaData }); - }); - Assert.NotNull(ex.InnerException); - Assert.IsType(ex.InnerException); - Assert.NotEmpty(ex.InnerException.Message); - Assert.Contains("metadata", ex.InnerException.Message, StringComparison.OrdinalIgnoreCase); - } - - [Theory] - [InlineData(SqlDbType.NVarChar)] - [InlineData(SqlDbType.VarChar)] - [InlineData(SqlDbType.VarBinary)] - public void GetPartialLengthWithVarSqlMetaDataType(SqlDbType sqlDbType) - { - Type sqlMetaDataType = typeof(SqlMetaData); - SqlMetaData exampleMetaData = new SqlMetaData("col2", sqlDbType, 16); - MethodInfo method = sqlMetaDataType.GetMethod("GetPartialLengthMetaData", BindingFlags.NonPublic | BindingFlags.Static); - SqlMetaData metaData = metaData = (SqlMetaData)method.Invoke(exampleMetaData, new object[] { exampleMetaData }); - Assert.Equal(exampleMetaData.Name, metaData.Name); - Assert.Equal(exampleMetaData.SqlDbType, metaData.SqlDbType); - Assert.Equal(SqlMetaData.Max, metaData.MaxLength); - Assert.Equal(0, metaData.Precision); - Assert.Equal(0, metaData.Scale); - Assert.Equal(exampleMetaData.LocaleId, metaData.LocaleId); - Assert.Equal(exampleMetaData.CompareOptions, metaData.CompareOptions); - Assert.Null(metaData.XmlSchemaCollectionDatabase); - Assert.Null(metaData.XmlSchemaCollectionName); - Assert.Null(metaData.XmlSchemaCollectionOwningSchema); - // PartialLength is an interal property which is why reflection is required. - PropertyInfo isPartialLengthProp = sqlMetaDataType.GetProperty("IsPartialLength", BindingFlags.NonPublic | BindingFlags.Instance); - Assert.True((bool)isPartialLengthProp.GetValue(metaData)); - Assert.Equal(exampleMetaData.Type, metaData.Type); - } - - [Theory] - [MemberData(nameof(SqlMetaDataInferredValues))] - public void InferFromValue(SqlDbType expectedDbType, object value) - { - SqlMetaData metaData = SqlMetaData.InferFromValue(value, "col1"); - Assert.Equal(expectedDbType, metaData.SqlDbType); - } - - [Theory] - [InlineData((SByte)1)] - [InlineData((UInt16)1)] - [InlineData((UInt32)1)] - [InlineData((UInt64)1)] - public void InferFromValueWithInvalidValue_Throws(object value) - { - ArgumentException ex = Assert.Throws(() => - { - SqlMetaData metaData = SqlMetaData.InferFromValue(value, "col1"); - }); - Assert.NotNull(ex); - Assert.NotEmpty(ex.Message); - Assert.Contains("invalid", ex.Message, StringComparison.OrdinalIgnoreCase); - } - - [Fact] - public void InferFromValueWithNull_Throws() - { - ArgumentNullException ex = Assert.Throws(() => - { - SqlMetaData metaData = SqlMetaData.InferFromValue(null, "col1"); - }); - Assert.Contains("null", ex.Message, StringComparison.OrdinalIgnoreCase); - } - - [Fact] - public void InferFromValueWithUdtValue_Throws() - { - ArgumentException ex = Assert.Throws(() => - { - Address address = new Address(); - SqlMetaData metaData = SqlMetaData.InferFromValue(address, "col1"); - }); - Assert.Contains("address", ex.Message, StringComparison.OrdinalIgnoreCase); - } - - [Fact] - public void IsPartialLengthTrueGetPartialLengthMetaData() - { - Type sqlMetaDataType = typeof(SqlMetaData); - SqlMetaData exampleMetaData = new SqlMetaData("col2", SqlDbType.Int); - FieldInfo isPartialLengthField = sqlMetaDataType.GetField("_partialLength", BindingFlags.NonPublic | BindingFlags.Instance); - isPartialLengthField.SetValue(exampleMetaData, true); - MethodInfo method = sqlMetaDataType.GetMethod("GetPartialLengthMetaData", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static); - SqlMetaData metaData = (SqlMetaData)method.Invoke(exampleMetaData, new object[] { exampleMetaData }); - Assert.Equal(exampleMetaData, metaData); - } - - [Fact] - public void NameDbTypeDatabaseOwningSchemaObjectNameConstructor() - { - SqlMetaData metaData = new SqlMetaData("col2", SqlDbType.Xml, "NorthWindDb", "schema", "name"); - Assert.Equal("col2", metaData.Name); - Assert.Equal(SqlDbType.Xml, metaData.SqlDbType); - Assert.Equal("NorthWindDb", metaData.XmlSchemaCollectionDatabase); - Assert.Equal("schema", metaData.XmlSchemaCollectionOwningSchema); - Assert.Equal("name", metaData.XmlSchemaCollectionName); - Assert.Equal("xml", metaData.TypeName); - } - - [Fact] - public void NonVarTypeGetPartialLengthMetaData() - { - Type sqlMetaDataType = typeof(SqlMetaData); - SqlMetaData exampleMetaData = new SqlMetaData("col2", SqlDbType.Int); - MethodInfo method = sqlMetaDataType.GetMethod("GetPartialLengthMetaData", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static); - SqlMetaData metaData = (SqlMetaData)method.Invoke(exampleMetaData, new object[] { exampleMetaData }); - Assert.Equal(exampleMetaData, metaData); - } - - [Fact] - public void StringConstructorWithLocaleCompareOption() - { - SqlMetaData metaData = new SqlMetaData("col2", SqlDbType.VarChar, 16, 2, SqlCompareOptions.IgnoreCase, true, true, SortOrder.Ascending, 1); - Assert.Equal("col2", metaData.Name); - Assert.Equal(SqlDbType.VarChar, metaData.SqlDbType); - Assert.Equal(DbType.AnsiString, metaData.DbType); - Assert.Null(metaData.Type); - Assert.Equal(16, metaData.MaxLength); - Assert.Equal(2, metaData.LocaleId); - Assert.Equal(SqlCompareOptions.IgnoreCase, metaData.CompareOptions); - Assert.True(metaData.UseServerDefault); - Assert.True(metaData.IsUniqueKey); - Assert.Equal(SortOrder.Ascending, metaData.SortOrder); - Assert.Equal(1, metaData.SortOrdinal); - } - - [Theory] - [InlineData(SqlDbType.Time)] - [InlineData(SqlDbType.DateTime2)] - [InlineData(SqlDbType.DateTimeOffset)] - public void TimeConstructorWithOutOfRange_Throws(SqlDbType dbType) - { - byte precision = 8; - byte scale = 8; - - ArgumentException ex = Assert.Throws(() => - { - SqlMetaData metaData = new SqlMetaData("col1", dbType, 5, precision, scale, 0, SqlCompareOptions.BinarySort, null, true, true, SortOrder.Ascending, 0); - }); - Assert.Contains("scale", ex.Message, StringComparison.OrdinalIgnoreCase); - } - - [Fact] - public void TimeConstructorWithInvalidType_Throws() - { - byte precision = 2; - byte scale = 2; - - ArgumentException ex = Assert.Throws(() => - { - SqlMetaData metaData = new SqlMetaData("col1", SqlDbType.Int, precision, scale); - }); - Assert.Contains("dbType", ex.Message, StringComparison.OrdinalIgnoreCase); - } // Test UDT constrtuctor without tvp extended properties [Fact] @@ -712,20 +27,6 @@ public void UdtConstructorTest() Assert.Equal(-1, metaData.SortOrdinal); } - [Fact] - public void UdtConstructorTestWithoutServerTypeName() - { - Address address = Address.Parse("123 baker st || Redmond"); - SqlMetaData metaData = new SqlMetaData("col1", SqlDbType.Udt, typeof(Address)); - Assert.Equal("col1", metaData.Name); - Assert.Equal(SqlDbType.Udt, metaData.SqlDbType); - Assert.Equal(address.GetType(), metaData.Type); - Assert.Equal("Address", metaData.TypeName); - Assert.False(metaData.UseServerDefault); - Assert.False(metaData.IsUniqueKey); - Assert.Equal(SortOrder.Unspecified, metaData.SortOrder); - Assert.Equal(-1, metaData.SortOrdinal); - } // Test UDT constrtuctor with tvp extended properties [Fact] @@ -742,278 +43,5 @@ public void UdtConstructorWithTvpTest() Assert.Equal(SortOrder.Ascending, metaData.SortOrder); Assert.Equal(0, metaData.SortOrdinal); } - - [Fact] - public void UdtConstructorWithInvalidType_Throws() - { - ArgumentException ex = Assert.Throws(() => - { - SqlMetaData metaData = new SqlMetaData("col1", SqlDbType.Int, typeof(int)); - }); - Assert.Contains("dbType", ex.Message, StringComparison.OrdinalIgnoreCase); - } - - [Fact] - public void UdtConstructorWithNull_Throws() - { - ArgumentNullException ex = Assert.Throws(() => - { - SqlMetaData metaData = new SqlMetaData("col1", SqlDbType.Udt, null); - }); - Assert.Contains("null", ex.Message, StringComparison.OrdinalIgnoreCase); - } - - [Fact] - public void XmlConstructor() - { - SqlMetaData metaData = new SqlMetaData("col2", SqlDbType.Xml, "NorthWindDb", "schema", "name", true, true, SortOrder.Ascending, 1); - Assert.Equal("col2", metaData.Name); - Assert.Equal(SqlDbType.Xml, metaData.SqlDbType); - Assert.Null(metaData.Type); - Assert.Equal("NorthWindDb", metaData.XmlSchemaCollectionDatabase); - Assert.Equal("schema", metaData.XmlSchemaCollectionOwningSchema); - Assert.Equal("name", metaData.XmlSchemaCollectionName); - Assert.True(metaData.UseServerDefault); - Assert.True(metaData.IsUniqueKey); - Assert.Equal(SortOrder.Ascending, metaData.SortOrder); - Assert.Equal(1, metaData.SortOrdinal); - } - - [Fact] - public void XmlConstructorWithNullObjectName_Throws() - { - ArgumentNullException ex = Assert.Throws(() => - { - SqlMetaData metaData = new SqlMetaData("col1", SqlDbType.Xml, "NorthWindDb", "schema", null); - }); - Assert.Contains("null", ex.Message, StringComparison.OrdinalIgnoreCase); - } - - #region Test values - public static readonly object[][] SqlMetaDataDateTimeValues = - { - new object[] {SqlDbType.DateTime, new SqlDateTime(DateTime.UtcNow)}, - new object[] {SqlDbType.Date, DateTime.Today}, - new object[] {SqlDbType.DateTime, DateTime.Today}, - new object[] {SqlDbType.DateTime2, DateTime.Today}, - new object[] {SqlDbType.SmallDateTime, DateTime.Today}, - }; - - public static readonly object[][] SqlMetaDataMaxLengthTrimValues = - { - new object[] {SqlDbType.Binary, new SqlBinary(new byte[] { 1, 2, 3, 4, 5 })}, - new object[] {SqlDbType.Binary, new byte[] { 1, 2, 3, 4, 5 }}, - new object[] {SqlDbType.Char, "Tests"}, - new object[] {SqlDbType.Char, "T"}, - new object[] {SqlDbType.Char, new char[]{'T','e','s','t','s'}}, - new object[] {SqlDbType.NChar, "T"}, - new object[] {SqlDbType.NChar, "Tests"}, - new object[] {SqlDbType.VarChar, "Tests" }, - new object[] {SqlDbType.VarChar, new SqlString("Tests")}, - new object[] {SqlDbType.VarChar, new char[]{'T','e','s','t','s'}}, - new object[] {SqlDbType.NVarChar, "Tests"}, - new object[] {SqlDbType.Binary, new SqlBytes(new byte[] { 1 })}, - new object[] {SqlDbType.Binary, new byte[] { 1 }}, - new object[] {SqlDbType.Timestamp, new SqlBytes(new byte[] { 1 })}, - }; - - public static readonly object[][] SqlMetaDataInvalidValues = - { - new object[] {SqlDbType.Char, 'T'}, - new object[] {SqlDbType.NChar, 'T'}, - new object[] {SqlDbType.Text, 'T'}, - new object[] {SqlDbType.NText, 'T'}, - new object[] {SqlDbType.Date, SqlDateTime.Null}, - new object[] {SqlDbType.SmallInt, 1}, - new object[] {SqlDbType.VarChar, SqlInt32.Zero}, - new object[] {SqlDbType.BigInt, (short)1}, - new object[] {SqlDbType.NVarChar, SqlInt16.Zero}, - new object[] {SqlDbType.Text, 10L}, - new object[] {SqlDbType.Binary, SqlInt64.Zero}, - new object[] {SqlDbType.Float, 1.0f}, - new object[] {SqlDbType.NChar, SqlSingle.Zero}, - new object[] {SqlDbType.Timestamp, 1.0d}, - new object[] {SqlDbType.Real, SqlDouble.Zero}, - new object[] {SqlDbType.VarBinary, false}, - new object[] {SqlDbType.NText, SqlBoolean.False}, - new object[] {SqlDbType.Time, (byte)1}, - new object[] {SqlDbType.Bit, SqlByte.Zero}, - new object[] {SqlDbType.Decimal, SqlMoney.Zero}, - new object[] {SqlDbType.SmallMoney, SqlDecimal.Null}, - new object[] {SqlDbType.Money, SqlDecimal.Null}, - new object[] {SqlDbType.Bit, SqlString.Null}, - new object[] {SqlDbType.Int, new char[] {'T','e','s', 't'}}, - new object[] {SqlDbType.Timestamp, new SqlString("T")}, - new object[] {SqlDbType.Image, SqlChars.Null}, - new object[] {SqlDbType.Int, new SqlChars(new char[] { 'T', 'e', 's', 't' })}, - new object[] {SqlDbType.Float, SqlBinary.Null}, - new object[] {SqlDbType.Float, new SqlBinary(new byte[] { 1 })}, - new object[] {SqlDbType.Float, SqlBytes.Null}, - new object[] {SqlDbType.Float, new SqlBytes(new byte[] { 1, 0, 0, 0 })}, - new object[] {SqlDbType.Float, new byte[] { 1, 0, 0, 0 }}, - new object[] {SqlDbType.TinyInt, new SqlBytes(new byte[] { 1 })}, - new object[] {SqlDbType.Bit, SqlBinary.Null}, - new object[] {SqlDbType.Bit, new SqlBinary(new byte[] { 1 })}, - new object[] {SqlDbType.Decimal, new SqlBytes()}, - new object[] {SqlDbType.Char, new TimeSpan(0, 0, 1)}, - new object[] {SqlDbType.UniqueIdentifier, new DateTimeOffset(new DateTime(0))}, - new object[] {SqlDbType.DateTimeOffset, SqlGuid.Null}, - new object[] {SqlDbType.Date, new SqlDateTime(DateTime.UtcNow)}, - new object[] {SqlDbType.Bit, SqlXml.Null }, - new object[] {SqlDbType.Bit, (sbyte)0}, - new object[] {SqlDbType.Bit, (UInt16)1}, - new object[] {SqlDbType.Bit, (UInt32)1}, - new object[] {SqlDbType.Bit, (UInt64)1}, - new object[] {SqlDbType.Bit, (sbyte)0}, - new object[] {SqlDbType.Int, Guid.Empty}, - new object[] {SqlDbType.NText, 'T'}, - new object[] {SqlDbType.SmallMoney, (decimal)int.MaxValue}, - new object[] {SqlDbType.SmallMoney, "Money" }, - new object[] {SqlDbType.Bit, 1.0M }, - new object[] {SqlDbType.Bit, DateTime.Today}, - }; - - public static readonly object[][] SqlMetaDataAdjustValues = - { - new object[] {SqlDbType.Int, null}, - new object[] {SqlDbType.Int, 1}, - new object[] {SqlDbType.Int, SqlInt32.Zero}, - new object[] {SqlDbType.SmallInt, (short)1}, - new object[] {SqlDbType.SmallInt, SqlInt16.Zero}, - new object[] {SqlDbType.BigInt, 10L}, - new object[] {SqlDbType.BigInt, SqlInt64.Zero}, - new object[] {SqlDbType.Real, 1.0f}, - new object[] {SqlDbType.Real, SqlSingle.Zero}, - new object[] {SqlDbType.Float, 1.0d}, - new object[] {SqlDbType.Float, SqlDouble.Zero}, - new object[] {SqlDbType.Bit, false}, - new object[] {SqlDbType.Bit, SqlBoolean.False}, - new object[] {SqlDbType.TinyInt, (byte)1}, - new object[] {SqlDbType.TinyInt, SqlByte.Zero}, - new object[] {SqlDbType.Money, 10.01M }, - new object[] {SqlDbType.Money, SqlMoney.Zero}, - new object[] {SqlDbType.SmallMoney, SqlMoney.Zero}, - new object[] {SqlDbType.SmallMoney, 10.01M }, - new object[] {SqlDbType.Decimal, 0M }, - new object[] {SqlDbType.Decimal, SqlDecimal.Null}, - new object[] {SqlDbType.Char, SqlString.Null}, - new object[] {SqlDbType.Char, new char[] {'T','e','s', 't'}}, - new object[] {SqlDbType.Char, "Test"}, - new object[] {SqlDbType.Char, new SqlString("T")}, - new object[] {SqlDbType.Char, new SqlString("Test")}, - new object[] {SqlDbType.Char, SqlChars.Null}, - new object[] {SqlDbType.Char, new SqlChars(new char[] { 'T', 'e', 's', 't' })}, - new object[] {SqlDbType.NChar, SqlString.Null}, - new object[] {SqlDbType.NChar, new char[] {'T','e' ,'s', 't'}}, - new object[] {SqlDbType.NChar, SqlChars.Null}, - new object[] {SqlDbType.NChar, "Test"}, - new object[] {SqlDbType.NChar, new SqlString("T")}, - new object[] {SqlDbType.NChar, new SqlString("Test")}, - new object[] {SqlDbType.NChar, new SqlChars(new char[] { 'T', 'e', 's', 't' })}, - new object[] {SqlDbType.VarChar, 'T'}, - new object[] {SqlDbType.VarChar, "T"}, - new object[] {SqlDbType.VarChar, "Test"}, - new object[] {SqlDbType.VarChar, new SqlString("T")}, - new object[] {SqlDbType.VarChar, new SqlString("Test")}, - new object[] {SqlDbType.VarChar, new SqlChars(new char[] { 'T', 'e', 's', 't' })}, - new object[] {SqlDbType.NVarChar, 'T'}, - new object[] {SqlDbType.NVarChar, "T"}, - new object[] {SqlDbType.NVarChar, "Test"}, - new object[] {SqlDbType.NVarChar, new char[] {'T','e','s', 't'}}, - new object[] {SqlDbType.NVarChar, new SqlString("T")}, - new object[] {SqlDbType.NVarChar, new SqlString("Test")}, - new object[] {SqlDbType.NVarChar, new SqlChars(new char[] { 'T', 'e', 's', 't' })}, - new object[] {SqlDbType.NText, "T"}, - new object[] {SqlDbType.NText, "Test"}, - new object[] {SqlDbType.NText, "Tests"}, - new object[] {SqlDbType.NText, new char[] {'T','e','s', 't'}}, - new object[] {SqlDbType.NText, new SqlString("T")}, - new object[] {SqlDbType.NText, new SqlString("Test")}, - new object[] {SqlDbType.NText, new SqlString(new string('T', 17))}, - new object[] {SqlDbType.NText, new SqlChars(new char[] { 'T', 'e', 's', 't' })}, - new object[] {SqlDbType.NText, new SqlChars(new char[] { 'T', 'e', '.', 't' })}, - new object[] {SqlDbType.Text, "Tests"}, - new object[] {SqlDbType.Text, new char[] {'T','e','s', 't'}}, - new object[] {SqlDbType.Text, new SqlChars(new char[] { 'T', 'e', 's', 't' })}, - new object[] {SqlDbType.Binary, SqlBinary.Null}, - new object[] {SqlDbType.Binary, new SqlBinary(new byte[] { 1 })}, - new object[] {SqlDbType.Binary, SqlBytes.Null}, - new object[] {SqlDbType.Binary, new SqlBytes(new byte[] { 1, 0, 0, 0 })}, - new object[] {SqlDbType.Binary, new byte[] { 1, 0, 0, 0 }}, - new object[] {SqlDbType.Binary, new SqlBytes(new byte[] { 1, 2, 3, 4, 5 })}, - new object[] {SqlDbType.VarBinary, new SqlBytes(new byte[] { 1 })}, - new object[] {SqlDbType.Timestamp, SqlBinary.Null}, - new object[] {SqlDbType.Timestamp, new SqlBinary(new byte[] { 1 })}, - new object[] {SqlDbType.Timestamp, new SqlBinary(new byte[] { 1, 2, 3, 4, 5 })}, - new object[] {SqlDbType.Timestamp, new SqlBytes()}, - new object[] {SqlDbType.Image, new SqlBinary(new byte[] { 1 })}, - new object[] {SqlDbType.Image, new SqlBytes(new byte[] { 1 })}, - new object[] {SqlDbType.Time, new TimeSpan(0, 0, 1)}, - new object[] {SqlDbType.DateTimeOffset, new DateTimeOffset(new DateTime(0))}, - new object[] {SqlDbType.UniqueIdentifier, SqlGuid.Null}, - new object[] {SqlDbType.UniqueIdentifier, Guid.Empty}, - }; - - public static readonly object[][] SqlMetaDataInferredValues = - { - new object[] {SqlDbType.Int, 1}, - new object[] {SqlDbType.Int, SqlInt32.Zero}, - new object[] {SqlDbType.SmallInt, (short)1}, - new object[] {SqlDbType.SmallInt, SqlInt16.Zero}, - new object[] {SqlDbType.BigInt, 10L}, - new object[] {SqlDbType.BigInt, SqlInt64.Zero}, - new object[] {SqlDbType.Real, 1.0f}, - new object[] {SqlDbType.Real, SqlSingle.Zero}, - new object[] {SqlDbType.Float, 1.0d}, - new object[] {SqlDbType.Float, SqlDouble.Zero}, - new object[] {SqlDbType.Bit, false}, - new object[] {SqlDbType.Bit, SqlBoolean.False}, - new object[] {SqlDbType.TinyInt, (byte)1}, - new object[] {SqlDbType.TinyInt, SqlByte.Zero}, - new object[] {SqlDbType.Money, SqlMoney.Zero}, - new object[] {SqlDbType.Decimal, SqlDecimal.Null}, - new object[] {SqlDbType.Decimal, new SqlDecimal(10.01M) }, - new object[] {SqlDbType.Decimal, 10.01M }, - new object[] {SqlDbType.NVarChar, "" }, - new object[] {SqlDbType.NVarChar, 'T'}, - new object[] {SqlDbType.NVarChar, "T"}, - new object[] {SqlDbType.NVarChar, "Test"}, - new object[] {SqlDbType.NVarChar, new string('a', 4001)}, - new object[] {SqlDbType.NVarChar, new char[] {}}, - new object[] {SqlDbType.NVarChar, new char[] {'T','e','s', 't'}}, - new object[] {SqlDbType.NVarChar, new char[4001]}, - new object[] {SqlDbType.NVarChar, new SqlString("T")}, - new object[] {SqlDbType.NVarChar, new SqlString("Test")}, - new object[] {SqlDbType.NVarChar, new SqlString("")}, - new object[] {SqlDbType.NVarChar, new SqlString(new string('a', 4001))}, - new object[] {SqlDbType.NVarChar, SqlString.Null}, - new object[] {SqlDbType.NVarChar, new SqlChars(new char[] { 'T' })}, - new object[] {SqlDbType.NVarChar, new SqlChars(new char[] { 'T', 'e', 's', 't' })}, - new object[] {SqlDbType.NVarChar, new SqlChars(new char[] {})}, - new object[] {SqlDbType.NVarChar, new SqlChars(new char[4001])}, - new object[] {SqlDbType.NVarChar, SqlChars.Null}, - new object[] {SqlDbType.VarBinary, new SqlBytes(new byte[] { })}, - new object[] {SqlDbType.VarBinary, new SqlBytes(new byte[] { 1 })}, - new object[] {SqlDbType.VarBinary, new SqlBytes(new byte[8001])}, - new object[] {SqlDbType.VarBinary, SqlBytes.Null}, - new object[] {SqlDbType.VarBinary, SqlBinary.Null}, - new object[] {SqlDbType.VarBinary, new SqlBinary(new byte[] { })}, - new object[] {SqlDbType.VarBinary, new SqlBinary(new byte[] { 1 })}, - new object[] {SqlDbType.VarBinary, new SqlBinary(new byte[8001])}, - new object[] {SqlDbType.VarBinary, new byte[] { }}, - new object[] {SqlDbType.VarBinary, new byte[] { 1 }}, - new object[] {SqlDbType.VarBinary, new byte[8001]}, - new object[] {SqlDbType.Time, new TimeSpan(0, 0, 1)}, - new object[] {SqlDbType.Time, new TimeSpan(TimeSpan.TicksPerDay - 1)}, - new object[] {SqlDbType.DateTimeOffset, new DateTimeOffset(new DateTime(0))}, - new object[] {SqlDbType.DateTimeOffset, new DateTimeOffset(DateTime.Now)}, - new object[] {SqlDbType.UniqueIdentifier, SqlGuid.Null}, - new object[] {SqlDbType.UniqueIdentifier, Guid.Empty}, - new object[] {SqlDbType.DateTime, new SqlDateTime(DateTime.UtcNow)}, - new object[] {SqlDbType.DateTime, DateTime.Today}, - new object[] {SqlDbType.Xml, new SqlXml()}, - new object[] {SqlDbType.Variant, new object()} - }; - #endregion } } diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlNotificationRequestTest.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlNotificationRequestTest.cs deleted file mode 100644 index eb7d204a95..0000000000 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlNotificationRequestTest.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System; -using Microsoft.Data.Sql; -using Xunit; - -namespace Microsoft.Data.SqlClient.Tests -{ - public class SqlNotificationRequestTest - { - [Fact] - public void SetOptions_OutOfRangeValue_Throws() - { - SqlNotificationRequest sqlNotification = new(); - string outOfRangeValue = new string('a', ushort.MaxValue + 1); - ArgumentOutOfRangeException ex = Assert.Throws(() => sqlNotification.Options = outOfRangeValue); - Assert.Null(ex.InnerException); - Assert.NotNull(ex.ParamName); - Assert.True(ex.ParamName.IndexOf("Options", StringComparison.OrdinalIgnoreCase) != -1); - } - - [Fact] - public void SetUserData_OutOfRangeValue_Throws() - { - SqlNotificationRequest sqlNotification = new(); - string outOfRangeValue = new string('a', ushort.MaxValue + 1); - ArgumentOutOfRangeException ex = Assert.Throws(() => sqlNotification.UserData = outOfRangeValue); - Assert.Null(ex.InnerException); - Assert.NotNull(ex.ParamName); - Assert.True(ex.ParamName.IndexOf("UserData", StringComparison.OrdinalIgnoreCase) != -1); - } - - [Fact] - public void SetTimeout_OutOfRangeValue_Throws() - { - SqlNotificationRequest sqlNotification = new(); - int outOfRangeValue = -1; - ArgumentOutOfRangeException ex = Assert.Throws(() => sqlNotification.Timeout = outOfRangeValue); - Assert.Null(ex.InnerException); - Assert.NotNull(ex.ParamName); - Assert.True(ex.ParamName.IndexOf("Timeout", StringComparison.OrdinalIgnoreCase) != -1); - } - } -} diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlParameterCollectionTest.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlParameterCollectionTest.cs deleted file mode 100644 index e93dbcc196..0000000000 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlParameterCollectionTest.cs +++ /dev/null @@ -1,114 +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. - -using System; -using Xunit; - -namespace Microsoft.Data.SqlClient.Tests -{ - public class SqlParameterCollectionTest - { - [Fact] - public void CollectionAddInvalidRange_Throws() - { - SqlCommand command = new SqlCommand(); - SqlParameterCollection collection = command.Parameters; - - Array invalid = null; - Assert.Throws(() => collection.AddRange(invalid)); - } - - [Fact] - public void CollectionAddRange() - { - SqlCommand command = new SqlCommand(); - SqlParameterCollection collection = command.Parameters; - Array sqlParameters = new SqlParameter[] { new("Test1", 1), new("Test2", 2) }; - - collection.AddRange(sqlParameters); - - Assert.Equal(2, collection.Count); - Assert.Equal((SqlParameter)sqlParameters.GetValue(0), collection[0]); - Assert.Equal((SqlParameter)sqlParameters.GetValue(1), collection[1]); - } - - [Fact] - public void CollectionCheckNameInvalid_Throws() - { - SqlCommand command = new SqlCommand(); - SqlParameterCollection collection = command.Parameters; - collection.Add(new SqlParameter("Test1", 1)); - collection.Add(new SqlParameter("Test2", 2)); - - IndexOutOfRangeException ex = Assert.Throws(() => collection.RemoveAt("DoesNotExist")); - Assert.Contains("DoesNotExist", ex.Message, StringComparison.OrdinalIgnoreCase); - } - - [Fact] - public void ConnectionCopyTo() - { - SqlCommand command = new SqlCommand(); - SqlParameterCollection collection = command.Parameters; - collection.Add(new SqlParameter("Test1", 1)); - collection.Add(new SqlParameter("Test2", 2)); - - SqlParameter[] copied = new SqlParameter[2]; - collection.CopyTo(copied, 0); - - Assert.Equal(collection[0], copied[0]); - Assert.Equal(collection[1], copied[1]); - } - - [Fact] - public void CollectionIndexOfCaseInsensitive() - { - SqlCommand command = new SqlCommand(); - SqlParameterCollection collection = command.Parameters; - collection.Add(new SqlParameter("TEST1", 1)); - collection.Add(new SqlParameter("Test2", 2)); - collection.Add(new SqlParameter("Test3", 3)); - - int index = collection.IndexOf("test1"); - Assert.Equal(0, index); - } - - [Fact] - public void CollectionRemove() - { - SqlCommand command = new SqlCommand(); - SqlParameterCollection collection = command.Parameters; - SqlParameter parameter1 = new SqlParameter("Test1", 1); - collection.Add(parameter1); - collection.Add(new SqlParameter("Test2", 2)); - collection.Add(new SqlParameter("Test3", 3)); - - collection.Remove(parameter1); - Assert.Equal(2, collection.Count); - Assert.Equal("Test2", collection[0].ParameterName); - } - - [Fact] - public void CollectionSetParameter() - { - SqlCommand command = new SqlCommand(); - SqlParameterCollection collection = command.Parameters; - collection.Add(new SqlParameter("TestOne", 0)); - collection.Add(new SqlParameter("Test2", 2)); - collection.Add(new SqlParameter("Test3", 3)); - - collection[0] = new SqlParameter("Test1", 1); - Assert.Equal("Test1", collection[0].ParameterName); - Assert.Equal(1, (int)collection[0].Value); - } - - [Fact] - public void CollectionValiateNull_Throws() - { - SqlCommand command = new SqlCommand(); - SqlParameterCollection collection = command.Parameters; - - Assert.Throws(() => collection.Add(null)); - } - } -} diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlParameterTest.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlParameterTest.cs index 2f29b1bd15..344a578b4a 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlParameterTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlParameterTest.cs @@ -659,67 +659,13 @@ public void InferType_DateTimeOffset() Assert.Equal(DbType.DateTimeOffset, param.DbType); } - [Theory] - [InlineData(15)] - [InlineData(1044)] - [InlineData(1047)] - [InlineData(1056)] - [InlineData(1065)] - [InlineData(1068)] - [InlineData(1070)] - [InlineData(1071)] - [InlineData(1081)] - [InlineData(1082)] - [InlineData(1083)] - [InlineData(1087)] - [InlineData(1090)] - [InlineData(1091)] - [InlineData(1092)] - [InlineData(1093)] - [InlineData(1101)] - [InlineData(1105)] - [InlineData(1106)] - [InlineData(1107)] - [InlineData(1108)] - [InlineData(1114)] - [InlineData(1121)] - [InlineData(1122)] - [InlineData(1123)] - [InlineData(1125)] - [InlineData(1133)] - [InlineData(1146)] - [InlineData(1148)] - [InlineData(1150)] - [InlineData(1152)] - [InlineData(1153)] - [InlineData(1155)] - [InlineData(1157)] - [InlineData(1164)] - [InlineData(2074)] - [InlineData(2092)] - [InlineData(2107)] - [InlineData(2143)] - [InlineData(3076)] - [InlineData(3098)] - [InlineData(5124)] - [InlineData(5146)] - [InlineData(8218)] - public void LocaleId(int lcid) - { - // To verify all the cases in SqlCollation.FirstSupportedCollationVersion - SqlParameter parameter = new SqlParameter(); - Assert.Equal(0, parameter.LocaleId); - parameter.LocaleId = lcid; - Assert.Equal(parameter.LocaleId, lcid); - } - [Fact] - public void LocaleIdOutOfRange_Throws() + public void LocaleId() { SqlParameter parameter = new SqlParameter(); - ArgumentOutOfRangeException ex = Assert.Throws(() => { parameter.LocaleId = -1; }); - Assert.NotNull(ex.ParamName); - Assert.Contains("LocaleId", ex.ParamName, StringComparison.OrdinalIgnoreCase); + Assert.Equal(0, parameter.LocaleId); + parameter.LocaleId = 15; + Assert.Equal(15, parameter.LocaleId); } [Fact] diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/ExceptionTestAKVStore.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/ExceptionTestAKVStore.cs index 389efad48d..ec729b098a 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/ExceptionTestAKVStore.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/ExceptionTestAKVStore.cs @@ -218,7 +218,7 @@ public void AkvStoreProviderVerifyFunctionWithInvalidSignature(bool fEnclaveEnab Buffer.BlockCopy(cmkSignature, 0, tamperedCmkSignature, 0, tamperedCmkSignature.Length); // Corrupt one byte at a time 10 times - RandomNumberGenerator rng = RandomNumberGenerator.Create(); + RandomNumberGenerator rng = new RNGCryptoServiceProvider(); byte[] randomIndexInCipherText = new byte[1]; for (int i = 0; i < 10; i++) { diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/TestFixtures/DatabaseHelper.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/TestFixtures/DatabaseHelper.cs index cd39d56b3c..f4875ce63b 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/TestFixtures/DatabaseHelper.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/TestFixtures/DatabaseHelper.cs @@ -174,8 +174,8 @@ internal static byte[] GenerateRandomBytes(int length) { // Generate random bytes cryptographically. byte[] randomBytes = new byte[length]; - RandomNumberGenerator rng = RandomNumberGenerator.Create(); - rng.GetBytes(randomBytes); + RNGCryptoServiceProvider rngCsp = new RNGCryptoServiceProvider(); + rngCsp.GetBytes(randomBytes); return randomBytes; } diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/TestFixtures/Setup/CertificateUtilityWin.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/TestFixtures/Setup/CertificateUtilityWin.cs index 72b14c8f51..66d3c3588d 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/TestFixtures/Setup/CertificateUtilityWin.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/TestFixtures/Setup/CertificateUtilityWin.cs @@ -188,7 +188,7 @@ internal static X509Certificate2 GetCertificate(string certificateName, StoreLoc /// internal static string GetCspPathFromCertificate(X509Certificate2 certificate) { - if (certificate.GetRSAPrivateKey() is RSACryptoServiceProvider csp) + if (certificate.PrivateKey is RSACryptoServiceProvider csp) { return string.Concat(csp.CspKeyContainerInfo.ProviderName, @"/", csp.CspKeyContainerInfo.KeyContainerName); } diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/TestFixtures/Setup/ColumnEncryptionKey.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/TestFixtures/Setup/ColumnEncryptionKey.cs index 19a2d2149c..5ba9c166fe 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/TestFixtures/Setup/ColumnEncryptionKey.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/TestFixtures/Setup/ColumnEncryptionKey.cs @@ -60,8 +60,8 @@ public static byte[] GenerateRandomBytes(int length) { // Generate random bytes cryptographically. byte[] randomBytes = new byte[length]; - RandomNumberGenerator rng = RandomNumberGenerator.Create(); - rng.GetBytes(randomBytes); + RNGCryptoServiceProvider rngCsp = new RNGCryptoServiceProvider(); + rngCsp.GetBytes(randomBytes); return randomBytes; } diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj b/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj index 3364313106..23ed738f37 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj @@ -13,29 +13,22 @@ $(ObjFolder)$(Configuration).$(Platform).$(AssemblyName) $(BinFolder)$(Configuration).$(Platform).$(AssemblyName) - + - - PreserveNewest - TCECryptoNativeBaseline.txt - - - PreserveNewest - TCECryptoNativeBaselineRsa.txt - - + - + + @@ -68,47 +61,96 @@ - - + + Common\System\Collections\DictionaryExtensions.cs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - + + + + + - - - + + - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + @@ -148,46 +190,20 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + - - + @@ -198,17 +214,17 @@ - - - - - - - - - - - + + + + + PreserveNewest + data.xml + + + PreserveNewest + MultipleResultsTest.bsl + PreserveNewest SqlParameterTest_DebugMode.bsl @@ -225,57 +241,42 @@ PreserveNewest SqlParameterTest_ReleaseMode_Azure.bsl - + PreserveNewest - data.xml + TCECryptoNativeBaseline.txt - + PreserveNewest - MultipleResultsTest.bsl + TCECryptoNativeBaselineRsa.txt + + + + + + + - - - - - - + - + - - - - - - - - - - - - - - - - - - - - - Common\System\Collections\DictionaryExtensions.cs - - - + + Microsoft.DotNet.XUnitExtensions + + + + + Address @@ -288,13 +289,6 @@ Utf8String - - Microsoft.DotNet.XUnitExtensions - - - - - @@ -315,7 +309,6 @@ - diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/ProviderAgnostic/ReaderTest/ReaderTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/ProviderAgnostic/ReaderTest/ReaderTest.cs index 697e57cb01..054d495760 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/ProviderAgnostic/ReaderTest/ReaderTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/ProviderAgnostic/ReaderTest/ReaderTest.cs @@ -2,7 +2,6 @@ // 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; using System.Data.Common; using System.IO; using System.Text; @@ -267,95 +266,5 @@ public static void TestMain() } } } - - /// - /// Covers GetFieldValue for SqlBuffer class - /// - [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup), nameof(DataTestUtility.IsNotAzureSynapse))] - public static void SqlDataReader_SqlBuffer_GetFieldValue() - { - string tableName = DataTestUtility.GetUniqueNameForSqlServer("SqlBuffer_GetFieldValue"); - DateTimeOffset dtoffset = DateTimeOffset.Now; - DateTime dt = DateTime.Now; - //Exclude the millisecond because of rounding at some points by SQL Server. - DateTime dateTime = new DateTime(dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute, dt.Second); - //Arrange - DbProviderFactory provider = SqlClientFactory.Instance; - - using DbConnection con = provider.CreateConnection(); - con.ConnectionString = DataTestUtility.TCPConnectionString; - con.Open(); - string sqlQueryOne = $"CREATE TABLE {tableName} ([CustomerId] [int],[FirstName] [nvarchar](50),[BoolCol] [BIT],[ShortCol] [SMALLINT],[ByteCol] [TINYINT],[LongCol] [BIGINT]);"; - string sqlQueryTwo = $"ALTER TABLE {tableName} ADD [DoubleCol] [FLOAT],[SingleCol] [REAL],[GUIDCol] [uniqueidentifier],[DateTimeCol] [DateTime],[DecimalCol] [SmallMoney],[DateTimeOffsetCol] [DateTimeOffset];"; - - try - { - using (DbCommand command = provider.CreateCommand()) - { - command.Connection = con; - command.CommandText = sqlQueryOne; - command.ExecuteNonQuery(); - } - using (DbCommand command = provider.CreateCommand()) - { - command.Connection = con; - command.CommandText = sqlQueryTwo; - command.ExecuteNonQuery(); - } - - System.Data.SqlTypes.SqlGuid sqlguid = new System.Data.SqlTypes.SqlGuid(Guid.NewGuid()); - - using (SqlCommand sqlCommand = new SqlCommand("", con as SqlConnection)) - { - sqlCommand.CommandText = $"INSERT INTO {tableName} " - + "VALUES (@CustomerId,@FirstName,@BoolCol,@ShortCol,@ByteCol,@LongCol,@DoubleCol,@SingleCol" - + ",@GUIDCol,@DateTimeCol,@DecimalCol,@DateTimeOffsetCol)"; - sqlCommand.Parameters.AddWithValue(@"CustomerId", 1); - sqlCommand.Parameters.AddWithValue(@"FirstName", "Microsoft"); - sqlCommand.Parameters.AddWithValue(@"BoolCol", true); - sqlCommand.Parameters.AddWithValue(@"ShortCol", 3274); - sqlCommand.Parameters.AddWithValue(@"ByteCol", 253); - sqlCommand.Parameters.AddWithValue(@"LongCol", 922222222222); - sqlCommand.Parameters.AddWithValue(@"DoubleCol", 10.7); - sqlCommand.Parameters.AddWithValue(@"SingleCol", 123.546f); - sqlCommand.Parameters.AddWithValue(@"GUIDCol", sqlguid); - sqlCommand.Parameters.AddWithValue(@"DateTimeCol", dateTime); - sqlCommand.Parameters.AddWithValue(@"DecimalCol", 280); - sqlCommand.Parameters.AddWithValue(@"DateTimeOffsetCol", dtoffset); - sqlCommand.ExecuteNonQuery(); - } - using (SqlCommand sqlCommand = new SqlCommand("", con as SqlConnection)) - { - sqlCommand.CommandText = "select top 1 * from " + tableName; - using (DbDataReader reader = sqlCommand.ExecuteReader()) - { - Assert.True(reader.Read()); - Assert.Equal(1, reader.GetFieldValue(0)); - Assert.Equal("Microsoft", reader.GetFieldValue(1)); - Assert.True(reader.GetFieldValue(2)); - Assert.Equal(3274, reader.GetFieldValue(3)); - Assert.Equal(253, reader.GetFieldValue(4)); - Assert.Equal(922222222222, reader.GetFieldValue(5)); - Assert.Equal(10.7, reader.GetFieldValue(6)); - Assert.Equal(123.546f, reader.GetFieldValue(7)); - Assert.Equal(sqlguid, reader.GetFieldValue(8)); - Assert.Equal(sqlguid.Value, reader.GetFieldValue(8).Value); - Assert.Equal(dateTime.ToString("dd/MM/yyyy HH:mm:ss.fff"), reader.GetFieldValue(9).ToString("dd/MM/yyyy HH:mm:ss.fff")); - Assert.Equal(280, reader.GetFieldValue(10)); - Assert.Equal(dtoffset, reader.GetFieldValue(11)); - } - } - } - finally - { - //cleanup - using (DbCommand cmd = provider.CreateCommand()) - { - cmd.Connection = con; - cmd.CommandText = "drop table " + tableName; - cmd.ExecuteNonQuery(); - } - } - } } } diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/AdapterTest/AdapterTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/AdapterTest/AdapterTest.cs index d00a9cf8b1..104a657133 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/AdapterTest/AdapterTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/AdapterTest/AdapterTest.cs @@ -1322,48 +1322,6 @@ public void TestReadOnlyColumnMetadata() } } - [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup), nameof(DataTestUtility.IsNotAzureSynapse))] - [InlineData(nameof(SqlCommandBuilder.GetInsertCommand), null)] - [InlineData(nameof(SqlCommandBuilder.GetInsertCommand), true)] - [InlineData(nameof(SqlCommandBuilder.GetInsertCommand), false)] - [InlineData(nameof(SqlCommandBuilder.GetUpdateCommand), null)] - [InlineData(nameof(SqlCommandBuilder.GetUpdateCommand), true)] - [InlineData(nameof(SqlCommandBuilder.GetUpdateCommand), false)] - [InlineData(nameof(SqlCommandBuilder.GetDeleteCommand), null)] - [InlineData(nameof(SqlCommandBuilder.GetDeleteCommand), false)] - [InlineData(nameof(SqlCommandBuilder.GetDeleteCommand), true)] - public void VerifyGetCommand(string methodName, bool? useColumnsForParameterNames) - { - using (SqlConnection connection = new SqlConnection(DataTestUtility.TCPConnectionString)) - { - connection.Open(); - using (SqlDataAdapter dataAdapter = new SqlDataAdapter("SELECT * FROM dbo.Customers", connection)) - { - using (SqlCommandBuilder commandBuilder = new SqlCommandBuilder(dataAdapter)) - { - object[] parameters = null; - Type[] parameterTypes = null; - if (useColumnsForParameterNames != null) - { - parameters = new object[] { useColumnsForParameterNames }; - parameterTypes = new Type[] { typeof(bool) }; - } - else - { - parameters = new object[] { }; - parameterTypes = new Type[] { }; - } - - MethodInfo method = commandBuilder.GetType().GetMethod(methodName, parameterTypes); - using (SqlCommand cmd = (SqlCommand)method.Invoke(commandBuilder, parameters)) - { - Assert.NotNull(cmd); - } - } - } - } - } - #region Utility_Methods private void CheckParameters(SqlCommand cmd, string expectedResults) { diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ConnectionPoolTest/ConnectionPoolTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ConnectionPoolTest/ConnectionPoolTest.cs index cfe74831f7..41a6404a20 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ConnectionPoolTest/ConnectionPoolTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ConnectionPoolTest/ConnectionPoolTest.cs @@ -185,11 +185,7 @@ public static void MaxPoolWaitForConnectionTest(string connectionString) ManualResetEventSlim taskAllowedToSpeak = new ManualResetEventSlim(false); Task waitTask = Task.Factory.StartNew(() => MaxPoolWaitForConnectionTask(newConnectionString, internalConnection, connectionPool, taskAllowedToSpeak)); - int count = 5; - while (waitTask.Status == TaskStatus.WaitingToRun && count-- > 0) - { - Thread.Sleep(200); - } + Thread.Sleep(200); Assert.Equal(TaskStatus.Running, waitTask.Status); connection1.Close(); diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ConnectivityTests/TcpDefaultForAzureTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ConnectivityTests/TcpDefaultForAzureTest.cs index f8271dfdc4..0128571616 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ConnectivityTests/TcpDefaultForAzureTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ConnectivityTests/TcpDefaultForAzureTest.cs @@ -38,24 +38,10 @@ static TcpDefaultForAzureTest() // The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. // (provider: Named Pipes Provider, error: 40 - Could not open a connection to SQL Server) [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup), nameof(DataTestUtility.IsNotAzureSynapse))] - [PlatformSpecific(TestPlatforms.Windows)] - public static void NonAzureNoProtocolConnectionTestWindows() + public static void NonAzureNoProtocolConnectionTest() { builder.DataSource = InvalidHostname; -#if NETFRAMEWORK - CheckConnectionFailure(builder.ConnectionString, NP); -#else CheckConnectionFailure(builder.ConnectionString, DataTestUtility.IsUsingManagedSNI() ? TCP : NP); -#endif - } - - [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup), nameof(DataTestUtility.IsNotAzureSynapse))] - [PlatformSpecific(TestPlatforms.Linux)] - public static void NonAzureNoProtocolConnectionTestLinux() - { - builder.DataSource = InvalidHostname; - // On Linux, TCP is the preferred protocol in use. - CheckConnectionFailure(builder.ConnectionString, TCP); } [Fact] diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/DataStreamTest/DataStreamTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/DataStreamTest/DataStreamTest.cs index 8026aa479c..2c5bce8c82 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/DataStreamTest/DataStreamTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/DataStreamTest/DataStreamTest.cs @@ -1555,14 +1555,8 @@ private static void ReadStream(string connectionString) DataTestUtility.AssertThrowsWrapper(() => stream.Read(null, 0, 1)); DataTestUtility.AssertThrowsWrapper(() => stream.Read(buffer, -1, 2)); DataTestUtility.AssertThrowsWrapper(() => stream.Read(buffer, 2, -1)); - - // ArgumentException is thrown in net5 and earlier. ArgumentOutOfRangeException in net6 and later - ArgumentException ex = Assert.ThrowsAny(() => stream.Read(buffer, buffer.Length, buffer.Length)); - Assert.True(ex.GetType() == typeof(ArgumentException) || ex.GetType() == typeof(ArgumentOutOfRangeException), - "Expected: ArgumentException in net5 and earlier. ArgumentOutOfRangeException in net6 and later."); - ex = Assert.ThrowsAny(() => stream.Read(buffer, int.MaxValue, int.MaxValue)); - Assert.True(ex.GetType() == typeof(ArgumentException) || ex.GetType() == typeof(ArgumentOutOfRangeException), - "Expected: ArgumentException in net5 and earlier. ArgumentOutOfRangeException in net6 and later."); + DataTestUtility.AssertThrowsWrapper(() => stream.Read(buffer, buffer.Length, buffer.Length)); + DataTestUtility.AssertThrowsWrapper(() => stream.Read(buffer, int.MaxValue, int.MaxValue)); } // Once Reader is closed diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/LocalDBTest/LocalDBTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/LocalDBTest/LocalDBTest.cs index 63edb9f926..ecbdb98a48 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/LocalDBTest/LocalDBTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/LocalDBTest/LocalDBTest.cs @@ -1,9 +1,7 @@ // 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; -using System.Diagnostics; -using System.Threading; +using System.Collections.Generic; using Xunit; namespace Microsoft.Data.SqlClient.ManualTesting.Tests @@ -15,18 +13,14 @@ public static class LocalDBTest private static readonly string s_localDbConnectionString = @$"server=(localdb)\{DataTestUtility.LocalDbAppName}"; private static readonly string[] s_sharedLocalDbInstances = new string[] { @$"server=(localdb)\.\{DataTestUtility.LocalDbSharedInstanceName}", @$"server=(localdb)\." }; private static readonly string s_badConnectionString = $@"server=(localdb)\{DataTestUtility.LocalDbAppName};Database=DOES_NOT_EXIST;Pooling=false;"; - private static readonly string s_commandPrompt = "cmd.exe"; - private static readonly string s_sqlLocalDbInfo = @$"/c SqlLocalDb info {DataTestUtility.LocalDbAppName}"; - private static readonly string s_startLocalDbCommand = @$"/c SqlLocalDb start {DataTestUtility.LocalDbAppName}"; - private static readonly string s_localDbNamedPipeConnectionString = @$"server={GetLocalDbNamedPipe()}"; + static string LocalDbName = DataTestUtility.LocalDbAppName; #region LocalDbTests [SkipOnTargetFramework(TargetFrameworkMonikers.Uap)] // No Registry support on UAP [ConditionalFact(nameof(IsLocalDBEnvironmentSet))] public static void SqlLocalDbConnectionTest() { ConnectionTest(s_localDbConnectionString); - ConnectionTest(s_localDbNamedPipeConnectionString); } [SkipOnTargetFramework(TargetFrameworkMonikers.Uap)] // No Registry support on UAP @@ -36,7 +30,6 @@ public static void LocalDBEncryptionNotSupportedTest() // Encryption is not supported by SQL Local DB. // But connection should succeed as encryption is disabled by driver. ConnectionWithEncryptionTest(s_localDbConnectionString); - ConnectionWithEncryptionTest(s_localDbNamedPipeConnectionString); } [SkipOnTargetFramework(TargetFrameworkMonikers.Uap)] // No Registry support on UAP @@ -44,7 +37,6 @@ public static void LocalDBEncryptionNotSupportedTest() public static void LocalDBMarsTest() { ConnectionWithMarsTest(s_localDbConnectionString); - ConnectionWithMarsTest(s_localDbNamedPipeConnectionString); } [SkipOnTargetFramework(TargetFrameworkMonikers.Uap)] // No Registry support on UAP @@ -131,39 +123,5 @@ private static void OpenConnection(string connString) var result = command.ExecuteScalar(); Assert.NotNull(result); } - - private static string GetLocalDbNamedPipe() - { - string state = ExecuteLocalDBCommandProcess(s_commandPrompt, s_sqlLocalDbInfo, "state"); - while (state.Equals("stopped", StringComparison.InvariantCultureIgnoreCase)) - { - state = ExecuteLocalDBCommandProcess(s_commandPrompt, s_startLocalDbCommand, "state"); - Thread.Sleep(2000); - } - return ExecuteLocalDBCommandProcess(s_commandPrompt, s_sqlLocalDbInfo, "pipeName"); - } - - private static string ExecuteLocalDBCommandProcess(string filename, string arguments, string infoType) - { - ProcessStartInfo sInfo = new() - { - FileName = filename, - Arguments = arguments, - UseShellExecute = false, - CreateNoWindow = false, - RedirectStandardOutput = true, - RedirectStandardError = true, - }; - string[] lines = Process.Start(sInfo).StandardOutput.ReadToEnd().Split(new string[] { Environment.NewLine }, StringSplitOptions.None); - if (infoType.Equals("state")) - { - return lines[5].Split(':')[1].Trim(); - } - else if (infoType.Equals("pipeName")) - { - return lines[7].Split(new string[] { "Instance pipe name:" }, StringSplitOptions.None)[1].Trim(); - } - return null; - } } } diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ParameterTest/DateTimeVariantTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ParameterTest/DateTimeVariantTest.cs index 31c232e3d0..8f6965d043 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ParameterTest/DateTimeVariantTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ParameterTest/DateTimeVariantTest.cs @@ -13,7 +13,7 @@ public static class DateTimeVariantTest private static string s_connStr; /// - /// Tests all 2008 DateTime types inside sql_variant to server using sql_variant parameter, SqlBulkCopy, and TVP parameter with sql_variant inside. + /// Tests all Katmai DateTime types inside sql_variant to server using sql_variant parameter, SqlBulkCopy, and TVP parameter with sql_variant inside. /// public static void TestAllDateTimeWithDataTypeAndVariant(string connStr) { @@ -78,20 +78,25 @@ private static void TestSimpleParameter_Type(object paramValue, string expectedT string procName = DataTestUtility.GetUniqueNameForSqlServer("paramProc1"); try { - using SqlConnection conn = new(s_connStr); - conn.Open(); - DropStoredProcedure(conn, procName); - xsql(conn, string.Format("create proc {0} (@param {1}) as begin select @param end;", procName, expectedBaseTypeName)); - - using SqlCommand cmd = conn.CreateCommand(); - cmd.CommandText = procName; - cmd.CommandType = CommandType.StoredProcedure; - SqlParameter p = cmd.Parameters.AddWithValue("@param", paramValue); - cmd.Parameters[0].SqlDbType = GetSqlDbType(expectedBaseTypeName); - using (SqlDataReader dr = cmd.ExecuteReader()) + using (SqlConnection conn = new SqlConnection(s_connStr)) { - dr.Read(); - VerifyReaderTypeAndValue("Test Simple Parameter [Data Type]", expectedBaseTypeName, expectedTypeName, dr[0], expectedTypeName, paramValue); + conn.Open(); + DropStoredProcedure(conn, procName); + xsql(conn, string.Format("create proc {0} (@param {1}) as begin select @param end;", procName, expectedBaseTypeName)); + + using (SqlCommand cmd = conn.CreateCommand()) + { + cmd.CommandText = procName; + cmd.CommandType = CommandType.StoredProcedure; + SqlParameter p = cmd.Parameters.AddWithValue("@param", paramValue); + cmd.Parameters[0].SqlDbType = GetSqlDbType(expectedBaseTypeName); + using (SqlDataReader dr = cmd.ExecuteReader()) + { + dr.Read(); + VerifyReaderTypeAndValue("Test Simple Parameter [Data Type]", expectedBaseTypeName, expectedTypeName, dr[0], expectedTypeName, paramValue); + dr.Dispose(); + } + } } } catch (Exception e) @@ -103,14 +108,16 @@ private static void TestSimpleParameter_Type(object paramValue, string expectedT } finally { - using SqlConnection conn = new(s_connStr); - conn.Open(); - DropStoredProcedure(conn, procName); + using (SqlConnection conn = new SqlConnection(s_connStr)) + { + conn.Open(); + DropStoredProcedure(conn, procName); + } } } // sql_variant parameters and sql_variant TVPs store all datetime values internally - // as datetime, hence breaking for 2008 types + // as datetime, hence breaking for katmai types private static void TestSimpleParameter_Variant(object paramValue, string expectedTypeName, string expectedBaseTypeName) { string tag = "TestSimpleParameter_Variant"; @@ -118,20 +125,25 @@ private static void TestSimpleParameter_Variant(object paramValue, string expect string procName = DataTestUtility.GetUniqueNameForSqlServer("paramProc2"); try { - using SqlConnection conn = new(s_connStr); - conn.Open(); - DropStoredProcedure(conn, procName); - xsql(conn, string.Format("create proc {0} (@param sql_variant) as begin select @param, sql_variant_property(@param,'BaseType') as BaseType end;", procName)); - - using SqlCommand cmd = conn.CreateCommand(); - cmd.CommandText = procName; - cmd.CommandType = CommandType.StoredProcedure; - SqlParameter p = cmd.Parameters.AddWithValue("@param", paramValue); - cmd.Parameters[0].SqlDbType = SqlDbType.Variant; - using (SqlDataReader dr = cmd.ExecuteReader()) + using (SqlConnection conn = new SqlConnection(s_connStr)) { - dr.Read(); - VerifyReaderTypeAndValue("Test Simple Parameter [Variant Type]", "SqlDbType.Variant", dr, expectedTypeName, expectedBaseTypeName, paramValue); + conn.Open(); + DropStoredProcedure(conn, procName); + xsql(conn, string.Format("create proc {0} (@param sql_variant) as begin select @param, sql_variant_property(@param,'BaseType') as BaseType end;", procName)); + + using (SqlCommand cmd = conn.CreateCommand()) + { + cmd.CommandText = procName; + cmd.CommandType = CommandType.StoredProcedure; + SqlParameter p = cmd.Parameters.AddWithValue("@param", paramValue); + cmd.Parameters[0].SqlDbType = SqlDbType.Variant; + using (SqlDataReader dr = cmd.ExecuteReader()) + { + dr.Read(); + VerifyReaderTypeAndValue("Test Simple Parameter [Variant Type]", "SqlDbType.Variant", dr, expectedTypeName, expectedBaseTypeName, paramValue); + dr.Dispose(); + } + } } } catch (Exception e) @@ -143,9 +155,11 @@ private static void TestSimpleParameter_Variant(object paramValue, string expect } finally { - using SqlConnection conn = new(s_connStr); - conn.Open(); - DropStoredProcedure(conn, procName); + using (SqlConnection conn = new SqlConnection(s_connStr)) + { + conn.Open(); + DropStoredProcedure(conn, procName); + } } } @@ -156,27 +170,32 @@ private static void TestSqlDataRecordParameterToTVP_Type(object paramValue, stri string tvpTypeName = DataTestUtility.GetUniqueNameForSqlServer("tvpType"); try { - using SqlConnection conn = new(s_connStr); - conn.Open(); - DropType(conn, tvpTypeName); - xsql(conn, string.Format("create type dbo.{0} as table (f1 {1})", tvpTypeName, expectedBaseTypeName)); - - // Send TVP using SqlMetaData. - SqlMetaData[] metadata = new SqlMetaData[1]; - metadata[0] = new SqlMetaData("f1", GetSqlDbType(expectedBaseTypeName)); - SqlDataRecord[] record = new SqlDataRecord[1]; - record[0] = new SqlDataRecord(metadata); - record[0].SetValue(0, paramValue); - - using SqlCommand cmd = conn.CreateCommand(); - cmd.CommandText = "select f1 from @tvpParam"; - SqlParameter p = cmd.Parameters.AddWithValue("@tvpParam", record); - p.SqlDbType = SqlDbType.Structured; - p.TypeName = string.Format("dbo.{0}", tvpTypeName); - using (SqlDataReader dr = cmd.ExecuteReader()) + using (SqlConnection conn = new SqlConnection(s_connStr)) { - dr.Read(); - VerifyReaderTypeAndValue("Test SqlDataRecord Parameter To TVP [Data Type]", expectedBaseTypeName, expectedTypeName, dr[0], expectedTypeName, paramValue); + conn.Open(); + DropType(conn, tvpTypeName); + xsql(conn, string.Format("create type dbo.{0} as table (f1 {1})", tvpTypeName, expectedBaseTypeName)); + + // Send TVP using SqlMetaData. + SqlMetaData[] metadata = new SqlMetaData[1]; + metadata[0] = new SqlMetaData("f1", GetSqlDbType(expectedBaseTypeName)); + SqlDataRecord[] record = new SqlDataRecord[1]; + record[0] = new SqlDataRecord(metadata); + record[0].SetValue(0, paramValue); + + using (SqlCommand cmd = conn.CreateCommand()) + { + cmd.CommandText = "select f1 from @tvpParam"; + SqlParameter p = cmd.Parameters.AddWithValue("@tvpParam", record); + p.SqlDbType = SqlDbType.Structured; + p.TypeName = string.Format("dbo.{0}", tvpTypeName); + using (SqlDataReader dr = cmd.ExecuteReader()) + { + dr.Read(); + VerifyReaderTypeAndValue("Test SqlDataRecord Parameter To TVP [Data Type]", expectedBaseTypeName, expectedTypeName, dr[0], expectedTypeName, paramValue); + dr.Dispose(); + } + } } } catch (Exception e) @@ -188,14 +207,16 @@ private static void TestSqlDataRecordParameterToTVP_Type(object paramValue, stri } finally { - using SqlConnection conn = new(s_connStr); - conn.Open(); - DropType(conn, tvpTypeName); + using (SqlConnection conn = new SqlConnection(s_connStr)) + { + conn.Open(); + DropType(conn, tvpTypeName); + } } } // sql_variant parameters and sql_variant TVPs store all datetime values internally - // as datetime, hence breaking for 2008 types + // as datetime, hence breaking for katmai types private static void TestSqlDataRecordParameterToTVP_Variant(object paramValue, string expectedTypeName, string expectedBaseTypeName) { string tag = "TestSqlDataRecordParameterToTVP_Variant"; @@ -203,27 +224,32 @@ private static void TestSqlDataRecordParameterToTVP_Variant(object paramValue, s string tvpTypeName = DataTestUtility.GetUniqueNameForSqlServer("tvpVariant"); try { - using SqlConnection conn = new(s_connStr); - conn.Open(); - DropType(conn, tvpTypeName); - xsql(conn, string.Format("create type dbo.{0} as table (f1 sql_variant)", tvpTypeName)); - - // Send TVP using SqlMetaData. - SqlMetaData[] metadata = new SqlMetaData[1]; - metadata[0] = new SqlMetaData("f1", SqlDbType.Variant); - SqlDataRecord[] record = new SqlDataRecord[1]; - record[0] = new SqlDataRecord(metadata); - record[0].SetValue(0, paramValue); - - using SqlCommand cmd = conn.CreateCommand(); - cmd.CommandText = "select f1, sql_variant_property(f1,'BaseType') as BaseType from @tvpParam"; - SqlParameter p = cmd.Parameters.AddWithValue("@tvpParam", record); - p.SqlDbType = SqlDbType.Structured; - p.TypeName = string.Format("dbo.{0}", tvpTypeName); - using (SqlDataReader dr = cmd.ExecuteReader()) + using (SqlConnection conn = new SqlConnection(s_connStr)) { - dr.Read(); - VerifyReaderTypeAndValue("Test SqlDataRecord Parameter To TVP [Variant Type]", "SqlDbType.Variant", dr, expectedTypeName, expectedBaseTypeName, paramValue); + conn.Open(); + DropType(conn, tvpTypeName); + xsql(conn, string.Format("create type dbo.{0} as table (f1 sql_variant)", tvpTypeName)); + + // Send TVP using SqlMetaData. + SqlMetaData[] metadata = new SqlMetaData[1]; + metadata[0] = new SqlMetaData("f1", SqlDbType.Variant); + SqlDataRecord[] record = new SqlDataRecord[1]; + record[0] = new SqlDataRecord(metadata); + record[0].SetValue(0, paramValue); + + using (SqlCommand cmd = conn.CreateCommand()) + { + cmd.CommandText = "select f1, sql_variant_property(f1,'BaseType') as BaseType from @tvpParam"; + SqlParameter p = cmd.Parameters.AddWithValue("@tvpParam", record); + p.SqlDbType = SqlDbType.Structured; + p.TypeName = string.Format("dbo.{0}", tvpTypeName); + using (SqlDataReader dr = cmd.ExecuteReader()) + { + dr.Read(); + VerifyReaderTypeAndValue("Test SqlDataRecord Parameter To TVP [Variant Type]", "SqlDbType.Variant", dr, expectedTypeName, expectedBaseTypeName, paramValue); + dr.Dispose(); + } + } } } catch (Exception e) @@ -235,9 +261,11 @@ private static void TestSqlDataRecordParameterToTVP_Variant(object paramValue, s } finally { - using SqlConnection conn = new(s_connStr); - conn.Open(); - DropType(conn, tvpTypeName); + using (SqlConnection conn = new SqlConnection(s_connStr)) + { + conn.Open(); + DropType(conn, tvpTypeName); + } } } @@ -248,29 +276,41 @@ private static void TestSqlDataReaderParameterToTVP_Type(object paramValue, stri string tvpTypeName = DataTestUtility.GetUniqueNameForSqlServer("tvpType"); try { - using SqlConnection conn = new(s_connStr); - conn.Open(); - DropType(conn, tvpTypeName); - xsql(conn, string.Format("create type dbo.{0} as table (f1 {1})", tvpTypeName, expectedBaseTypeName)); - using (SqlConnection connInput = new(s_connStr)) + using (SqlConnection conn = new SqlConnection(s_connStr)) { - connInput.Open(); - using (SqlCommand cmdInput = connInput.CreateCommand()) + conn.Open(); + DropType(conn, tvpTypeName); + xsql(conn, string.Format("create type dbo.{0} as table (f1 {1})", tvpTypeName, expectedBaseTypeName)); + + // Send TVP using SqlDataReader. + using (SqlConnection connInput = new SqlConnection(s_connStr)) { - cmdInput.CommandText = "select @p1 as f1"; - cmdInput.Parameters.Add("@p1", GetSqlDbType(expectedBaseTypeName)); - cmdInput.Parameters["@p1"].Value = paramValue; - using SqlDataReader drInput = cmdInput.ExecuteReader(CommandBehavior.CloseConnection); - using SqlCommand cmd = conn.CreateCommand(); - cmd.CommandText = "select f1 from @tvpParam"; - SqlParameter p = cmd.Parameters.AddWithValue("@tvpParam", drInput); - p.SqlDbType = SqlDbType.Structured; - p.TypeName = string.Format("dbo.{0}", tvpTypeName); - using (SqlDataReader dr = cmd.ExecuteReader()) + connInput.Open(); + + using (SqlCommand cmdInput = connInput.CreateCommand()) { - dr.Read(); - VerifyReaderTypeAndValue("Test SqlDataReader Parameter To TVP [Data Type]", expectedBaseTypeName, expectedTypeName, dr[0], expectedTypeName, paramValue); + cmdInput.CommandText = "select @p1 as f1"; + cmdInput.Parameters.Add("@p1", GetSqlDbType(expectedBaseTypeName)); + cmdInput.Parameters["@p1"].Value = paramValue; + + using (SqlDataReader drInput = cmdInput.ExecuteReader(CommandBehavior.CloseConnection)) + { + using (SqlCommand cmd = conn.CreateCommand()) + { + cmd.CommandText = "select f1 from @tvpParam"; + SqlParameter p = cmd.Parameters.AddWithValue("@tvpParam", drInput); + p.SqlDbType = SqlDbType.Structured; + p.TypeName = string.Format("dbo.{0}", tvpTypeName); + using (SqlDataReader dr = cmd.ExecuteReader()) + { + dr.Read(); + VerifyReaderTypeAndValue("Test SqlDataReader Parameter To TVP [Data Type]", expectedBaseTypeName, expectedTypeName, dr[0], expectedTypeName, paramValue); + dr.Dispose(); + } + } + } } + connInput.Close(); } } } @@ -283,14 +323,16 @@ private static void TestSqlDataReaderParameterToTVP_Type(object paramValue, stri } finally { - using SqlConnection conn = new(s_connStr); - conn.Open(); - DropType(conn, tvpTypeName); + using (SqlConnection conn = new SqlConnection(s_connStr)) + { + conn.Open(); + DropType(conn, tvpTypeName); + } } } // sql_variant parameters and sql_variant TVPs store all datetime values internally - // as datetime, hence breaking for 2008 types + // as datetime, hence breaking for katmai types private static void TestSqlDataReaderParameterToTVP_Variant(object paramValue, string expectedTypeName, string expectedBaseTypeName) { string tag = "TestSqlDataReaderParameterToTVP_Variant"; @@ -298,31 +340,39 @@ private static void TestSqlDataReaderParameterToTVP_Variant(object paramValue, s string tvpTypeName = DataTestUtility.GetUniqueNameForSqlServer("tvpVariant"); try { - using SqlConnection conn = new(s_connStr); - conn.Open(); - DropType(conn, tvpTypeName); - xsql(conn, string.Format("create type dbo.{0} as table (f1 sql_variant)", tvpTypeName)); - - // Send TVP using SqlDataReader. - using (SqlConnection connInput = new(s_connStr)) + using (SqlConnection conn = new SqlConnection(s_connStr)) { - connInput.Open(); - using (SqlCommand cmdInput = connInput.CreateCommand()) + conn.Open(); + DropType(conn, tvpTypeName); + xsql(conn, string.Format("create type dbo.{0} as table (f1 sql_variant)", tvpTypeName)); + + // Send TVP using SqlDataReader. + using (SqlConnection connInput = new SqlConnection(s_connStr)) { - cmdInput.CommandText = "select @p1 as f1"; - cmdInput.Parameters.Add("@p1", SqlDbType.Variant); - cmdInput.Parameters["@p1"].Value = paramValue; - using SqlDataReader drInput = cmdInput.ExecuteReader(CommandBehavior.CloseConnection); - using SqlCommand cmd = conn.CreateCommand(); - cmd.CommandText = "select f1, sql_variant_property(f1,'BaseType') as BaseType from @tvpParam"; - SqlParameter p = cmd.Parameters.AddWithValue("@tvpParam", drInput); - p.SqlDbType = SqlDbType.Structured; - p.TypeName = string.Format("dbo.{0}", tvpTypeName); - using (SqlDataReader dr = cmd.ExecuteReader()) + connInput.Open(); + using (SqlCommand cmdInput = connInput.CreateCommand()) { - dr.Read(); - VerifyReaderTypeAndValue("Test SqlDataReader Parameter To TVP [Variant Type]", "SqlDbType.Variant", dr, expectedTypeName, expectedBaseTypeName, paramValue); + cmdInput.CommandText = "select @p1 as f1"; + cmdInput.Parameters.Add("@p1", SqlDbType.Variant); + cmdInput.Parameters["@p1"].Value = paramValue; + using (SqlDataReader drInput = cmdInput.ExecuteReader(CommandBehavior.CloseConnection)) + { + using (SqlCommand cmd = conn.CreateCommand()) + { + cmd.CommandText = "select f1, sql_variant_property(f1,'BaseType') as BaseType from @tvpParam"; + SqlParameter p = cmd.Parameters.AddWithValue("@tvpParam", drInput); + p.SqlDbType = SqlDbType.Structured; + p.TypeName = string.Format("dbo.{0}", tvpTypeName); + using (SqlDataReader dr = cmd.ExecuteReader()) + { + dr.Read(); + VerifyReaderTypeAndValue("Test SqlDataReader Parameter To TVP [Variant Type]", "SqlDbType.Variant", dr, expectedTypeName, expectedBaseTypeName, paramValue); + dr.Dispose(); + } + } + } } + connInput.Close(); } } } @@ -335,14 +385,16 @@ private static void TestSqlDataReaderParameterToTVP_Variant(object paramValue, s } finally { - using SqlConnection conn = new(s_connStr); - conn.Open(); - DropType(conn, tvpTypeName); + using (SqlConnection conn = new SqlConnection(s_connStr)) + { + conn.Open(); + DropType(conn, tvpTypeName); + } } } // sql_variant parameters and sql_variant TVPs store all datetime values internally - // as datetime, hence breaking for 2008 types + // as datetime, hence breaking for katmai types private static void TestSqlDataReader_TVP_Type(object paramValue, string expectedTypeName, string expectedBaseTypeName) { string tag = "TestSqlDataReader_TVP_Type"; @@ -353,56 +405,61 @@ private static void TestSqlDataReader_TVP_Type(object paramValue, string expecte string ProcName = DataTestUtility.GetUniqueNameForSqlServer("spTVPProc"); try { - using SqlConnection conn = new(s_connStr); - conn.Open(); - - DropStoredProcedure(conn, ProcName); - DropTable(conn, InputTableName); - DropTable(conn, OutputTableName); - DropType(conn, $"dbo.{tvpTypeName}"); + using (SqlConnection conn = new SqlConnection(s_connStr)) + { + conn.Open(); - xsql(conn, string.Format("create type dbo.{0} as table (f1 {1})", tvpTypeName, expectedBaseTypeName)); - xsql(conn, string.Format("create table {0} (f1 {1})", InputTableName, expectedBaseTypeName)); - xsql(conn, string.Format("create table {0} (f1 {1})", OutputTableName, expectedBaseTypeName)); + DropStoredProcedure(conn, ProcName); + DropTable(conn, InputTableName); + DropTable(conn, OutputTableName); + DropType(conn, $"dbo.{tvpTypeName}"); - string value = string.Empty; - if (paramValue.GetType() == typeof(DateTimeOffset)) - { - DateTime dt = ((DateTimeOffset)paramValue).UtcDateTime; - value = dt.ToString("M/d/yyyy") + " " + dt.TimeOfDay; - } - else if (paramValue.GetType() == typeof(TimeSpan)) - { - value = ((TimeSpan)paramValue).ToString(); - } - else - { - value = ((DateTime)paramValue).ToString("M/d/yyyy") + " " + ((DateTime)paramValue).TimeOfDay; - } - xsql(conn, string.Format("insert into {0} values(CAST('{1}' AS {2}))", InputTableName, value, expectedBaseTypeName)); - xsql(conn, string.Format("create proc {0} (@P {1} READONLY) as begin insert into {2} select * from @P; end", ProcName, tvpTypeName, OutputTableName)); + xsql(conn, string.Format("create type dbo.{0} as table (f1 {1})", tvpTypeName, expectedBaseTypeName)); + xsql(conn, string.Format("create table {0} (f1 {1})", InputTableName, expectedBaseTypeName)); + xsql(conn, string.Format("create table {0} (f1 {1})", OutputTableName, expectedBaseTypeName)); - SqlCommand cmd = conn.CreateCommand(); - cmd.CommandText = string.Format("SELECT * FROM {0}", InputTableName); - using SqlDataReader r = cmd.ExecuteReader(); - using (SqlConnection conn2 = new(s_connStr)) - { - conn2.Open(); - SqlCommand cmd2 = new(ProcName, conn2) + string value = string.Empty; + if (paramValue.GetType() == typeof(System.DateTimeOffset)) { - CommandType = CommandType.StoredProcedure - }; - SqlParameter p = cmd2.Parameters.AddWithValue("@P", r); - p.SqlDbType = SqlDbType.Structured; - p.TypeName = tvpTypeName; - cmd2.ExecuteNonQuery(); - - cmd2.CommandText = string.Format("SELECT f1 FROM {0}", OutputTableName); - cmd2.CommandType = CommandType.Text; - using (SqlDataReader dr = cmd2.ExecuteReader()) + DateTime dt = ((System.DateTimeOffset)paramValue).UtcDateTime; + value = dt.ToString("M/d/yyyy") + " " + dt.TimeOfDay; + } + else if (paramValue.GetType() == typeof(System.TimeSpan)) + { + value = ((System.TimeSpan)paramValue).ToString(); + } + else + { + value = ((System.DateTime)paramValue).ToString("M/d/yyyy") + " " + ((System.DateTime)paramValue).TimeOfDay; + } + xsql(conn, string.Format("insert into {0} values(CAST('{1}' AS {2}))", InputTableName, value, expectedBaseTypeName)); + xsql(conn, string.Format("create proc {0} (@P {1} READONLY) as begin insert into {2} select * from @P; end", ProcName, tvpTypeName, OutputTableName)); + + SqlCommand cmd = conn.CreateCommand(); + cmd.CommandText = string.Format("SELECT * FROM {0}", InputTableName); + using (SqlDataReader r = cmd.ExecuteReader()) { - dr.Read(); - VerifyReaderTypeAndValue("Test SqlDataReader TVP [Data Type]", expectedBaseTypeName, expectedTypeName, dr[0], expectedTypeName, paramValue); + using (SqlConnection conn2 = new SqlConnection(s_connStr)) + { + conn2.Open(); + SqlCommand cmd2 = new SqlCommand(ProcName, conn2); + cmd2.CommandType = CommandType.StoredProcedure; + SqlParameter p = cmd2.Parameters.AddWithValue("@P", r); + p.SqlDbType = SqlDbType.Structured; + p.TypeName = tvpTypeName; + cmd2.ExecuteNonQuery(); + + cmd2.CommandText = string.Format("SELECT f1 FROM {0}", OutputTableName); + ; + cmd2.CommandType = CommandType.Text; + using (SqlDataReader dr = cmd2.ExecuteReader()) + { + dr.Read(); + VerifyReaderTypeAndValue("Test SqlDataReader TVP [Data Type]", expectedBaseTypeName, expectedTypeName, dr[0], expectedTypeName, paramValue); + dr.Dispose(); + } + conn2.Close(); + } } } } @@ -415,12 +472,14 @@ private static void TestSqlDataReader_TVP_Type(object paramValue, string expecte } finally { - using SqlConnection conn = new(s_connStr); - conn.Open(); - DropStoredProcedure(conn, ProcName); - DropTable(conn, InputTableName); - DropTable(conn, OutputTableName); - DropType(conn, tvpTypeName); + using (SqlConnection conn = new SqlConnection(s_connStr)) + { + conn.Open(); + DropStoredProcedure(conn, ProcName); + DropTable(conn, InputTableName); + DropTable(conn, OutputTableName); + DropType(conn, tvpTypeName); + } } } @@ -434,56 +493,60 @@ private static void TestSqlDataReader_TVP_Variant(object paramValue, string expe string ProcName = DataTestUtility.GetUniqueNameForSqlServer("spTVPProc_DRdrTVPVar"); try { - using SqlConnection conn = new(s_connStr); - conn.Open(); - - DropStoredProcedure(conn, ProcName); - DropTable(conn, InputTableName); - DropTable(conn, OutputTableName); - DropType(conn, tvpTypeName); + using (SqlConnection conn = new SqlConnection(s_connStr)) + { + conn.Open(); - xsql(conn, string.Format("create type {0} as table (f1 sql_variant)", tvpTypeName)); - xsql(conn, string.Format("create table {0} (f1 sql_variant)", InputTableName)); - xsql(conn, string.Format("create table {0} (f1 sql_variant)", OutputTableName)); + DropStoredProcedure(conn, ProcName); + DropTable(conn, InputTableName); + DropTable(conn, OutputTableName); + DropType(conn, tvpTypeName); - string value = string.Empty; - if (paramValue.GetType() == typeof(DateTimeOffset)) - { - DateTime dt = ((DateTimeOffset)paramValue).UtcDateTime; - value = dt.ToString("M/d/yyyy") + " " + dt.TimeOfDay; - } - else if (paramValue.GetType() == typeof(TimeSpan)) - { - value = ((TimeSpan)paramValue).ToString(); - } - else - { - value = ((DateTime)paramValue).ToString("M/d/yyyy") + " " + ((DateTime)paramValue).TimeOfDay; - } - xsql(conn, string.Format("insert into {0} values(CAST('{1}' AS {2}))", InputTableName, value, expectedBaseTypeName)); - xsql(conn, string.Format("create proc {0} (@P {1} READONLY) as begin insert into {2} select * from @P; end", ProcName, tvpTypeName, OutputTableName)); + xsql(conn, string.Format("create type {0} as table (f1 sql_variant)", tvpTypeName)); + xsql(conn, string.Format("create table {0} (f1 sql_variant)", InputTableName)); + xsql(conn, string.Format("create table {0} (f1 sql_variant)", OutputTableName)); - SqlCommand cmd = conn.CreateCommand(); - cmd.CommandText = string.Format("SELECT * FROM {0}", InputTableName); - using SqlDataReader r = cmd.ExecuteReader(); - using (SqlConnection conn2 = new(s_connStr)) - { - conn2.Open(); - using (SqlCommand cmd2 = new(ProcName, conn2)) + string value = string.Empty; + if (paramValue.GetType() == typeof(System.DateTimeOffset)) { - cmd2.CommandType = CommandType.StoredProcedure; - SqlParameter p = cmd2.Parameters.AddWithValue("@P", r); - p.SqlDbType = SqlDbType.Structured; - p.TypeName = tvpTypeName; - cmd2.ExecuteNonQuery(); + DateTime dt = ((System.DateTimeOffset)paramValue).UtcDateTime; + value = dt.ToString("M/d/yyyy") + " " + dt.TimeOfDay; + } + else if (paramValue.GetType() == typeof(System.TimeSpan)) + { + value = ((System.TimeSpan)paramValue).ToString(); + } + else + { + value = ((System.DateTime)paramValue).ToString("M/d/yyyy") + " " + ((System.DateTime)paramValue).TimeOfDay; + } + xsql(conn, string.Format("insert into {0} values(CAST('{1}' AS {2}))", InputTableName, value, expectedBaseTypeName)); + xsql(conn, string.Format("create proc {0} (@P {1} READONLY) as begin insert into {2} select * from @P; end", ProcName, tvpTypeName, OutputTableName)); - cmd2.CommandText = string.Format("SELECT f1, sql_variant_property(f1,'BaseType') as BaseType FROM {0}", OutputTableName); - ; - cmd2.CommandType = CommandType.Text; - using (SqlDataReader dr = cmd2.ExecuteReader()) + SqlCommand cmd = conn.CreateCommand(); + cmd.CommandText = string.Format("SELECT * FROM {0}", InputTableName); + using (SqlDataReader r = cmd.ExecuteReader()) + { + using (SqlConnection conn2 = new SqlConnection(s_connStr)) { - dr.Read(); - VerifyReaderTypeAndValue("Test SqlDataReader TVP [Variant Type]", "SqlDbType.Variant", dr, expectedTypeName, expectedBaseTypeName, paramValue); + conn2.Open(); + SqlCommand cmd2 = new SqlCommand(ProcName, conn2); + cmd2.CommandType = CommandType.StoredProcedure; + SqlParameter p = cmd2.Parameters.AddWithValue("@P", r); + p.SqlDbType = SqlDbType.Structured; + p.TypeName = tvpTypeName; + cmd2.ExecuteNonQuery(); + + cmd2.CommandText = string.Format("SELECT f1, sql_variant_property(f1,'BaseType') as BaseType FROM {0}", OutputTableName); + ; + cmd2.CommandType = CommandType.Text; + using (SqlDataReader dr = cmd2.ExecuteReader()) + { + dr.Read(); + VerifyReaderTypeAndValue("Test SqlDataReader TVP [Variant Type]", "SqlDbType.Variant", dr, expectedTypeName, expectedBaseTypeName, paramValue); + dr.Dispose(); + } + conn2.Close(); } } } @@ -497,17 +560,19 @@ private static void TestSqlDataReader_TVP_Variant(object paramValue, string expe } finally { - using SqlConnection conn = new(s_connStr); - conn.Open(); - DropStoredProcedure(conn, ProcName); - DropTable(conn, InputTableName); - DropTable(conn, OutputTableName); - DropType(conn, tvpTypeName); + using (SqlConnection conn = new SqlConnection(s_connStr)) + { + conn.Open(); + DropStoredProcedure(conn, ProcName); + DropTable(conn, InputTableName); + DropTable(conn, OutputTableName); + DropType(conn, tvpTypeName); + } } } // sql_variant parameters and sql_variant TVPs store all datetime values internally - // as datetime, hence breaking for 2008 types + // as datetime, hence breaking for katmai types private static void TestSimpleDataReader_Type(object paramValue, string expectedTypeName, string expectedBaseTypeName) { string tag = "TestSimpleDataReader_Type"; @@ -516,36 +581,41 @@ private static void TestSimpleDataReader_Type(object paramValue, string expected string procName = DataTestUtility.GetUniqueNameForSqlServer("paramProc3"); try { - using SqlConnection conn = new(s_connStr); - conn.Open(); - DropTable(conn, inputTable); - DropStoredProcedure(conn, procName); - - string value = string.Empty; - if (paramValue.GetType() == typeof(DateTimeOffset)) - { - DateTime dt = ((DateTimeOffset)paramValue).UtcDateTime; - value = dt.ToString("M/d/yyyy") + " " + dt.TimeOfDay; - } - else if (paramValue.GetType() == typeof(TimeSpan)) - { - value = ((TimeSpan)paramValue).ToString(); - } - else - { - value = ((DateTime)paramValue).ToString("M/d/yyyy") + " " + ((DateTime)paramValue).TimeOfDay; - } - xsql(conn, string.Format("create table {0} (f1 {1})", inputTable, expectedBaseTypeName)); - xsql(conn, string.Format("insert into {0}(f1) values('{1}');", inputTable, value)); - xsql(conn, string.Format("create proc {0} as begin select f1 from {1} end;", procName, inputTable)); - - using SqlCommand cmd = conn.CreateCommand(); - cmd.CommandText = procName; - cmd.CommandType = CommandType.StoredProcedure; - using (SqlDataReader dr = cmd.ExecuteReader()) + using (SqlConnection conn = new SqlConnection(s_connStr)) { - dr.Read(); - VerifyReaderTypeAndValue("Test Simple Data Reader [Data Type]", expectedBaseTypeName, expectedTypeName, dr[0], expectedTypeName, paramValue); + conn.Open(); + DropTable(conn, inputTable); + DropStoredProcedure(conn, procName); + + string value = string.Empty; + if (paramValue.GetType() == typeof(System.DateTimeOffset)) + { + DateTime dt = ((System.DateTimeOffset)paramValue).UtcDateTime; + value = dt.ToString("M/d/yyyy") + " " + dt.TimeOfDay; + } + else if (paramValue.GetType() == typeof(System.TimeSpan)) + { + value = ((System.TimeSpan)paramValue).ToString(); + } + else + { + value = ((System.DateTime)paramValue).ToString("M/d/yyyy") + " " + ((System.DateTime)paramValue).TimeOfDay; + } + xsql(conn, string.Format("create table {0} (f1 {1})", inputTable, expectedBaseTypeName)); + xsql(conn, string.Format("insert into {0}(f1) values('{1}');", inputTable, value)); + xsql(conn, string.Format("create proc {0} as begin select f1 from {1} end;", procName, inputTable)); + + using (SqlCommand cmd = conn.CreateCommand()) + { + cmd.CommandText = procName; + cmd.CommandType = CommandType.StoredProcedure; + using (SqlDataReader dr = cmd.ExecuteReader()) + { + dr.Read(); + VerifyReaderTypeAndValue("Test Simple Data Reader [Data Type]", expectedBaseTypeName, expectedTypeName, dr[0], expectedTypeName, paramValue); + dr.Dispose(); + } + } } } catch (Exception e) @@ -557,10 +627,12 @@ private static void TestSimpleDataReader_Type(object paramValue, string expected } finally { - using SqlConnection conn = new(s_connStr); - conn.Open(); - DropStoredProcedure(conn, procName); - DropTable(conn, inputTable); + using (SqlConnection conn = new SqlConnection(s_connStr)) + { + conn.Open(); + DropStoredProcedure(conn, procName); + DropTable(conn, inputTable); + } } } @@ -572,36 +644,41 @@ private static void TestSimpleDataReader_Variant(object paramValue, string expec string procName = DataTestUtility.GetUniqueNameForSqlServer("paramProc4"); try { - using SqlConnection conn = new(s_connStr); - conn.Open(); - DropTable(conn, inputTable); - DropStoredProcedure(conn, procName); - - string value = string.Empty; - if (paramValue.GetType() == typeof(DateTimeOffset)) - { - DateTime dt = ((DateTimeOffset)paramValue).UtcDateTime; - value = dt.ToString("M/d/yyyy") + " " + dt.TimeOfDay; - } - else if (paramValue.GetType() == typeof(TimeSpan)) - { - value = ((TimeSpan)paramValue).ToString(); - } - else - { - value = ((DateTime)paramValue).ToString("M/d/yyyy") + " " + ((DateTime)paramValue).TimeOfDay; - } - xsql(conn, string.Format("create table {0} (f1 sql_variant)", inputTable)); - xsql(conn, string.Format("insert into {0}(f1) values(CAST('{1}' AS {2}));", inputTable, value, expectedBaseTypeName)); - xsql(conn, string.Format("create proc {0} as begin select f1, sql_variant_property(f1,'BaseType') as BaseType from {1} end;", procName, inputTable)); - - using SqlCommand cmd = conn.CreateCommand(); - cmd.CommandText = procName; - cmd.CommandType = CommandType.StoredProcedure; - using (SqlDataReader dr = cmd.ExecuteReader()) + using (SqlConnection conn = new SqlConnection(s_connStr)) { - dr.Read(); - VerifyReaderTypeAndValue("Test Simple Data Reader [Variant Type]", "SqlDbType.Variant", dr, expectedTypeName, expectedBaseTypeName, paramValue); + conn.Open(); + DropTable(conn, inputTable); + DropStoredProcedure(conn, procName); + + string value = string.Empty; + if (paramValue.GetType() == typeof(System.DateTimeOffset)) + { + DateTime dt = ((System.DateTimeOffset)paramValue).UtcDateTime; + value = dt.ToString("M/d/yyyy") + " " + dt.TimeOfDay; + } + else if (paramValue.GetType() == typeof(System.TimeSpan)) + { + value = ((System.TimeSpan)paramValue).ToString(); + } + else + { + value = ((System.DateTime)paramValue).ToString("M/d/yyyy") + " " + ((System.DateTime)paramValue).TimeOfDay; + } + xsql(conn, string.Format("create table {0} (f1 sql_variant)", inputTable)); + xsql(conn, string.Format("insert into {0}(f1) values(CAST('{1}' AS {2}));", inputTable, value, expectedBaseTypeName)); + xsql(conn, string.Format("create proc {0} as begin select f1, sql_variant_property(f1,'BaseType') as BaseType from {1} end;", procName, inputTable)); + + using (SqlCommand cmd = conn.CreateCommand()) + { + cmd.CommandText = procName; + cmd.CommandType = CommandType.StoredProcedure; + using (SqlDataReader dr = cmd.ExecuteReader()) + { + dr.Read(); + VerifyReaderTypeAndValue("Test Simple Data Reader [Variant Type]", "SqlDbType.Variant", dr, expectedTypeName, expectedBaseTypeName, paramValue); + dr.Dispose(); + } + } } } catch (Exception e) @@ -613,10 +690,12 @@ private static void TestSimpleDataReader_Variant(object paramValue, string expec } finally { - using SqlConnection conn = new(s_connStr); - conn.Open(); - DropStoredProcedure(conn, procName); - DropTable(conn, inputTable); + using (SqlConnection conn = new SqlConnection(s_connStr)) + { + conn.Open(); + DropStoredProcedure(conn, procName); + DropTable(conn, inputTable); + } } } @@ -628,54 +707,63 @@ private static void SqlBulkCopySqlDataReader_Type(object paramValue, string expe string bulkCopyTableName = DataTestUtility.GetUniqueNameForSqlServer("bulkDestTable"); try { - using SqlConnection conn = new(s_connStr); - conn.Open(); - DropTable(conn, bulkCopyTableName); - xsql(conn, string.Format("create table {0} (f1 {1})", bulkCopyTableName, expectedBaseTypeName)); - - DropTable(conn, bulkCopySrcTableName); - xsql(conn, string.Format("create table {0} (f1 {1})", bulkCopySrcTableName, expectedBaseTypeName)); - string value = string.Empty; - if (paramValue.GetType() == typeof(DateTimeOffset)) + using (SqlConnection conn = new SqlConnection(s_connStr)) { - DateTime dt = ((DateTimeOffset)paramValue).UtcDateTime; - value = dt.ToString("M/d/yyyy") + " " + dt.TimeOfDay; - } - else if (paramValue.GetType() == typeof(TimeSpan)) - { - value = ((TimeSpan)paramValue).ToString(); - } - else - { - value = ((DateTime)paramValue).ToString("M/d/yyyy") + " " + ((DateTime)paramValue).TimeOfDay; - } - xsql(conn, string.Format("insert into {0}(f1) values(CAST('{1}' AS {2}));", bulkCopySrcTableName, value, expectedBaseTypeName)); - - using SqlConnection connInput = new(s_connStr); - connInput.Open(); - using (SqlCommand cmdInput = connInput.CreateCommand()) - { - cmdInput.CommandText = string.Format("select * from {0}", bulkCopySrcTableName); - using SqlDataReader drInput = cmdInput.ExecuteReader(); - // Perform bulk copy to target. - using (SqlBulkCopy bulkCopy = new(conn)) + conn.Open(); + DropTable(conn, bulkCopyTableName); + xsql(conn, string.Format("create table {0} (f1 {1})", bulkCopyTableName, expectedBaseTypeName)); + + DropTable(conn, bulkCopySrcTableName); + xsql(conn, string.Format("create table {0} (f1 {1})", bulkCopySrcTableName, expectedBaseTypeName)); + string value = string.Empty; + if (paramValue.GetType() == typeof(System.DateTimeOffset)) { - bulkCopy.BulkCopyTimeout = 60; - bulkCopy.BatchSize = 1; - bulkCopy.DestinationTableName = bulkCopyTableName; - bulkCopy.WriteToServer(drInput); + DateTime dt = ((System.DateTimeOffset)paramValue).UtcDateTime; + value = dt.ToString("M/d/yyyy") + " " + dt.TimeOfDay; + } + else if (paramValue.GetType() == typeof(System.TimeSpan)) + { + value = ((System.TimeSpan)paramValue).ToString(); } + else + { + value = ((System.DateTime)paramValue).ToString("M/d/yyyy") + " " + ((System.DateTime)paramValue).TimeOfDay; + } + xsql(conn, string.Format("insert into {0}(f1) values(CAST('{1}' AS {2}));", bulkCopySrcTableName, value, expectedBaseTypeName)); - // Verify target. - using SqlCommand cmd = conn.CreateCommand(); - cmd.CommandText = string.Format("select f1 from {0}", bulkCopyTableName); - using (SqlDataReader drVerify = cmd.ExecuteReader()) + using (SqlConnection connInput = new SqlConnection(s_connStr)) { - drVerify.Read(); - VerifyReaderTypeAndValue("SqlBulkCopy From SqlDataReader [Data Type]", expectedBaseTypeName, expectedTypeName, drVerify[0], expectedTypeName, paramValue); + connInput.Open(); + using (SqlCommand cmdInput = connInput.CreateCommand()) + { + cmdInput.CommandText = string.Format("select * from {0}", bulkCopySrcTableName); + using (SqlDataReader drInput = cmdInput.ExecuteReader()) + { + // Perform bulk copy to target. + using (SqlBulkCopy bulkCopy = new SqlBulkCopy(conn)) + { + bulkCopy.BulkCopyTimeout = 60; + bulkCopy.BatchSize = 1; + bulkCopy.DestinationTableName = bulkCopyTableName; + bulkCopy.WriteToServer(drInput); + } + + // Verify target. + using (SqlCommand cmd = conn.CreateCommand()) + { + cmd.CommandText = string.Format("select f1 from {0}", bulkCopyTableName); + using (SqlDataReader drVerify = cmd.ExecuteReader()) + { + drVerify.Read(); + VerifyReaderTypeAndValue("SqlBulkCopy From SqlDataReader [Data Type]", expectedBaseTypeName, expectedTypeName, drVerify[0], expectedTypeName, paramValue); + drVerify.Dispose(); + } + } + } + } + connInput.Close(); } } - connInput.Close(); } catch (Exception e) { @@ -686,10 +774,12 @@ private static void SqlBulkCopySqlDataReader_Type(object paramValue, string expe } finally { - using SqlConnection conn = new(s_connStr); - conn.Open(); - DropTable(conn, bulkCopyTableName); - DropTable(conn, bulkCopySrcTableName); + using (SqlConnection conn = new SqlConnection(s_connStr)) + { + conn.Open(); + DropTable(conn, bulkCopyTableName); + DropTable(conn, bulkCopySrcTableName); + } } } @@ -702,59 +792,67 @@ private static void SqlBulkCopySqlDataReader_Variant(object paramValue, string e string bulkCopyTableName = DataTestUtility.GetUniqueNameForSqlServer("bulkDestTable"); try { - using SqlConnection conn = new(s_connStr); - conn.Open(); - DropTable(conn, bulkCopyTableName); - xsql(conn, string.Format("create table {0} (f1 sql_variant)", bulkCopyTableName)); - - DropTable(conn, bulkCopySrcTableName); - xsql(conn, string.Format("create table {0} (f1 {1})", bulkCopySrcTableName, expectedBaseTypeName)); - string value = string.Empty; - if (paramValue.GetType() == typeof(DateTimeOffset)) - { - DateTime dt = ((DateTimeOffset)paramValue).UtcDateTime; - value = dt.ToString("M/d/yyyy") + " " + dt.TimeOfDay; - } - else if (paramValue.GetType() == typeof(TimeSpan)) + using (SqlConnection conn = new SqlConnection(s_connStr)) { - value = ((TimeSpan)paramValue).ToString(); - } - else - { - value = ((DateTime)paramValue).ToString("M/d/yyyy") + " " + ((DateTime)paramValue).TimeOfDay; - } - xsql(conn, string.Format("insert into {0}(f1) values(CAST('{1}' AS {2}));", bulkCopySrcTableName, value, expectedBaseTypeName)); + conn.Open(); + DropTable(conn, bulkCopyTableName); + xsql(conn, string.Format("create table {0} (f1 sql_variant)", bulkCopyTableName)); + + DropTable(conn, bulkCopySrcTableName); + xsql(conn, string.Format("create table {0} (f1 {1})", bulkCopySrcTableName, expectedBaseTypeName)); + string value = string.Empty; + if (paramValue.GetType() == typeof(System.DateTimeOffset)) + { + DateTime dt = ((System.DateTimeOffset)paramValue).UtcDateTime; + value = dt.ToString("M/d/yyyy") + " " + dt.TimeOfDay; + } + else if (paramValue.GetType() == typeof(System.TimeSpan)) + { + value = ((System.TimeSpan)paramValue).ToString(); + } + else + { + value = ((System.DateTime)paramValue).ToString("M/d/yyyy") + " " + ((System.DateTime)paramValue).TimeOfDay; + } + xsql(conn, string.Format("insert into {0}(f1) values(CAST('{1}' AS {2}));", bulkCopySrcTableName, value, expectedBaseTypeName)); - using (SqlConnection connInput = new(s_connStr)) - { - connInput.Open(); - using (SqlCommand cmdInput = connInput.CreateCommand()) + using (SqlConnection connInput = new SqlConnection(s_connStr)) { - cmdInput.CommandText = string.Format("select * from {0}", bulkCopySrcTableName); - using SqlDataReader drInput = cmdInput.ExecuteReader(); + connInput.Open(); + using (SqlCommand cmdInput = connInput.CreateCommand()) { - // Perform bulk copy to target. - using (SqlBulkCopy bulkCopy = new(conn)) + cmdInput.CommandText = string.Format("select * from {0}", bulkCopySrcTableName); + using (SqlDataReader drInput = cmdInput.ExecuteReader()) { - bulkCopy.BulkCopyTimeout = 60; - bulkCopy.BatchSize = 1; - bulkCopy.DestinationTableName = bulkCopyTableName; - bulkCopy.WriteToServer(drInput); - } - - // Verify target. - using SqlCommand cmd = conn.CreateCommand(); - cmd.CommandText = string.Format("select f1, sql_variant_property(f1,'BaseType') as BaseType from {0}", bulkCopyTableName); - using (SqlDataReader drVerify = cmd.ExecuteReader()) - { - drVerify.Read(); - VerifyReaderTypeAndValue("SqlBulkCopy From SqlDataReader [Variant Type]", "SqlDbType.Variant", drVerify, expectedTypeName, expectedBaseTypeName, paramValue); + { + // Perform bulk copy to target. + using (SqlBulkCopy bulkCopy = new SqlBulkCopy(conn)) + { + bulkCopy.BulkCopyTimeout = 60; + bulkCopy.BatchSize = 1; + bulkCopy.DestinationTableName = bulkCopyTableName; + bulkCopy.WriteToServer(drInput); + } + + // Verify target. + using (SqlCommand cmd = conn.CreateCommand()) + { + cmd.CommandText = string.Format("select f1, sql_variant_property(f1,'BaseType') as BaseType from {0}", bulkCopyTableName); + using (SqlDataReader drVerify = cmd.ExecuteReader()) + { + drVerify.Read(); + VerifyReaderTypeAndValue("SqlBulkCopy From SqlDataReader [Variant Type]", "SqlDbType.Variant", drVerify, expectedTypeName, expectedBaseTypeName, paramValue); + drVerify.Dispose(); + } + } + } } } + connInput.Close(); } - } - conn.Close(); + conn.Close(); + } } catch (Exception e) { @@ -765,10 +863,12 @@ private static void SqlBulkCopySqlDataReader_Variant(object paramValue, string e } finally { - using SqlConnection conn = new(s_connStr); - conn.Open(); - DropTable(conn, bulkCopyTableName); - DropTable(conn, bulkCopySrcTableName); + using (SqlConnection conn = new SqlConnection(s_connStr)) + { + conn.Open(); + DropTable(conn, bulkCopyTableName); + DropTable(conn, bulkCopySrcTableName); + } } } @@ -779,32 +879,37 @@ private static void SqlBulkCopyDataTable_Type(object paramValue, string expected string bulkCopyTableName = DataTestUtility.GetUniqueNameForSqlServer("bulkDestType"); try { - using SqlConnection conn = new(s_connStr); - conn.Open(); - DropTable(conn, bulkCopyTableName); - xsql(conn, string.Format("create table {0} (f1 {1})", bulkCopyTableName, expectedBaseTypeName)); + using (SqlConnection conn = new SqlConnection(s_connStr)) + { + conn.Open(); + DropTable(conn, bulkCopyTableName); + xsql(conn, string.Format("create table {0} (f1 {1})", bulkCopyTableName, expectedBaseTypeName)); - // Send using DataTable as source. - DataTable t = new(); - t.Columns.Add("f1", paramValue.GetType()); - t.Rows.Add(new object[] { paramValue }); + // Send using DataTable as source. + DataTable t = new DataTable(); + t.Columns.Add("f1", paramValue.GetType()); + t.Rows.Add(new object[] { paramValue }); - // Perform bulk copy to target. - using (SqlBulkCopy bulkCopy = new(conn)) - { - bulkCopy.BulkCopyTimeout = 60; - bulkCopy.BatchSize = 1; - bulkCopy.DestinationTableName = bulkCopyTableName; - bulkCopy.WriteToServer(t, DataRowState.Added); - } + // Perform bulk copy to target. + using (SqlBulkCopy bulkCopy = new SqlBulkCopy(conn)) + { + bulkCopy.BulkCopyTimeout = 60; + bulkCopy.BatchSize = 1; + bulkCopy.DestinationTableName = bulkCopyTableName; + bulkCopy.WriteToServer(t, DataRowState.Added); + } - // Verify target. - using SqlCommand cmd = conn.CreateCommand(); - cmd.CommandText = string.Format("select f1 from {0}", bulkCopyTableName); - using (SqlDataReader drVerify = cmd.ExecuteReader()) - { - drVerify.Read(); - VerifyReaderTypeAndValue("SqlBulkCopy From Data Table [Data Type]", expectedBaseTypeName, expectedTypeName, drVerify[0], expectedTypeName, paramValue); + // Verify target. + using (SqlCommand cmd = conn.CreateCommand()) + { + cmd.CommandText = string.Format("select f1 from {0}", bulkCopyTableName); + using (SqlDataReader drVerify = cmd.ExecuteReader()) + { + drVerify.Read(); + VerifyReaderTypeAndValue("SqlBulkCopy From Data Table [Data Type]", expectedBaseTypeName, expectedTypeName, drVerify[0], expectedTypeName, paramValue); + drVerify.Dispose(); + } + } } } catch (Exception e) @@ -824,14 +929,16 @@ private static void SqlBulkCopyDataTable_Type(object paramValue, string expected } finally { - using SqlConnection conn = new(s_connStr); - conn.Open(); - DropTable(conn, bulkCopyTableName); + using (SqlConnection conn = new SqlConnection(s_connStr)) + { + conn.Open(); + DropTable(conn, bulkCopyTableName); + } } } // sql_variant parameters and sql_variant TVPs store all datetime values internally - // as datetime, hence breaking for 2008 types + // as datetime, hence breaking for katmai types private static void SqlBulkCopyDataTable_Variant(object paramValue, string expectedTypeName, string expectedBaseTypeName) { string tag = "SqlBulkCopyDataTable_Variant"; @@ -839,32 +946,37 @@ private static void SqlBulkCopyDataTable_Variant(object paramValue, string expec string bulkCopyTableName = DataTestUtility.GetUniqueNameForSqlServer("bulkDestVariant"); try { - using SqlConnection conn = new(s_connStr); - conn.Open(); - DropTable(conn, bulkCopyTableName); - xsql(conn, string.Format("create table {0} (f1 sql_variant)", bulkCopyTableName)); + using (SqlConnection conn = new SqlConnection(s_connStr)) + { + conn.Open(); + DropTable(conn, bulkCopyTableName); + xsql(conn, string.Format("create table {0} (f1 sql_variant)", bulkCopyTableName)); - // Send using DataTable as source. - DataTable t = new(); - t.Columns.Add("f1", typeof(object)); - t.Rows.Add(new object[] { paramValue }); + // Send using DataTable as source. + DataTable t = new DataTable(); + t.Columns.Add("f1", typeof(object)); + t.Rows.Add(new object[] { paramValue }); - // Perform bulk copy to target. - using (SqlBulkCopy bulkCopy = new(conn)) - { - bulkCopy.BulkCopyTimeout = 60; - bulkCopy.BatchSize = 1; - bulkCopy.DestinationTableName = bulkCopyTableName; - bulkCopy.WriteToServer(t, DataRowState.Added); - } + // Perform bulk copy to target. + using (SqlBulkCopy bulkCopy = new SqlBulkCopy(conn)) + { + bulkCopy.BulkCopyTimeout = 60; + bulkCopy.BatchSize = 1; + bulkCopy.DestinationTableName = bulkCopyTableName; + bulkCopy.WriteToServer(t, DataRowState.Added); + } - // Verify target. - using SqlCommand cmd = conn.CreateCommand(); - cmd.CommandText = string.Format("select f1, sql_variant_property(f1,'BaseType') as BaseType from {0}", bulkCopyTableName); - using (SqlDataReader drVerify = cmd.ExecuteReader()) - { - drVerify.Read(); - VerifyReaderTypeAndValue("SqlBulkCopy From Data Table [Variant Type]", "SqlDbType.Variant", drVerify, expectedTypeName, expectedBaseTypeName, paramValue); + // Verify target. + using (SqlCommand cmd = conn.CreateCommand()) + { + cmd.CommandText = string.Format("select f1, sql_variant_property(f1,'BaseType') as BaseType from {0}", bulkCopyTableName); + using (SqlDataReader drVerify = cmd.ExecuteReader()) + { + drVerify.Read(); + VerifyReaderTypeAndValue("SqlBulkCopy From Data Table [Variant Type]", "SqlDbType.Variant", drVerify, expectedTypeName, expectedBaseTypeName, paramValue); + drVerify.Dispose(); + } + } } } catch (Exception e) @@ -876,9 +988,11 @@ private static void SqlBulkCopyDataTable_Variant(object paramValue, string expec } finally { - using SqlConnection conn = new(s_connStr); - conn.Open(); - DropTable(conn, bulkCopyTableName); + using (SqlConnection conn = new SqlConnection(s_connStr)) + { + conn.Open(); + DropTable(conn, bulkCopyTableName); + } } } @@ -889,27 +1003,38 @@ private static void SqlBulkCopyDataRow_Type(object paramValue, string expectedTy string bulkCopyTableName = DataTestUtility.GetUniqueNameForSqlServer("bulkDestType"); try { - using SqlConnection conn = new(s_connStr); - conn.Open(); - DropTable(conn, bulkCopyTableName); - xsql(conn, string.Format("create table {0} (f1 {1})", bulkCopyTableName, expectedBaseTypeName)); - DataTable t = new(); - t.Columns.Add("f1", paramValue.GetType()); - t.Rows.Add(new object[] { paramValue }); - DataRow[] rowToSend = t.Select(); - using (SqlBulkCopy bulkCopy = new(conn)) + using (SqlConnection conn = new SqlConnection(s_connStr)) { - bulkCopy.BulkCopyTimeout = 60; - bulkCopy.BatchSize = 1; - bulkCopy.DestinationTableName = bulkCopyTableName; - bulkCopy.WriteToServer(rowToSend); - } - using SqlCommand cmd = conn.CreateCommand(); - cmd.CommandText = string.Format("select f1 from {0}", bulkCopyTableName); - using (SqlDataReader drVerify = cmd.ExecuteReader()) - { - drVerify.Read(); - VerifyReaderTypeAndValue("SqlBulkCopy From Data Row [Data Type]", expectedBaseTypeName, expectedTypeName, drVerify[0], expectedTypeName, paramValue); + conn.Open(); + DropTable(conn, bulkCopyTableName); + xsql(conn, string.Format("create table {0} (f1 {1})", bulkCopyTableName, expectedBaseTypeName)); + + DataTable t = new DataTable(); + t.Columns.Add("f1", paramValue.GetType()); + t.Rows.Add(new object[] { paramValue }); + // Send using DataRow as source. + DataRow[] rowToSend = t.Select(); + + // Perform bulk copy to target. + using (SqlBulkCopy bulkCopy = new SqlBulkCopy(conn)) + { + bulkCopy.BulkCopyTimeout = 60; + bulkCopy.BatchSize = 1; + bulkCopy.DestinationTableName = bulkCopyTableName; + bulkCopy.WriteToServer(rowToSend); + } + + // Verify target. + using (SqlCommand cmd = conn.CreateCommand()) + { + cmd.CommandText = string.Format("select f1 from {0}", bulkCopyTableName); + using (SqlDataReader drVerify = cmd.ExecuteReader()) + { + drVerify.Read(); + VerifyReaderTypeAndValue("SqlBulkCopy From Data Row [Data Type]", expectedBaseTypeName, expectedTypeName, drVerify[0], expectedTypeName, paramValue); + drVerify.Dispose(); + } + } } } catch (Exception e) @@ -929,14 +1054,16 @@ private static void SqlBulkCopyDataRow_Type(object paramValue, string expectedTy } finally { - using SqlConnection conn = new(s_connStr); - conn.Open(); - DropTable(conn, bulkCopyTableName); + using (SqlConnection conn = new SqlConnection(s_connStr)) + { + conn.Open(); + DropTable(conn, bulkCopyTableName); + } } } // sql_variant parameters and sql_variant TVPs store all datetime values internally - // as datetime, hence breaking for 2008 types + // as datetime, hence breaking for katmai types private static void SqlBulkCopyDataRow_Variant(object paramValue, string expectedTypeName, string expectedBaseTypeName) { string tag = "SqlBulkCopyDataRow_Variant"; @@ -944,27 +1071,38 @@ private static void SqlBulkCopyDataRow_Variant(object paramValue, string expecte string bulkCopyTableName = DataTestUtility.GetUniqueNameForSqlServer("bulkDestVariant"); try { - using SqlConnection conn = new(s_connStr); - conn.Open(); - DropTable(conn, bulkCopyTableName); - xsql(conn, string.Format("create table {0} (f1 sql_variant)", bulkCopyTableName)); - DataTable t = new(); - t.Columns.Add("f1", typeof(object)); - t.Rows.Add(new object[] { paramValue }); - DataRow[] rowToSend = t.Select(); - using (SqlBulkCopy bulkCopy = new(conn)) - { - bulkCopy.BulkCopyTimeout = 60; - bulkCopy.BatchSize = 1; - bulkCopy.DestinationTableName = bulkCopyTableName; - bulkCopy.WriteToServer(rowToSend); - } - using SqlCommand cmd = conn.CreateCommand(); - cmd.CommandText = string.Format("select f1, sql_variant_property(f1,'BaseType') as BaseType from {0}", bulkCopyTableName); - using (SqlDataReader drVerify = cmd.ExecuteReader()) + using (SqlConnection conn = new SqlConnection(s_connStr)) { - drVerify.Read(); - VerifyReaderTypeAndValue("SqlBulkCopy From Data Row [Variant Type]", "SqlDbType.Variant", drVerify, expectedTypeName, expectedBaseTypeName, paramValue); + conn.Open(); + DropTable(conn, bulkCopyTableName); + xsql(conn, string.Format("create table {0} (f1 sql_variant)", bulkCopyTableName)); + + DataTable t = new DataTable(); + t.Columns.Add("f1", typeof(object)); + t.Rows.Add(new object[] { paramValue }); + // Send using DataRow as source. + DataRow[] rowToSend = t.Select(); + + // Perform bulk copy to target. + using (SqlBulkCopy bulkCopy = new SqlBulkCopy(conn)) + { + bulkCopy.BulkCopyTimeout = 60; + bulkCopy.BatchSize = 1; + bulkCopy.DestinationTableName = bulkCopyTableName; + bulkCopy.WriteToServer(rowToSend); + } + + // Verify target. + using (SqlCommand cmd = conn.CreateCommand()) + { + cmd.CommandText = string.Format("select f1, sql_variant_property(f1,'BaseType') as BaseType from {0}", bulkCopyTableName); + using (SqlDataReader drVerify = cmd.ExecuteReader()) + { + drVerify.Read(); + VerifyReaderTypeAndValue("SqlBulkCopy From Data Row [Variant Type]", "SqlDbType.Variant", drVerify, expectedTypeName, expectedBaseTypeName, paramValue); + drVerify.Dispose(); + } + } } } catch (Exception e) @@ -976,9 +1114,11 @@ private static void SqlBulkCopyDataRow_Variant(object paramValue, string expecte } finally { - using SqlConnection conn = new(s_connStr); - conn.Open(); - DropTable(conn, bulkCopyTableName); + using (SqlConnection conn = new SqlConnection(s_connStr)) + { + conn.Open(); + DropTable(conn, bulkCopyTableName); + } } } @@ -986,23 +1126,32 @@ private static void SqlBulkCopyDataRow_Variant(object paramValue, string expecte private static SqlDbType GetSqlDbType(string expectedBaseTypeName) { - return expectedBaseTypeName.ToLowerInvariant() switch - { - "time" => SqlDbType.Time, - "date" => SqlDbType.Date, - "smalldatetime" => SqlDbType.SmallDateTime, - "datetime" => SqlDbType.DateTime, - "datetime2" => SqlDbType.DateTime2, - "datetimeoffset" => SqlDbType.DateTimeOffset, - _ => SqlDbType.Variant, - }; + switch (expectedBaseTypeName.ToLowerInvariant()) + { + case "time": + return SqlDbType.Time; + case "date": + return SqlDbType.Date; + case "smalldatetime": + return SqlDbType.SmallDateTime; + case "datetime": + return SqlDbType.DateTime; + case "datetime2": + return SqlDbType.DateTime2; + case "datetimeoffset": + return SqlDbType.DateTimeOffset; + default: + return SqlDbType.Variant; + } } private static void xsql(SqlConnection conn, string sql) { - using SqlCommand cmd = conn.CreateCommand(); - cmd.CommandText = sql; - cmd.ExecuteNonQuery(); + using (SqlCommand cmd = conn.CreateCommand()) + { + cmd.CommandText = sql; + cmd.ExecuteNonQuery(); + } } private static void DropStoredProcedure(SqlConnection conn, string procName) @@ -1037,7 +1186,7 @@ private static void VerifyReaderTypeAndValue(string tag, string expectedBaseType } if (!actualValue.Equals(expectedValue)) { - string ErrorMessage; + string ErrorMessage = string.Empty; if (IsValueCorrectForType(expectedBaseTypeName, expectedValue, actualValue)) { ErrorMessage = string.Format("[EXPECTED ERROR]: VALUE MISMATCH - [Actual = {0}] [Expected = {1}]", @@ -1082,7 +1231,7 @@ private static void VerifyReaderTypeAndValue(string tag, string type, SqlDataRea } if (!actualValue.Equals(expectedValue)) { - string ErrorMessage; + string ErrorMessage = string.Empty; if (IsValueCorrectForType(expectedBaseTypeName, expectedValue, actualValue)) { ErrorMessage = string.Format("[EXPECTED ERROR]: VALUE MISMATCH - [Actual = {0}] [Expected = {1}]", @@ -1104,13 +1253,13 @@ private static bool IsValueCorrectForType(string expectedBaseTypeName, object ex switch (expectedBaseTypeName) { case "date": - if (((DateTime)expectedValue).ToString("M/d/yyyy").Equals(((DateTime)actualValue).ToString("M/d/yyyy"))) + if (((System.DateTime)expectedValue).ToString("M/d/yyyy").Equals(((System.DateTime)actualValue).ToString("M/d/yyyy"))) return true; else return false; case "datetime": - if ((((DateTime)expectedValue).Ticks == 3155378975999999999) && - (((DateTime)actualValue).Ticks == 3155378975999970000)) + if ((((System.DateTime)expectedValue).Ticks == 3155378975999999999) && + (((System.DateTime)actualValue).Ticks == 3155378975999970000)) return true; else return false; @@ -1157,19 +1306,19 @@ private static bool IsExpectedInvalidOperationException(Exception e, string expe private static string AmendTheGivenMessageDateValueException(string message, object paramValue) { - string value; - if (paramValue.GetType() == typeof(DateTimeOffset)) + string value = string.Empty; + if (paramValue.GetType() == typeof(System.DateTimeOffset)) { - DateTime dt = ((DateTimeOffset)paramValue).UtcDateTime; + DateTime dt = ((System.DateTimeOffset)paramValue).UtcDateTime; value = dt.ToString("M/d/yyyy") + " " + dt.TimeOfDay; } - else if (paramValue.GetType() == typeof(TimeSpan)) + else if (paramValue.GetType() == typeof(System.TimeSpan)) { - value = ((TimeSpan)paramValue).ToString(); + value = ((System.TimeSpan)paramValue).ToString(); } else { - value = ((DateTime)paramValue).ToString("M/d/yyyy") + " " + ((DateTime)paramValue).TimeOfDay; + value = ((System.DateTime)paramValue).ToString("M/d/yyyy") + " " + ((System.DateTime)paramValue).TimeOfDay; } return message.Replace(paramValue.ToString(), value); @@ -1179,19 +1328,19 @@ private static string AmendTheGivenMessageDateValueException(string message, obj private static void DisplayHeader(string tag, object paramValue, string expectedBaseTypeName) { Console.WriteLine(""); - string value; - if (paramValue.GetType() == typeof(DateTimeOffset)) + string value = string.Empty; + if (paramValue.GetType() == typeof(System.DateTimeOffset)) { - DateTimeOffset dt = (DateTimeOffset)paramValue; + System.DateTimeOffset dt = (System.DateTimeOffset)paramValue; value = dt.DateTime.ToString("M/d/yyyy") + " " + dt.DateTime.TimeOfDay + " " + dt.Offset; } - else if (paramValue.GetType() == typeof(TimeSpan)) + else if (paramValue.GetType() == typeof(System.TimeSpan)) { - value = ((TimeSpan)paramValue).ToString(); + value = ((System.TimeSpan)paramValue).ToString(); } else { - value = ((DateTime)paramValue).ToString("M/d/yyyy") + " " + ((DateTime)paramValue).TimeOfDay; + value = ((System.DateTime)paramValue).ToString("M/d/yyyy") + " " + ((System.DateTime)paramValue).TimeOfDay; } Console.WriteLine(string.Format("------------------------------ {0} [type: {1} value:{2}] ------------------------------", tag, expectedBaseTypeName, value)); diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ParameterTest/OutputParameter.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ParameterTest/OutputParameter.cs index 6af1a39e1d..8d81e13ec9 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ParameterTest/OutputParameter.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ParameterTest/OutputParameter.cs @@ -26,20 +26,22 @@ private static void InvalidValueInOutParam(string connectionString) connection.Open(); // Command simply set the outparam - using var command = new SqlCommand("SET @decimal = 1.23", connection); - - // Create valid param - var decimalParam = new SqlParameter("decimal", new decimal(2.34)) { SqlDbType = SqlDbType.Decimal, Direction = ParameterDirection.Output, Scale = 2, Precision = 5 }; - command.Parameters.Add(decimalParam); - // Set value of param to invalid value - decimalParam.Value = "Not a decimal"; - - // Execute - command.ExecuteNonQuery(); - // Validate - if (((decimal)decimalParam.Value) != new decimal(1.23)) + using (var command = new SqlCommand("SET @decimal = 1.23", connection)) { - Console.WriteLine("FAIL: Value is incorrect: {0}", decimalParam.Value); + + // Create valid param + var decimalParam = new SqlParameter("decimal", new decimal(2.34)) { SqlDbType = SqlDbType.Decimal, Direction = ParameterDirection.Output, Scale = 2, Precision = 5 }; + command.Parameters.Add(decimalParam); + // Set value of param to invalid value + decimalParam.Value = "Not a decimal"; + + // Execute + command.ExecuteNonQuery(); + // Validate + if (((decimal)decimalParam.Value) != new decimal(1.23)) + { + Console.WriteLine("FAIL: Value is incorrect: {0}", decimalParam.Value); + } } } diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ParameterTest/ParametersTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ParameterTest/ParametersTest.cs index fe0f1eb4a9..af54b4a4cc 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ParameterTest/ParametersTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ParameterTest/ParametersTest.cs @@ -14,7 +14,7 @@ namespace Microsoft.Data.SqlClient.ManualTesting.Tests { public static class ParametersTest { - private static readonly string s_connString = DataTestUtility.TCPConnectionString; + private static string s_connString = DataTestUtility.TCPConnectionString; [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup))] public static void CodeCoverageSqlClient() @@ -108,49 +108,50 @@ public static void CodeCoverageSqlClient() [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup), nameof(DataTestUtility.IsNotAzureSynapse))] public static void Test_Copy_SqlParameter() { - using var conn = new SqlConnection(s_connString); - string cTableName = DataTestUtility.GetUniqueNameForSqlServer("#tmp"); - try + using (var conn = new SqlConnection(s_connString)) { - // Create tmp table - var sCreateTable = "IF NOT EXISTS("; - sCreateTable += $"SELECT * FROM sysobjects WHERE name= '{ cTableName }' and xtype = 'U')"; - sCreateTable += $"CREATE TABLE { cTableName }( BinValue binary(16) null)"; + string cTableName = DataTestUtility.GetUniqueNameForSqlServer("#tmp"); + try + { + // Create tmp table + var sCreateTable = "IF NOT EXISTS("; + sCreateTable += $"SELECT * FROM sysobjects WHERE name= '{ cTableName }' and xtype = 'U')"; + sCreateTable += $"CREATE TABLE { cTableName }( BinValue binary(16) null)"; - conn.Open(); - var cmd = new SqlCommand(sCreateTable, conn); - cmd.ExecuteNonQuery(); + conn.Open(); + var cmd = new SqlCommand(sCreateTable, conn); + cmd.ExecuteNonQuery(); - var dt = new DataTable("SourceDataTable"); - dt.Columns.Add("SourceBinValue", typeof(byte[])); + var dt = new DataTable("SourceDataTable"); + dt.Columns.Add("SourceBinValue", typeof(byte[])); - dt.Rows.Add(Guid.NewGuid().ToByteArray()); - dt.Rows.Add(DBNull.Value); + dt.Rows.Add(Guid.NewGuid().ToByteArray()); + dt.Rows.Add(DBNull.Value); - var cmdInsert = new SqlCommand - { - UpdatedRowSource = UpdateRowSource.None, - Connection = conn, + var cmdInsert = new SqlCommand(); + cmdInsert.UpdatedRowSource = UpdateRowSource.None; + cmdInsert.Connection = conn; - CommandText = $"INSERT { cTableName } (BinValue) " - }; - cmdInsert.CommandText += "Values(@BinValue)"; - cmdInsert.Parameters.Add("@BinValue", SqlDbType.Binary, 16, "SourceBinValue"); + cmdInsert.CommandText = $"INSERT { cTableName } (BinValue) "; + cmdInsert.CommandText += "Values(@BinValue)"; + cmdInsert.Parameters.Add("@BinValue", SqlDbType.Binary, 16, "SourceBinValue"); - var da = new SqlDataAdapter + var da = new SqlDataAdapter(); + + da.InsertCommand = cmdInsert; + da.UpdateBatchSize = 2; + da.AcceptChangesDuringUpdate = false; + da.Update(dt); + } + finally { - InsertCommand = cmdInsert, - UpdateBatchSize = 2, - AcceptChangesDuringUpdate = false - }; - da.Update(dt); - } - finally - { - // End of test, cleanup tmp table; - var sDropTable = $"DROP TABLE IF EXISTS {cTableName}"; - using SqlCommand cmd = new(sDropTable, conn); - cmd.ExecuteNonQuery(); + // End of test, cleanup tmp table; + var sDropTable = $"DROP TABLE IF EXISTS {cTableName}"; + using (SqlCommand cmd = new SqlCommand(sDropTable, conn)) + { + cmd.ExecuteNonQuery(); + } + } } } @@ -158,149 +159,163 @@ public static void Test_Copy_SqlParameter() [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup), nameof(DataTestUtility.IsNotAzureSynapse))] public static void Test_SqlParameter_Constructor() { - using var conn = new SqlConnection(s_connString); - var dataTable = new DataTable(); - var adapter = new SqlDataAdapter - { - SelectCommand = new SqlCommand("SELECT CustomerID, ContactTitle FROM dbo.Customers WHERE ContactTitle = @ContactTitle", conn) - }; - var selectParam = new SqlParameter("@ContactTitle", SqlDbType.NVarChar, 30, ParameterDirection.Input, true, 0, 0, "ContactTitle", DataRowVersion.Current, "Owner"); - adapter.SelectCommand.Parameters.Add(selectParam); - - adapter.UpdateCommand = new SqlCommand("UPDATE dbo.Customers SET ContactTitle = @ContactTitle WHERE CustomerID = @CustomerID", conn); - var titleParam = new SqlParameter("@ContactTitle", SqlDbType.NVarChar, 30, ParameterDirection.Input, true, 0, 0, "ContactTitle", DataRowVersion.Current, null); - var idParam = new SqlParameter("@CustomerID", SqlDbType.NChar, 5, ParameterDirection.Input, false, 0, 0, "CustomerID", DataRowVersion.Current, null); - adapter.UpdateCommand.Parameters.Add(titleParam); - adapter.UpdateCommand.Parameters.Add(idParam); - - adapter.Fill(dataTable); - object titleData = dataTable.Rows[0]["ContactTitle"]; - Assert.Equal("Owner", (string)titleData); - - titleData = "Test Data"; - adapter.Update(dataTable); - adapter.Fill(dataTable); - Assert.Equal("Test Data", (string)titleData); - - titleData = "Owner"; - adapter.Update(dataTable); + using (var conn = new SqlConnection(s_connString)) + { + var dataTable = new DataTable(); + var adapter = new SqlDataAdapter(); + + adapter.SelectCommand = new SqlCommand("SELECT CustomerID, ContactTitle FROM dbo.Customers WHERE ContactTitle = @ContactTitle", conn); + var selectParam = new SqlParameter("@ContactTitle", SqlDbType.NVarChar, 30, ParameterDirection.Input, true, 0, 0, "ContactTitle", DataRowVersion.Current, "Owner"); + adapter.SelectCommand.Parameters.Add(selectParam); + + adapter.UpdateCommand = new SqlCommand("UPDATE dbo.Customers SET ContactTitle = @ContactTitle WHERE CustomerID = @CustomerID", conn); + var titleParam = new SqlParameter("@ContactTitle", SqlDbType.NVarChar, 30, ParameterDirection.Input, true, 0, 0, "ContactTitle", DataRowVersion.Current, null); + var idParam = new SqlParameter("@CustomerID", SqlDbType.NChar, 5, ParameterDirection.Input, false, 0, 0, "CustomerID", DataRowVersion.Current, null); + adapter.UpdateCommand.Parameters.Add(titleParam); + adapter.UpdateCommand.Parameters.Add(idParam); + + adapter.Fill(dataTable); + object titleData = dataTable.Rows[0]["ContactTitle"]; + Assert.Equal("Owner", (string)titleData); + + titleData = "Test Data"; + adapter.Update(dataTable); + adapter.Fill(dataTable); + Assert.Equal("Test Data", (string)titleData); + + titleData = "Owner"; + adapter.Update(dataTable); + } } [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup))] public static void Test_WithEnumValue_ShouldInferToUnderlyingType() { - using var conn = new SqlConnection(s_connString); - conn.Open(); - var cmd = new SqlCommand("select @input", conn); - cmd.Parameters.AddWithValue("@input", MyEnum.B); - object value = cmd.ExecuteScalar(); - Assert.Equal(MyEnum.B, (MyEnum)value); + using (var conn = new SqlConnection(s_connString)) + { + conn.Open(); + var cmd = new SqlCommand("select @input", conn); + cmd.Parameters.AddWithValue("@input", MyEnum.B); + object value = cmd.ExecuteScalar(); + Assert.Equal(MyEnum.B, (MyEnum)value); + } } [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup))] public static void Test_WithOutputEnumParameter_ShouldReturnEnum() { - using var conn = new SqlConnection(s_connString); - conn.Open(); - var cmd = new SqlCommand("set @output = @input", conn); - cmd.Parameters.AddWithValue("@input", MyEnum.B); - SqlParameter outputParam = cmd.CreateParameter(); - outputParam.ParameterName = "@output"; - outputParam.DbType = DbType.Int32; - outputParam.Direction = ParameterDirection.Output; - cmd.Parameters.Add(outputParam); - cmd.ExecuteNonQuery(); - Assert.Equal(MyEnum.B, (MyEnum)outputParam.Value); + using (var conn = new SqlConnection(s_connString)) + { + conn.Open(); + var cmd = new SqlCommand("set @output = @input", conn); + cmd.Parameters.AddWithValue("@input", MyEnum.B); + + var outputParam = cmd.CreateParameter(); + outputParam.ParameterName = "@output"; + outputParam.DbType = DbType.Int32; + outputParam.Direction = ParameterDirection.Output; + cmd.Parameters.Add(outputParam); + + cmd.ExecuteNonQuery(); + + Assert.Equal(MyEnum.B, (MyEnum)outputParam.Value); + } } [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup))] public static void Test_WithDecimalValue_ShouldReturnDecimal() { - using var conn = new SqlConnection(s_connString); - conn.Open(); - var cmd = new SqlCommand("select @foo", conn); - cmd.Parameters.AddWithValue("@foo", new SqlDecimal(0.5)); - var result = (decimal)cmd.ExecuteScalar(); - Assert.Equal(result, (decimal)0.5); + using (var conn = new SqlConnection(s_connString)) + { + conn.Open(); + var cmd = new SqlCommand("select @foo", conn); + cmd.Parameters.AddWithValue("@foo", new SqlDecimal(0.5)); + var result = (decimal)cmd.ExecuteScalar(); + Assert.Equal(result, (decimal)0.5); + } } // Synapse: Unsupported parameter type found while parsing RPC request. The request has been terminated. [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup), nameof(DataTestUtility.IsNotAzureSynapse))] public static void Test_WithGuidValue_ShouldReturnGuid() { - using var conn = new SqlConnection(s_connString); - conn.Open(); - var expectedGuid = Guid.NewGuid(); - var cmd = new SqlCommand("select @input", conn); - cmd.Parameters.AddWithValue("@input", expectedGuid); - var result = cmd.ExecuteScalar(); - Assert.Equal(expectedGuid, (Guid)result); + using (var conn = new SqlConnection(s_connString)) + { + conn.Open(); + var expectedGuid = Guid.NewGuid(); + var cmd = new SqlCommand("select @input", conn); + cmd.Parameters.AddWithValue("@input", expectedGuid); + var result = cmd.ExecuteScalar(); + Assert.Equal(expectedGuid, (Guid)result); + } } // Synapse: Parse error at line: 1, column: 8: Incorrect syntax near 'TYPE'. [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup), nameof(DataTestUtility.IsNotAzureServer))] public static void TestParametersWithDatatablesTVPInsert() { - SqlConnectionStringBuilder builder = new(DataTestUtility.TCPConnectionString); + SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(DataTestUtility.TCPConnectionString); int x = 4, y = 5; - DataTable table = new() - { - Columns = { { "x", typeof(int) }, { "y", typeof(int) } }, - Rows = { { x, y } } - }; + DataTable table = new DataTable { Columns = { { "x", typeof(int) }, { "y", typeof(int) } }, Rows = { { x, y } } }; - using SqlConnection connection = new(builder.ConnectionString); - string tableName = DataTestUtility.GetUniqueNameForSqlServer("Table"); - string procName = DataTestUtility.GetUniqueNameForSqlServer("Proc"); - string typeName = DataTestUtility.GetUniqueName("Type"); - try + using (SqlConnection connection = new SqlConnection(builder.ConnectionString)) { - connection.Open(); - using (SqlCommand cmd = connection.CreateCommand()) + string tableName = DataTestUtility.GetUniqueNameForSqlServer("Table"); + string procName = DataTestUtility.GetUniqueNameForSqlServer("Proc"); + string typeName = DataTestUtility.GetUniqueName("Type"); + try { - cmd.CommandText = $"CREATE TYPE {typeName} AS TABLE (x INT, y INT)"; - cmd.ExecuteNonQuery(); + connection.Open(); + using (SqlCommand cmd = connection.CreateCommand()) + { + cmd.CommandText = $"CREATE TYPE {typeName} AS TABLE (x INT, y INT)"; + cmd.ExecuteNonQuery(); - cmd.CommandText = $"CREATE TABLE {tableName} (x INT, y INT)"; - cmd.ExecuteNonQuery(); + cmd.CommandText = $"CREATE TABLE {tableName} (x INT, y INT)"; + cmd.ExecuteNonQuery(); - cmd.CommandText = $"CREATE PROCEDURE {procName} @TVP {typeName} READONLY AS " + - $"SET NOCOUNT ON INSERT INTO {tableName}(x, y) SELECT * FROM @TVP"; - cmd.ExecuteNonQuery(); + cmd.CommandText = $"CREATE PROCEDURE {procName} @TVP {typeName} READONLY AS " + + $"SET NOCOUNT ON INSERT INTO {tableName}(x, y) SELECT * FROM @TVP"; + cmd.ExecuteNonQuery(); - } - using (SqlCommand cmd = connection.CreateCommand()) - { - // Update Data Using TVPs - cmd.CommandText = procName; - cmd.CommandType = CommandType.StoredProcedure; + } + using (SqlCommand cmd = connection.CreateCommand()) + { + // Update Data Using TVPs + cmd.CommandText = procName; + cmd.CommandType = CommandType.StoredProcedure; - SqlParameter parameter = cmd.Parameters.AddWithValue("@TVP", table); - parameter.TypeName = typeName; + SqlParameter parameter = cmd.Parameters.AddWithValue("@TVP", table); + parameter.TypeName = typeName; - cmd.ExecuteNonQuery(); + cmd.ExecuteNonQuery(); - // Verify if the data was updated - cmd.CommandText = "select * from " + tableName; - cmd.CommandType = CommandType.Text; - using SqlDataReader reader = cmd.ExecuteReader(); - DataTable dbData = new(); - dbData.Load(reader); - Assert.Equal(1, dbData.Rows.Count); - Assert.Equal(x, dbData.Rows[0][0]); - Assert.Equal(y, dbData.Rows[0][1]); + // Verify if the data was updated + cmd.CommandText = "select * from " + tableName; + cmd.CommandType = CommandType.Text; + using (SqlDataReader reader = cmd.ExecuteReader()) + { + DataTable dbData = new DataTable(); + dbData.Load(reader); + Assert.Equal(1, dbData.Rows.Count); + Assert.Equal(x, dbData.Rows[0][0]); + Assert.Equal(y, dbData.Rows[0][1]); + } + } + } + finally + { + using (SqlCommand cmd = connection.CreateCommand()) + { + cmd.CommandText = "DROP PROCEDURE " + procName; + cmd.ExecuteNonQuery(); + cmd.CommandText = "DROP TABLE " + tableName; + cmd.ExecuteNonQuery(); + cmd.CommandText = "DROP TYPE " + typeName; + cmd.ExecuteNonQuery(); + } } - } - finally - { - using SqlCommand cmd = connection.CreateCommand(); - cmd.CommandText = "DROP PROCEDURE " + procName; - cmd.ExecuteNonQuery(); - cmd.CommandText = "DROP TABLE " + tableName; - cmd.ExecuteNonQuery(); - cmd.CommandText = "DROP TYPE " + typeName; - cmd.ExecuteNonQuery(); } } @@ -325,14 +340,20 @@ public static void TestParametersWithDatatablesTVPInsert() [InlineData("CAST(-0.0000000000000000000000000001 as decimal(38, 38))", "-0.0000000000000000000000000001")] public static void SqlDecimalConvertToDecimal_TestInRange(string sqlDecimalValue, string expectedDecimalValue) { - using SqlConnection cnn = new(s_connString); - cnn.Open(); - using SqlCommand cmd = new($"SELECT {sqlDecimalValue} val"); - cmd.Connection = cnn; - using SqlDataReader rdr = cmd.ExecuteReader(); - Assert.True(rdr.Read(), "SqlDataReader must have a value"); - decimal retrunValue = rdr.GetDecimal(0); - Assert.Equal(expectedDecimalValue, retrunValue.ToString()); + using (SqlConnection cnn = new(s_connString)) + { + cnn.Open(); + using (SqlCommand cmd = new($"SELECT {sqlDecimalValue} val")) + { + cmd.Connection = cnn; + using (SqlDataReader rdr = cmd.ExecuteReader()) + { + Assert.True(rdr.Read(), "SqlDataReader must have a value"); + decimal retrunValue = rdr.GetDecimal(0); + Assert.Equal(expectedDecimalValue, retrunValue.ToString()); + } + } + } } [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup))] @@ -345,13 +366,19 @@ public static void SqlDecimalConvertToDecimal_TestInRange(string sqlDecimalValue [InlineData("CAST(0.123456789012345678901234567890 as decimal(38, 36))")] public static void SqlDecimalConvertToDecimal_TestOutOfRange(string sqlDecimalValue) { - using SqlConnection cnn = new(s_connString); - cnn.Open(); - using SqlCommand cmd = new($"SELECT {sqlDecimalValue} val"); - cmd.Connection = cnn; - using SqlDataReader rdr = cmd.ExecuteReader(); - Assert.True(rdr.Read(), "SqlDataReader must have a value"); - Assert.Throws(() => rdr.GetDecimal(0)); + using (SqlConnection cnn = new(s_connString)) + { + cnn.Open(); + using (SqlCommand cmd = new($"SELECT {sqlDecimalValue} val")) + { + cmd.Connection = cnn; + using (SqlDataReader rdr = cmd.ExecuteReader()) + { + Assert.True(rdr.Read(), "SqlDataReader must have a value"); + Assert.Throws(() => rdr.GetDecimal(0)); + } + } + } } [Theory] @@ -359,30 +386,30 @@ public static void SqlDecimalConvertToDecimal_TestOutOfRange(string sqlDecimalVa public static void TestScaledDecimalParameter_CommandInsert(string connectionString, bool truncateScaledDecimal) { string tableName = DataTestUtility.GetUniqueNameForSqlServer("TestDecimalParameterCMD"); - using SqlConnection connection = InitialDatabaseTable(connectionString, tableName); - try + using (SqlConnection connection = InitialDatabaseTable(connectionString, tableName)) { - using (SqlCommand cmd = connection.CreateCommand()) + try { - AppContext.SetSwitch(TruncateDecimalSwitch, truncateScaledDecimal); - var p = new SqlParameter("@Value", null) + using (SqlCommand cmd = connection.CreateCommand()) { - Precision = 18, - Scale = 2 - }; - cmd.Parameters.Add(p); - for (int i = 0; i < s_testValues.Length; i++) - { - p.Value = s_testValues[i]; - cmd.CommandText = $"INSERT INTO {tableName} (Id, [Value]) VALUES({i}, @Value)"; - cmd.ExecuteNonQuery(); + AppContext.SetSwitch(truncateDecimalSwitch, truncateScaledDecimal); + var p = new SqlParameter("@Value", null); + p.Precision = 18; + p.Scale = 2; + cmd.Parameters.Add(p); + for (int i = 0; i < _testValues.Length; i++) + { + p.Value = _testValues[i]; + cmd.CommandText = $"INSERT INTO {tableName} (Id, [Value]) VALUES({i}, @Value)"; + cmd.ExecuteNonQuery(); + } } + Assert.True(ValidateInsertedValues(connection, tableName, truncateScaledDecimal), $"Invalid test happened with connection string [{connection.ConnectionString}]"); + } + finally + { + DataTestUtility.DropTable(connection, tableName); } - Assert.True(ValidateInsertedValues(connection, tableName, truncateScaledDecimal), $"Invalid test happened with connection string [{connection.ConnectionString}]"); - } - finally - { - DataTestUtility.DropTable(connection, tableName); } } @@ -391,31 +418,33 @@ public static void TestScaledDecimalParameter_CommandInsert(string connectionStr public static void TestScaledDecimalParameter_BulkCopy(string connectionString, bool truncateScaledDecimal) { string tableName = DataTestUtility.GetUniqueNameForSqlServer("TestDecimalParameterBC"); - using SqlConnection connection = InitialDatabaseTable(connectionString, tableName); - try + using (SqlConnection connection = InitialDatabaseTable(connectionString, tableName)) { - using (SqlBulkCopy bulkCopy = new(connection)) + try { - DataTable table = new(tableName); - table.Columns.Add("Id", typeof(int)); - table.Columns.Add("Value", typeof(decimal)); - for (int i = 0; i < s_testValues.Length; i++) + using (SqlBulkCopy bulkCopy = new SqlBulkCopy(connection)) { - DataRow newRow = table.NewRow(); - newRow["Id"] = i; - newRow["Value"] = s_testValues[i]; - table.Rows.Add(newRow); - } + DataTable table = new DataTable(tableName); + table.Columns.Add("Id", typeof(int)); + table.Columns.Add("Value", typeof(decimal)); + for (int i = 0; i < _testValues.Length; i++) + { + var newRow = table.NewRow(); + newRow["Id"] = i; + newRow["Value"] = _testValues[i]; + table.Rows.Add(newRow); + } - bulkCopy.DestinationTableName = tableName; - AppContext.SetSwitch(TruncateDecimalSwitch, truncateScaledDecimal); - bulkCopy.WriteToServer(table); + bulkCopy.DestinationTableName = tableName; + AppContext.SetSwitch(truncateDecimalSwitch, truncateScaledDecimal); + bulkCopy.WriteToServer(table); + } + Assert.True(ValidateInsertedValues(connection, tableName, truncateScaledDecimal), $"Invalid test happened with connection string [{connection.ConnectionString}]"); + } + finally + { + DataTestUtility.DropTable(connection, tableName); } - Assert.True(ValidateInsertedValues(connection, tableName, truncateScaledDecimal), $"Invalid test happened with connection string [{connection.ConnectionString}]"); - } - finally - { - DataTestUtility.DropTable(connection, tableName); } } @@ -427,53 +456,53 @@ public static void TestScaledDecimalTVP_CommandSP(string connectionString, bool string tableName = DataTestUtility.GetUniqueNameForSqlServer("TestDecimalParameterBC"); string tableTypeName = DataTestUtility.GetUniqueNameForSqlServer("UDTTTestDecimalParameterBC"); string spName = DataTestUtility.GetUniqueNameForSqlServer("spTestDecimalParameterBC"); - using SqlConnection connection = InitialDatabaseUDTT(connectionString, tableName, tableTypeName, spName); - try + using (SqlConnection connection = InitialDatabaseUDTT(connectionString, tableName, tableTypeName, spName)) { - using (SqlCommand cmd = connection.CreateCommand()) + try { - var p = new SqlParameter("@tvp", SqlDbType.Structured) - { - TypeName = $"dbo.{tableTypeName}" - }; - cmd.CommandText = spName; - cmd.CommandType = CommandType.StoredProcedure; - cmd.Parameters.Add(p); - - DataTable table = new(tableName); - table.Columns.Add("Id", typeof(int)); - table.Columns.Add("Value", typeof(decimal)); - for (int i = 0; i < s_testValues.Length; i++) + using (SqlCommand cmd = connection.CreateCommand()) { - DataRow newRow = table.NewRow(); - newRow["Id"] = i; - newRow["Value"] = s_testValues[i]; - table.Rows.Add(newRow); + var p = new SqlParameter("@tvp", SqlDbType.Structured); + p.TypeName = $"dbo.{tableTypeName}"; + cmd.CommandText = spName; + cmd.CommandType = CommandType.StoredProcedure; + cmd.Parameters.Add(p); + + DataTable table = new DataTable(tableName); + table.Columns.Add("Id", typeof(int)); + table.Columns.Add("Value", typeof(decimal)); + for (int i = 0; i < _testValues.Length; i++) + { + var newRow = table.NewRow(); + newRow["Id"] = i; + newRow["Value"] = _testValues[i]; + table.Rows.Add(newRow); + } + p.Value = table; + AppContext.SetSwitch(truncateDecimalSwitch, truncateScaledDecimal); + cmd.ExecuteNonQuery(); } - p.Value = table; - AppContext.SetSwitch(TruncateDecimalSwitch, truncateScaledDecimal); - cmd.ExecuteNonQuery(); + // TVP always rounds data without attention to the configuration. + Assert.True(ValidateInsertedValues(connection, tableName, false && truncateScaledDecimal), $"Invalid test happened with connection string [{connection.ConnectionString}]"); + } + finally + { + DataTestUtility.DropTable(connection, tableName); + DataTestUtility.DropStoredProcedure(connection, spName); + DataTestUtility.DropUserDefinedType(connection, tableTypeName); } - // TVP always rounds data without attention to the configuration. - Assert.True(ValidateInsertedValues(connection, tableName, false && truncateScaledDecimal), $"Invalid test happened with connection string [{connection.ConnectionString}]"); - } - finally - { - DataTestUtility.DropTable(connection, tableName); - DataTestUtility.DropStoredProcedure(connection, spName); - DataTestUtility.DropUserDefinedType(connection, tableTypeName); } } #region Decimal parameter test setup - private static readonly decimal[] s_testValues = new[] { 4210862852.8600000000_0000000000m, 19.1560m, 19.1550m, 19.1549m }; - private static readonly decimal[] s_expectedRoundedValues = new[] { 4210862852.86m, 19.16m, 19.16m, 19.15m }; - private static readonly decimal[] s_expectedTruncatedValues = new[] { 4210862852.86m, 19.15m, 19.15m, 19.15m }; - private const string TruncateDecimalSwitch = "Switch.Microsoft.Data.SqlClient.TruncateScaledDecimal"; + private static readonly decimal[] _testValues = new[] { 4210862852.8600000000_0000000000m, 19.1560m, 19.1550m, 19.1549m }; + private static readonly decimal[] _expectedRoundedValues = new[] { 4210862852.86m, 19.16m, 19.16m, 19.15m }; + private static readonly decimal[] _expectedTruncatedValues = new[] { 4210862852.86m, 19.15m, 19.15m, 19.15m }; + private const string truncateDecimalSwitch = "Switch.Microsoft.Data.SqlClient.TruncateScaledDecimal"; private static SqlConnection InitialDatabaseUDTT(string cnnString, string tableName, string tableTypeName, string spName) { - SqlConnection connection = new(cnnString); + SqlConnection connection = new SqlConnection(cnnString); connection.Open(); using (SqlCommand cmd = connection.CreateCommand()) { @@ -489,7 +518,7 @@ private static SqlConnection InitialDatabaseUDTT(string cnnString, string tableN private static SqlConnection InitialDatabaseTable(string cnnString, string tableName) { - SqlConnection connection = new(cnnString); + SqlConnection connection = new SqlConnection(cnnString); connection.Open(); using (SqlCommand cmd = connection.CreateCommand()) { @@ -503,7 +532,7 @@ private static SqlConnection InitialDatabaseTable(string cnnString, string table private static bool ValidateInsertedValues(SqlConnection connection, string tableName, bool truncateScaledDecimal) { bool exceptionHit; - decimal[] expectedValues = truncateScaledDecimal ? s_expectedTruncatedValues : s_expectedRoundedValues; + decimal[] expectedValues = truncateScaledDecimal ? _expectedTruncatedValues : _expectedRoundedValues; try { @@ -512,13 +541,15 @@ private static bool ValidateInsertedValues(SqlConnection connection, string tabl // Verify if the data was as same as our expectation. cmd.CommandText = $"SELECT [Value] FROM {tableName} ORDER BY Id ASC"; cmd.CommandType = CommandType.Text; - using SqlDataReader reader = cmd.ExecuteReader(); - DataTable dbData = new(); - dbData.Load(reader); - Assert.Equal(expectedValues.Length, dbData.Rows.Count); - for (int i = 0; i < expectedValues.Length; i++) + using (SqlDataReader reader = cmd.ExecuteReader()) { - Assert.Equal(expectedValues[i], dbData.Rows[i][0]); + DataTable dbData = new DataTable(); + dbData.Load(reader); + Assert.Equal(expectedValues.Length, dbData.Rows.Count); + for (int i = 0; i < expectedValues.Length; i++) + { + Assert.Equal(expectedValues[i], dbData.Rows[i][0]); + } } } exceptionHit = false; @@ -554,11 +585,13 @@ private enum MyEnum private static void ExecuteNonQueryCommand(string connectionString, string cmdText) { - using SqlConnection conn = new(connectionString); - using SqlCommand cmd = conn.CreateCommand(); - conn.Open(); - cmd.CommandText = cmdText; - cmd.ExecuteNonQuery(); + using (SqlConnection conn = new SqlConnection(connectionString)) + using (SqlCommand cmd = conn.CreateCommand()) + { + conn.Open(); + cmd.CommandText = cmdText; + cmd.ExecuteNonQuery(); + } } [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup))] @@ -566,72 +599,86 @@ private static void EnableOptimizedParameterBinding_ParametersAreUsedByName() { int firstInput = 1; int secondInput = 2; - using var connection = new SqlConnection(DataTestUtility.TCPConnectionString); - connection.Open(); + using (var connection = new SqlConnection(DataTestUtility.TCPConnectionString)) + { + connection.Open(); - using var command = new SqlCommand("SELECT @Second, @First", connection); - command.EnableOptimizedParameterBinding = true; - command.Parameters.AddWithValue("@First", firstInput); - command.Parameters.AddWithValue("@Second", secondInput); + using (var command = new SqlCommand("SELECT @Second, @First", connection)) + { + command.EnableOptimizedParameterBinding = true; + command.Parameters.AddWithValue("@First", firstInput); + command.Parameters.AddWithValue("@Second", secondInput); - using SqlDataReader reader = command.ExecuteReader(); - reader.Read(); + using (SqlDataReader reader = command.ExecuteReader()) + { + reader.Read(); - int firstOutput = reader.GetInt32(0); - int secondOutput = reader.GetInt32(1); + int firstOutput = reader.GetInt32(0); + int secondOutput = reader.GetInt32(1); - Assert.Equal(firstInput, secondOutput); - Assert.Equal(secondInput, firstOutput); + Assert.Equal(firstInput, secondOutput); + Assert.Equal(secondInput, firstOutput); + } + } + } } [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup))] private static void EnableOptimizedParameterBinding_NamesMustMatch() { - using var connection = new SqlConnection(DataTestUtility.TCPConnectionString); - connection.Open(); + using (var connection = new SqlConnection(DataTestUtility.TCPConnectionString)) + { + connection.Open(); - using var command = new SqlCommand("SELECT @DoesNotExist", connection); - command.EnableOptimizedParameterBinding = true; - command.Parameters.AddWithValue("@Exists", 1); + using (var command = new SqlCommand("SELECT @DoesNotExist", connection)) + { + command.EnableOptimizedParameterBinding = true; + command.Parameters.AddWithValue("@Exists", 1); - SqlException sqlException = null; - try - { - command.ExecuteNonQuery(); - } - catch (SqlException sqlEx) - { - sqlException = sqlEx; - } + SqlException sqlException = null; + try + { + command.ExecuteNonQuery(); + } + catch (SqlException sqlEx) + { + sqlException = sqlEx; + } - Assert.NotNull(sqlException); - Assert.Contains("Must declare the scalar variable", sqlException.Message); - Assert.Contains("@DoesNotExist", sqlException.Message); + Assert.NotNull(sqlException); + Assert.Contains("Must declare the scalar variable", sqlException.Message); + Assert.Contains("@DoesNotExist", sqlException.Message); + } + } } [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup))] private static void EnableOptimizedParameterBinding_AllNamesMustBeDeclared() { - using var connection = new SqlConnection(DataTestUtility.TCPConnectionString); - connection.Open(); + using (var connection = new SqlConnection(DataTestUtility.TCPConnectionString)) + { + connection.Open(); - using var command = new SqlCommand("SELECT @Exists, @DoesNotExist", connection); - command.EnableOptimizedParameterBinding = true; - command.Parameters.AddWithValue("@Exists", 1); + using (var command = new SqlCommand("SELECT @Exists, @DoesNotExist", connection)) + { + command.EnableOptimizedParameterBinding = true; + command.Parameters.AddWithValue("@Exists", 1); - SqlException sqlException = null; - try - { - command.ExecuteNonQuery(); - } - catch (SqlException sqlEx) - { - sqlException = sqlEx; - } + SqlException sqlException = null; + try + { + command.ExecuteNonQuery(); + } + catch (SqlException sqlEx) + { + sqlException = sqlEx; + } - Assert.NotNull(sqlException); - Assert.Contains("Must declare the scalar variable", sqlException.Message); - Assert.Contains("@DoesNotExist", sqlException.Message); + Assert.NotNull(sqlException); + Assert.Contains("Must declare the scalar variable", sqlException.Message); + Assert.Contains("@DoesNotExist", sqlException.Message); + } + } } [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup))] @@ -641,25 +688,31 @@ private static void EnableOptimizedParameterBinding_NamesCanBeReUsed() int secondInput = 2; int thirdInput = 3; - using var connection = new SqlConnection(DataTestUtility.TCPConnectionString); - connection.Open(); + using (var connection = new SqlConnection(DataTestUtility.TCPConnectionString)) + { + connection.Open(); - using var command = new SqlCommand("SELECT @First, @Second, @First", connection); - command.EnableOptimizedParameterBinding = true; - command.Parameters.AddWithValue("@First", firstInput); - command.Parameters.AddWithValue("@Second", secondInput); - command.Parameters.AddWithValue("@Third", thirdInput); + using (var command = new SqlCommand("SELECT @First, @Second, @First", connection)) + { + command.EnableOptimizedParameterBinding = true; + command.Parameters.AddWithValue("@First", firstInput); + command.Parameters.AddWithValue("@Second", secondInput); + command.Parameters.AddWithValue("@Third", thirdInput); - using SqlDataReader reader = command.ExecuteReader(); - reader.Read(); + using (SqlDataReader reader = command.ExecuteReader()) + { + reader.Read(); - int firstOutput = reader.GetInt32(0); - int secondOutput = reader.GetInt32(1); - int thirdOutput = reader.GetInt32(2); + int firstOutput = reader.GetInt32(0); + int secondOutput = reader.GetInt32(1); + int thirdOutput = reader.GetInt32(2); - Assert.Equal(firstInput, firstOutput); - Assert.Equal(secondInput, secondOutput); - Assert.Equal(firstInput, thirdOutput); + Assert.Equal(firstInput, firstOutput); + Assert.Equal(secondInput, secondOutput); + Assert.Equal(firstInput, thirdOutput); + } + } + } } [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup))] @@ -669,19 +722,23 @@ private static void EnableOptimizedParameterBinding_InputOutputFails() int secondInput = 2; int thirdInput = 3; - using var connection = new SqlConnection(DataTestUtility.TCPConnectionString); - connection.Open(); + using (var connection = new SqlConnection(DataTestUtility.TCPConnectionString)) + { + connection.Open(); - using var command = new SqlCommand("SELECT @Third = (@Third + @First + @Second)", connection); - command.EnableOptimizedParameterBinding = true; - command.Parameters.AddWithValue("@First", firstInput); - command.Parameters.AddWithValue("@Second", secondInput); - SqlParameter thirdParameter = command.Parameters.AddWithValue("@Third", thirdInput); - thirdParameter.Direction = ParameterDirection.InputOutput; + using (var command = new SqlCommand("SELECT @Third = (@Third + @First + @Second)", connection)) + { + command.EnableOptimizedParameterBinding = true; + command.Parameters.AddWithValue("@First", firstInput); + command.Parameters.AddWithValue("@Second", secondInput); + SqlParameter thirdParameter = command.Parameters.AddWithValue("@Third", thirdInput); + thirdParameter.Direction = ParameterDirection.InputOutput; - InvalidOperationException exception = Assert.Throws(() => command.ExecuteNonQuery()); + InvalidOperationException exception = Assert.Throws(() => command.ExecuteNonQuery()); - Assert.Contains("OptimizedParameterBinding", exception.Message); + Assert.Contains("OptimizedParameterBinding", exception.Message); + } + } } [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup))] @@ -691,19 +748,23 @@ private static void EnableOptimizedParameterBinding_OutputFails() int secondInput = 2; int thirdInput = 3; - using var connection = new SqlConnection(DataTestUtility.TCPConnectionString); - connection.Open(); + using (var connection = new SqlConnection(DataTestUtility.TCPConnectionString)) + { + connection.Open(); - using var command = new SqlCommand("SELECT @Third = (@Third + @First + @Second)", connection); - command.EnableOptimizedParameterBinding = true; - command.Parameters.AddWithValue("@First", firstInput); - command.Parameters.AddWithValue("@Second", secondInput); - SqlParameter thirdParameter = command.Parameters.AddWithValue("@Third", thirdInput); - thirdParameter.Direction = ParameterDirection.Output; + using (var command = new SqlCommand("SELECT @Third = (@Third + @First + @Second)", connection)) + { + command.EnableOptimizedParameterBinding = true; + command.Parameters.AddWithValue("@First", firstInput); + command.Parameters.AddWithValue("@Second", secondInput); + SqlParameter thirdParameter = command.Parameters.AddWithValue("@Third", thirdInput); + thirdParameter.Direction = ParameterDirection.Output; - InvalidOperationException exception = Assert.Throws(() => command.ExecuteNonQuery()); + InvalidOperationException exception = Assert.Throws(() => command.ExecuteNonQuery()); - Assert.Contains("OptimizedParameterBinding", exception.Message); + Assert.Contains("OptimizedParameterBinding", exception.Message); + } + } } [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup))] @@ -724,18 +785,22 @@ private static void EnableOptimizedParameterBinding_ReturnSucceeds() { ExecuteNonQueryCommand(DataTestUtility.TCPConnectionString, createSprocQuery); - using var connection = new SqlConnection(DataTestUtility.TCPConnectionString); - connection.Open(); + using (var connection = new SqlConnection(DataTestUtility.TCPConnectionString)) + { + connection.Open(); - using var command = new SqlCommand(sprocName, connection) { CommandType = CommandType.StoredProcedure }; - command.EnableOptimizedParameterBinding = true; - command.Parameters.AddWithValue("@in", firstInput); - SqlParameter returnParameter = command.Parameters.AddWithValue("@retval", 0); - returnParameter.Direction = ParameterDirection.ReturnValue; + using (var command = new SqlCommand(sprocName, connection) { CommandType = CommandType.StoredProcedure }) + { + command.EnableOptimizedParameterBinding = true; + command.Parameters.AddWithValue("@in", firstInput); + SqlParameter returnParameter = command.Parameters.AddWithValue("@retval", 0); + returnParameter.Direction = ParameterDirection.ReturnValue; - command.ExecuteNonQuery(); + command.ExecuteNonQuery(); - Assert.Equal(firstInput, Convert.ToInt32(returnParameter.Value)); + Assert.Equal(firstInput, Convert.ToInt32(returnParameter.Value)); + } + } } finally { diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ParameterTest/SqlAdapterUpdateBatch.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ParameterTest/SqlAdapterUpdateBatch.cs index 7f383e8201..90d413a66d 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ParameterTest/SqlAdapterUpdateBatch.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ParameterTest/SqlAdapterUpdateBatch.cs @@ -41,10 +41,12 @@ public void SqlAdapterTest() finally { var dropTableQuery = "DROP TABLE IF EXISTS " + tableName; - using var connection = new SqlConnection(DataTestUtility.TCPConnectionString); - using var cmd = new SqlCommand(dropTableQuery, connection); - connection.Open(); - cmd.ExecuteNonQuery(); + using (var connection = new SqlConnection(DataTestUtility.TCPConnectionString)) + using (var cmd = new SqlCommand(dropTableQuery, connection)) + { + connection.Open(); + cmd.ExecuteNonQuery(); + } } } @@ -63,27 +65,29 @@ public EventInfo() private static void ExecuteNonQueries(string tableName) { - List entities = new() + List entities = new List { - new EventInfo { Level = "L1", Message = "Message 1" }, - new EventInfo { Level = "L2", Message = "Message 2" }, - new EventInfo { Level = "L3", Message = "Message 3" }, - new EventInfo { Level = "L4", Message = "Message 4" }, + new EventInfo {Level = "L1", Message = "Message 1"}, + new EventInfo {Level = "L2", Message = "Message 2"}, + new EventInfo {Level = "L3", Message = "Message 3"}, + new EventInfo {Level = "L4", Message = "Message 4"}, }; var sql = "INSERT INTO " + tableName + "(Level, Message, EventTime) VALUES(@Level, @Message, @EventTime)"; - using var connection = new SqlConnection(DataTestUtility.TCPConnectionString); - using var adapter = new SqlDataAdapter(); - using var cmd = new SqlCommand(sql, connection); - cmd.Parameters.Add(new SqlParameter("@Level", System.Data.SqlDbType.NVarChar, 50, "Level")); - cmd.Parameters.Add(new SqlParameter("@Message", SqlDbType.NVarChar, 500, "Message")); - cmd.Parameters.Add(new SqlParameter("@EventTime", SqlDbType.DateTime, 0, "EventTime")); - cmd.UpdatedRowSource = UpdateRowSource.None; + using (var connection = new SqlConnection(DataTestUtility.TCPConnectionString)) + using (var adapter = new SqlDataAdapter()) + using (var cmd = new SqlCommand(sql, connection)) + { + cmd.Parameters.Add(new SqlParameter("@Level", System.Data.SqlDbType.NVarChar, 50, "Level")); + cmd.Parameters.Add(new SqlParameter("@Message", SqlDbType.NVarChar, 500, "Message")); + cmd.Parameters.Add(new SqlParameter("@EventTime", SqlDbType.DateTime, 0, "EventTime")); + cmd.UpdatedRowSource = UpdateRowSource.None; - adapter.InsertCommand = cmd; - adapter.UpdateBatchSize = 2; + adapter.InsertCommand = cmd; + adapter.UpdateBatchSize = 2; - adapter.Update(ConvertToTable(entities)); + adapter.Update(ConvertToTable(entities)); + } } private static DataTable ConvertToTable(List entities) { @@ -93,9 +97,9 @@ private static DataTable ConvertToTable(List entities) table.Columns.Add("Message", typeof(string)); table.Columns.Add("EventTime", typeof(DateTime)); - foreach (EventInfo entity in entities) + foreach (var entity in entities) { - DataRow row = table.NewRow(); + var row = table.NewRow(); row["Level"] = entity.Level; row["Message"] = entity.Message; row["EventTime"] = entity.EventTime; diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ParameterTest/SqlVariantParam.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ParameterTest/SqlVariantParam.cs index 2d11274191..f27e7d0b1e 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ParameterTest/SqlVariantParam.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ParameterTest/SqlVariantParam.cs @@ -46,7 +46,7 @@ public static void SendAllSqlTypesInsideVariant(string connStr) /// private static SqlDataReader GetReaderForVariant(object paramValue, bool includeBaseType) { - SqlConnection conn = new(s_connStr); + SqlConnection conn = new SqlConnection(s_connStr); conn.Open(); SqlCommand cmd = conn.CreateCommand(); cmd.CommandText = "select @p1 as f1"; @@ -100,8 +100,10 @@ private static void SendVariant(object paramValue, string expectedTypeName, stri /// private static void SendVariantParam(object paramValue, string expectedTypeName, string expectedBaseTypeName) { - using SqlDataReader dr = GetReaderForVariant(paramValue, true); - VerifyReader("SendVariantParam", dr, expectedTypeName, expectedBaseTypeName); + using (SqlDataReader dr = GetReaderForVariant(paramValue, true)) + { + VerifyReader("SendVariantParam", dr, expectedTypeName, expectedBaseTypeName); + } } /// /// Round trip sql_variant value using SqlBulkCopy. @@ -111,83 +113,93 @@ private static void SendVariantBulkCopy(object paramValue, string expectedTypeNa string bulkCopyTableName = DataTestUtility.GetUniqueNameForSqlServer("bulkDest"); // Fetch reader using type. - using SqlDataReader dr = GetReaderForVariant(paramValue, false); - using SqlConnection connBulk = new(s_connStr); - connBulk.Open(); - - ExecuteSQL(connBulk, "create table dbo.{0} (f1 sql_variant)", bulkCopyTableName); - try + using (SqlDataReader dr = GetReaderForVariant(paramValue, false)) { - // Perform bulk copy to target. - using (SqlBulkCopy bulkCopy = new(connBulk)) + using (SqlConnection connBulk = new SqlConnection(s_connStr)) { - bulkCopy.BulkCopyTimeout = 60; - bulkCopy.BatchSize = 1; - bulkCopy.DestinationTableName = bulkCopyTableName; - bulkCopy.WriteToServer(dr); - } + connBulk.Open(); - // Verify target. - using (SqlCommand cmd = connBulk.CreateCommand()) - { - cmd.CommandText = string.Format("select f1, sql_variant_property(f1,'BaseType') as BaseType from {0}", bulkCopyTableName); - using SqlDataReader drVerify = cmd.ExecuteReader(); - VerifyReader("SendVariantBulkCopy[SqlDataReader]", drVerify, expectedTypeName, expectedBaseTypeName); - } + ExecuteSQL(connBulk, "create table dbo.{0} (f1 sql_variant)", bulkCopyTableName); + try + { + // Perform bulk copy to target. + using (SqlBulkCopy bulkCopy = new SqlBulkCopy(connBulk)) + { + bulkCopy.BulkCopyTimeout = 60; + bulkCopy.BatchSize = 1; + bulkCopy.DestinationTableName = bulkCopyTableName; + bulkCopy.WriteToServer(dr); + } - // Truncate target table for next pass. - ExecuteSQL(connBulk, "truncate table {0}", bulkCopyTableName); + // Verify target. + using (SqlCommand cmd = connBulk.CreateCommand()) + { + cmd.CommandText = string.Format("select f1, sql_variant_property(f1,'BaseType') as BaseType from {0}", bulkCopyTableName); + using (SqlDataReader drVerify = cmd.ExecuteReader()) + { + VerifyReader("SendVariantBulkCopy[SqlDataReader]", drVerify, expectedTypeName, expectedBaseTypeName); + } + } - // Send using DataTable as source. - DataTable t = new(); - t.Columns.Add("f1", typeof(object)); - t.Rows.Add(new object[] { paramValue }); + // Truncate target table for next pass. + ExecuteSQL(connBulk, "truncate table {0}", bulkCopyTableName); - // Perform bulk copy to target. - using (SqlBulkCopy bulkCopy = new(connBulk)) - { - bulkCopy.BulkCopyTimeout = 60; - bulkCopy.BatchSize = 1; - bulkCopy.DestinationTableName = bulkCopyTableName; - bulkCopy.WriteToServer(t, DataRowState.Added); - } + // Send using DataTable as source. + DataTable t = new DataTable(); + t.Columns.Add("f1", typeof(object)); + t.Rows.Add(new object[] { paramValue }); - // Verify target. - using (SqlCommand cmd = connBulk.CreateCommand()) - { - cmd.CommandText = string.Format("select f1, sql_variant_property(f1,'BaseType') as BaseType from {0}", bulkCopyTableName); - using SqlDataReader drVerify = cmd.ExecuteReader(); - VerifyReader("SendVariantBulkCopy[DataTable]", drVerify, expectedTypeName, expectedBaseTypeName); - } + // Perform bulk copy to target. + using (SqlBulkCopy bulkCopy = new SqlBulkCopy(connBulk)) + { + bulkCopy.BulkCopyTimeout = 60; + bulkCopy.BatchSize = 1; + bulkCopy.DestinationTableName = bulkCopyTableName; + bulkCopy.WriteToServer(t, DataRowState.Added); + } - // Truncate target table for next pass. - ExecuteSQL(connBulk, "truncate table {0}", bulkCopyTableName); + // Verify target. + using (SqlCommand cmd = connBulk.CreateCommand()) + { + cmd.CommandText = string.Format("select f1, sql_variant_property(f1,'BaseType') as BaseType from {0}", bulkCopyTableName); + using (SqlDataReader drVerify = cmd.ExecuteReader()) + { + VerifyReader("SendVariantBulkCopy[DataTable]", drVerify, expectedTypeName, expectedBaseTypeName); + } + } - // Send using DataRow as source. - DataRow[] rowToSend = t.Select(); + // Truncate target table for next pass. + ExecuteSQL(connBulk, "truncate table {0}", bulkCopyTableName); - // Perform bulk copy to target. - using (SqlBulkCopy bulkCopy = new(connBulk)) - { - bulkCopy.BulkCopyTimeout = 60; - bulkCopy.BatchSize = 1; - bulkCopy.DestinationTableName = bulkCopyTableName; - bulkCopy.WriteToServer(rowToSend); - } + // Send using DataRow as source. + DataRow[] rowToSend = t.Select(); - // Verify target. - using (SqlCommand cmd = connBulk.CreateCommand()) - { - cmd.CommandText = string.Format("select f1, sql_variant_property(f1,'BaseType') as BaseType from {0}", bulkCopyTableName); - using SqlDataReader drVerify = cmd.ExecuteReader(); - VerifyReader("SendVariantBulkCopy[DataRow]", drVerify, expectedTypeName, expectedBaseTypeName); + // Perform bulk copy to target. + using (SqlBulkCopy bulkCopy = new SqlBulkCopy(connBulk)) + { + bulkCopy.BulkCopyTimeout = 60; + bulkCopy.BatchSize = 1; + bulkCopy.DestinationTableName = bulkCopyTableName; + bulkCopy.WriteToServer(rowToSend); + } + + // Verify target. + using (SqlCommand cmd = connBulk.CreateCommand()) + { + cmd.CommandText = string.Format("select f1, sql_variant_property(f1,'BaseType') as BaseType from {0}", bulkCopyTableName); + using (SqlDataReader drVerify = cmd.ExecuteReader()) + { + VerifyReader("SendVariantBulkCopy[DataRow]", drVerify, expectedTypeName, expectedBaseTypeName); + } + } + } + finally + { + // Cleanup target table. + ExecuteSQL(connBulk, "drop table {0}", bulkCopyTableName); + } } } - finally - { - // Cleanup target table. - ExecuteSQL(connBulk, "drop table {0}", bulkCopyTableName); - } } /// /// Round trip sql_variant value using TVP. @@ -196,46 +208,54 @@ private static void SendVariantTvp(object paramValue, string expectedTypeName, s { string tvpTypeName = DataTestUtility.GetUniqueNameForSqlServer("tvpVariant"); - using SqlConnection connTvp = new(s_connStr); - connTvp.Open(); - - ExecuteSQL(connTvp, "create type dbo.{0} as table (f1 sql_variant)", tvpTypeName); - try + using (SqlConnection connTvp = new SqlConnection(s_connStr)) { - // Send TVP using SqlMetaData. - SqlMetaData[] metadata = new SqlMetaData[1]; - metadata[0] = new SqlMetaData("f1", SqlDbType.Variant); - SqlDataRecord[] record = new SqlDataRecord[1]; - record[0] = new SqlDataRecord(metadata); - record[0].SetValue(0, paramValue); - - using (SqlCommand cmd = connTvp.CreateCommand()) + connTvp.Open(); + + ExecuteSQL(connTvp, "create type dbo.{0} as table (f1 sql_variant)", tvpTypeName); + try { - cmd.CommandText = "select f1, sql_variant_property(f1,'BaseType') as BaseType from @tvpParam"; - SqlParameter p = cmd.Parameters.AddWithValue("@tvpParam", record); - p.SqlDbType = SqlDbType.Structured; - p.TypeName = string.Format("dbo.{0}", tvpTypeName); - using SqlDataReader dr = cmd.ExecuteReader(); - VerifyReader("SendVariantTvp[SqlMetaData]", dr, expectedTypeName, expectedBaseTypeName); - } + // Send TVP using SqlMetaData. + SqlMetaData[] metadata = new SqlMetaData[1]; + metadata[0] = new SqlMetaData("f1", SqlDbType.Variant); + SqlDataRecord[] record = new SqlDataRecord[1]; + record[0] = new SqlDataRecord(metadata); + record[0].SetValue(0, paramValue); + + using (SqlCommand cmd = connTvp.CreateCommand()) + { + cmd.CommandText = "select f1, sql_variant_property(f1,'BaseType') as BaseType from @tvpParam"; + SqlParameter p = cmd.Parameters.AddWithValue("@tvpParam", record); + p.SqlDbType = SqlDbType.Structured; + p.TypeName = string.Format("dbo.{0}", tvpTypeName); + using (SqlDataReader dr = cmd.ExecuteReader()) + { + VerifyReader("SendVariantTvp[SqlMetaData]", dr, expectedTypeName, expectedBaseTypeName); + } + } - // Send TVP using SqlDataReader. - using (SqlDataReader dr = GetReaderForVariant(paramValue, false)) + // Send TVP using SqlDataReader. + using (SqlDataReader dr = GetReaderForVariant(paramValue, false)) + { + using (SqlCommand cmd = connTvp.CreateCommand()) + { + cmd.CommandText = "select f1, sql_variant_property(f1,'BaseType') as BaseType from @tvpParam"; + SqlParameter p = cmd.Parameters.AddWithValue("@tvpParam", dr); + p.SqlDbType = SqlDbType.Structured; + p.TypeName = string.Format("dbo.{0}", tvpTypeName); + using (SqlDataReader dr2 = cmd.ExecuteReader()) + { + VerifyReader("SendVariantTvp[SqlDataReader]", dr2, expectedTypeName, expectedBaseTypeName); + } + } + } + } + finally { - using SqlCommand cmd = connTvp.CreateCommand(); - cmd.CommandText = "select f1, sql_variant_property(f1,'BaseType') as BaseType from @tvpParam"; - SqlParameter p = cmd.Parameters.AddWithValue("@tvpParam", dr); - p.SqlDbType = SqlDbType.Structured; - p.TypeName = string.Format("dbo.{0}", tvpTypeName); - using SqlDataReader dr2 = cmd.ExecuteReader(); - VerifyReader("SendVariantTvp[SqlDataReader]", dr2, expectedTypeName, expectedBaseTypeName); + // Cleanup tvp type. + ExecuteSQL(connTvp, "drop type {0}", tvpTypeName); } } - finally - { - // Cleanup tvp type. - ExecuteSQL(connTvp, "drop type {0}", tvpTypeName); - } } /// /// Helper to execute t-sql with variable object name. @@ -245,9 +265,22 @@ private static void SendVariantTvp(object paramValue, string expectedTypeName, s /// Variable object name for t-sql private static void ExecuteSQL(SqlConnection conn, string formatSql, string objectName) { - using SqlCommand cmd = conn.CreateCommand(); - cmd.CommandText = string.Format(formatSql, objectName); - cmd.ExecuteNonQuery(); + using (SqlCommand cmd = conn.CreateCommand()) + { + cmd.CommandText = string.Format(formatSql, objectName); + cmd.ExecuteNonQuery(); + } + } + /// + /// Simple helper to execute t-sql. + /// + private static void ExecuteSQL(SqlConnection conn, string sql) + { + using (SqlCommand cmd = conn.CreateCommand()) + { + cmd.CommandText = sql; + cmd.ExecuteNonQuery(); + } } } } diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ParameterTest/SteAttribute.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ParameterTest/SteAttribute.cs index be82171115..2dcafd004b 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ParameterTest/SteAttribute.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ParameterTest/SteAttribute.cs @@ -8,19 +8,19 @@ namespace Microsoft.Data.SqlClient.ManualTesting.Tests { public class SteAttributeKey { - public static readonly SteAttributeKey SqlDbType = new(); - public static readonly SteAttributeKey MultiValued = new(); - public static readonly SteAttributeKey Value = new(); - public static readonly SteAttributeKey MaxLength = new(); - public static readonly SteAttributeKey Precision = new(); - public static readonly SteAttributeKey Scale = new(); - public static readonly SteAttributeKey LocaleId = new(); - public static readonly SteAttributeKey CompareOptions = new(); - public static readonly SteAttributeKey TypeName = new(); - public static readonly SteAttributeKey Type = new(); - public static readonly SteAttributeKey Fields = new(); - public static readonly SteAttributeKey Offset = new(); - public static readonly SteAttributeKey Length = new(); + public static readonly SteAttributeKey SqlDbType = new SteAttributeKey(); + public static readonly SteAttributeKey MultiValued = new SteAttributeKey(); + public static readonly SteAttributeKey Value = new SteAttributeKey(); + public static readonly SteAttributeKey MaxLength = new SteAttributeKey(); + public static readonly SteAttributeKey Precision = new SteAttributeKey(); + public static readonly SteAttributeKey Scale = new SteAttributeKey(); + public static readonly SteAttributeKey LocaleId = new SteAttributeKey(); + public static readonly SteAttributeKey CompareOptions = new SteAttributeKey(); + public static readonly SteAttributeKey TypeName = new SteAttributeKey(); + public static readonly SteAttributeKey Type = new SteAttributeKey(); + public static readonly SteAttributeKey Fields = new SteAttributeKey(); + public static readonly SteAttributeKey Offset = new SteAttributeKey(); + public static readonly SteAttributeKey Length = new SteAttributeKey(); public static readonly IList MetaDataKeys = new List( new SteAttributeKey[] { @@ -44,8 +44,8 @@ public class SteAttributeKey public class SteAttribute { - private readonly SteAttributeKey _key; - private readonly object _value; + private SteAttributeKey _key; + private object _value; public SteAttribute(SteAttributeKey key, object value) { diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ParameterTest/SteParam.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ParameterTest/SteParam.cs index cb6d2de7d5..153d1fe324 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ParameterTest/SteParam.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ParameterTest/SteParam.cs @@ -13,8 +13,9 @@ public class SteParam // Map values from a permutation into a parameter (doesn't currently map values) public static void Map(StePermutation perm, SqlParameter param) { + object attr; bool didSetSqlDbType = false; - if (perm.TryGetValue(SteAttributeKey.SqlDbType, out object attr) && (attr != SteTypeBoundaries.s_doNotUseMarker)) + if (perm.TryGetValue(SteAttributeKey.SqlDbType, out attr) && (attr != SteTypeBoundaries.s_doNotUseMarker)) { param.SqlDbType = (SqlDbType)attr; didSetSqlDbType = true; diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ParameterTest/StePermutationSet.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ParameterTest/StePermutationSet.cs index 82754022a9..79b3364fd4 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ParameterTest/StePermutationSet.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ParameterTest/StePermutationSet.cs @@ -5,7 +5,6 @@ using System; using System.Collections; using System.Collections.Generic; -using System.Text; namespace Microsoft.Data.SqlClient.ManualTesting.Tests { @@ -13,7 +12,7 @@ public class StePermutation : Dictionary { public override string ToString() { - StringBuilder b = new(); + System.Text.StringBuilder b = new System.Text.StringBuilder(); bool needSeparator = false; foreach (KeyValuePair pair in this) { @@ -37,9 +36,15 @@ public override string ToString() public abstract class StePermutationGenerator : IEnumerable { // standard GetEnumerator, implemented in terms of specialized enumerator - public IEnumerator GetEnumerator() => GetEnumerator(DefaultKeys); + public IEnumerator GetEnumerator() + { + return this.GetEnumerator(this.DefaultKeys); + } - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(DefaultKeys); + IEnumerator IEnumerable.GetEnumerator() + { + return this.GetEnumerator(this.DefaultKeys); + } public abstract IEnumerable DefaultKeys { @@ -65,8 +70,8 @@ private enum LogicalPosition AfterElements // Position is after final element } - private readonly SteSimplePermutationGenerator _parent; // Source of enumeration elements - private readonly List _keysOfInterest; // attribute keys to use to generate permutations + private SteSimplePermutationGenerator _parent; // Source of enumeration elements + private List _keysOfInterest; // attribute keys to use to generate permutations private IEnumerator[] _position; // One enumerator for each non-empty attribute list in parent private LogicalPosition _logicalPosition; // Logical positioning of self @@ -82,7 +87,8 @@ public SteSimplePermEnumerator(SteSimplePermutationGenerator parent, IEnumerable _keysOfInterest = new List(); foreach (SteAttributeKey key in keysOfInterest) { - if (_parent.AttributeLists.TryGetValue(key, out ArrayList list) && list.Count > 0) + ArrayList list; + if (_parent.AttributeLists.TryGetValue(key, out list) && list.Count > 0) { _keysOfInterest.Add(key); } @@ -151,7 +157,13 @@ public StePermutation Current } } - object IEnumerator.Current => Current; + object IEnumerator.Current + { + get + { + return this.Current; + } + } // Standard enumerator restart method public void Reset() @@ -184,7 +196,7 @@ public void Dispose() } // permutationGenerator private fields - private readonly Dictionary _permutationBase; + private Dictionary _permutationBase; // generator's ctor public SteSimplePermutationGenerator() @@ -204,7 +216,8 @@ public override IEnumerable DefaultKeys // Add a new attribute to the set public void Add(SteAttributeKey key, object attribute) { - if (!_permutationBase.TryGetValue(key, out ArrayList targetList)) + ArrayList targetList; + if (!_permutationBase.TryGetValue(key, out targetList)) { targetList = new ArrayList(); _permutationBase.Add(key, targetList); diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ParameterTest/SteTypeBoundaries.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ParameterTest/SteTypeBoundaries.cs index b469c0795b..aa11d34b94 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ParameterTest/SteTypeBoundaries.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ParameterTest/SteTypeBoundaries.cs @@ -7,7 +7,6 @@ using System.Collections.Generic; using System.Data; using System.Data.SqlTypes; -using System.Text; namespace Microsoft.Data.SqlClient.ManualTesting.Tests { @@ -15,7 +14,7 @@ public abstract class SteTypeBoundaries : StePermutationGenerator { // Use this marker for attribute value to indicate the attribute is not used // (ex. option where Decimal parameter's Scale property should not be set at all) - public static object s_doNotUseMarker = new(); + public static object s_doNotUseMarker = new object(); } // simple types can just wrap a simple permutation generator @@ -32,225 +31,199 @@ public class SteSimpleTypeBoundaries : SteTypeBoundaries public static readonly IList s_udtsOnly; static SteSimpleTypeBoundaries() { - List list = new(); + List list = new List(); // DevNote: Don't put null value attributes first -- it confuses DataTable generation for SteStructuredTypeBoundaries // BigInt - SteSimplePermutationGenerator type = new() - { - { SteAttributeKey.SqlDbType, SqlDbType.BigInt }, - { SteAttributeKey.Value, (long)0 }, - { SteAttributeKey.Value, long.MaxValue }, - { SteAttributeKey.Value, long.MinValue }, - { SteAttributeKey.Value, new SqlInt64(long.MaxValue) }, - { SteAttributeKey.Value, new SqlInt64(long.MinValue) }, - { SteAttributeKey.Value, null }, - { SteAttributeKey.Value, DBNull.Value } - }; + SteSimplePermutationGenerator type = new SteSimplePermutationGenerator(); + type.Add(SteAttributeKey.SqlDbType, SqlDbType.BigInt); + type.Add(SteAttributeKey.Value, (long)0); + type.Add(SteAttributeKey.Value, long.MaxValue); + type.Add(SteAttributeKey.Value, long.MinValue); + type.Add(SteAttributeKey.Value, new SqlInt64(long.MaxValue)); + type.Add(SteAttributeKey.Value, new SqlInt64(long.MinValue)); + type.Add(SteAttributeKey.Value, null); + type.Add(SteAttributeKey.Value, DBNull.Value); list.Add(new SteSimpleTypeBoundaries(type)); // Binary types - type = new SteSimplePermutationGenerator - { - { SteAttributeKey.SqlDbType, SqlDbType.Binary }, - { SteAttributeKey.SqlDbType, SqlDbType.VarBinary }, - { SteAttributeKey.SqlDbType, SqlDbType.Image }, - { SteAttributeKey.MaxLength, 1 }, // a small value - { SteAttributeKey.MaxLength, 40 }, // Somewhere in the middle - { SteAttributeKey.MaxLength, 8000 }, // Couple values around maximum tds length - { SteAttributeKey.Value, CreateByteArray(0) }, - { SteAttributeKey.Value, CreateByteArray(1) }, - { SteAttributeKey.Value, CreateByteArray(50) }, - { SteAttributeKey.Value, s_moderateSizeByteArray }, - { SteAttributeKey.Value, new SqlBytes(CreateByteArray(0)) }, - { SteAttributeKey.Value, new SqlBytes(CreateByteArray(1)) }, - { SteAttributeKey.Value, new SqlBytes(CreateByteArray(40)) }, - { SteAttributeKey.Value, new SqlBytes(s_moderateSizeByteArray) }, - { SteAttributeKey.Value, null }, - { SteAttributeKey.Value, DBNull.Value }, - { SteAttributeKey.Offset, s_doNotUseMarker }, - { SteAttributeKey.Offset, -1 }, - { SteAttributeKey.Offset, 0 }, - { SteAttributeKey.Offset, 10 }, - { SteAttributeKey.Offset, 8000 }, - { SteAttributeKey.Offset, int.MaxValue }, - { SteAttributeKey.Length, 0 }, - { SteAttributeKey.Length, 40 }, - { SteAttributeKey.Length, 8000 }, - { SteAttributeKey.Length, 1000000 }, - { SteAttributeKey.Length, -1 } - }; + type = new SteSimplePermutationGenerator(); + type.Add(SteAttributeKey.SqlDbType, SqlDbType.Binary); + type.Add(SteAttributeKey.SqlDbType, SqlDbType.VarBinary); + type.Add(SteAttributeKey.SqlDbType, SqlDbType.Image); + type.Add(SteAttributeKey.MaxLength, 1); // a small value + type.Add(SteAttributeKey.MaxLength, 40); // Somewhere in the middle + type.Add(SteAttributeKey.MaxLength, 8000); // Couple values around maximum tds length + type.Add(SteAttributeKey.Value, CreateByteArray(0)); + type.Add(SteAttributeKey.Value, CreateByteArray(1)); + type.Add(SteAttributeKey.Value, CreateByteArray(50)); + type.Add(SteAttributeKey.Value, s_moderateSizeByteArray); + type.Add(SteAttributeKey.Value, new SqlBytes(CreateByteArray(0))); + type.Add(SteAttributeKey.Value, new SqlBytes(CreateByteArray(1))); + type.Add(SteAttributeKey.Value, new SqlBytes(CreateByteArray(40))); + type.Add(SteAttributeKey.Value, new SqlBytes(s_moderateSizeByteArray)); + type.Add(SteAttributeKey.Value, null); + type.Add(SteAttributeKey.Value, DBNull.Value); + type.Add(SteAttributeKey.Offset, s_doNotUseMarker); + type.Add(SteAttributeKey.Offset, -1); + type.Add(SteAttributeKey.Offset, 0); + type.Add(SteAttributeKey.Offset, 10); + type.Add(SteAttributeKey.Offset, 8000); + type.Add(SteAttributeKey.Offset, int.MaxValue); + type.Add(SteAttributeKey.Length, 0); + type.Add(SteAttributeKey.Length, 40); + type.Add(SteAttributeKey.Length, 8000); + type.Add(SteAttributeKey.Length, 1000000); + type.Add(SteAttributeKey.Length, -1); list.Add(new SteSimpleTypeBoundaries(type)); // Byte - type = new SteSimplePermutationGenerator - { - { SteAttributeKey.SqlDbType, SqlDbType.TinyInt }, - { SteAttributeKey.Value, byte.MaxValue }, - { SteAttributeKey.Value, byte.MinValue }, - { SteAttributeKey.Value, null }, - { SteAttributeKey.Value, DBNull.Value } - }; + type = new SteSimplePermutationGenerator(); + type.Add(SteAttributeKey.SqlDbType, SqlDbType.TinyInt); + type.Add(SteAttributeKey.Value, byte.MaxValue); + type.Add(SteAttributeKey.Value, byte.MinValue); + type.Add(SteAttributeKey.Value, null); + type.Add(SteAttributeKey.Value, DBNull.Value); list.Add(new SteSimpleTypeBoundaries(type)); // Character (ANSI) - type = new SteSimplePermutationGenerator - { - { SteAttributeKey.SqlDbType, SqlDbType.Char }, - { SteAttributeKey.SqlDbType, SqlDbType.Text }, - { SteAttributeKey.SqlDbType, SqlDbType.VarChar }, - { SteAttributeKey.MaxLength, 1 }, - { SteAttributeKey.MaxLength, 30 }, - { SteAttributeKey.MaxLength, 8000 }, - { SteAttributeKey.Value, CreateString(1) }, - { SteAttributeKey.Value, CreateString(20) }, - { SteAttributeKey.Value, s_moderateSizeString }, - { SteAttributeKey.Value, CreateString(1).ToCharArray() }, - { SteAttributeKey.Value, CreateString(25).ToCharArray() }, - { SteAttributeKey.Value, s_moderateSizeCharArray }, - { SteAttributeKey.Value, new SqlChars(CreateString(1).ToCharArray()) }, - { SteAttributeKey.Value, new SqlChars(CreateString(30).ToCharArray()) }, - { SteAttributeKey.Value, new SqlChars(s_moderateSizeCharArray) }, - { SteAttributeKey.Value, null }, - { SteAttributeKey.Value, DBNull.Value } - }; + type = new SteSimplePermutationGenerator(); + type.Add(SteAttributeKey.SqlDbType, SqlDbType.Char); + type.Add(SteAttributeKey.SqlDbType, SqlDbType.Text); + type.Add(SteAttributeKey.SqlDbType, SqlDbType.VarChar); + type.Add(SteAttributeKey.MaxLength, 1); + type.Add(SteAttributeKey.MaxLength, 30); + type.Add(SteAttributeKey.MaxLength, 8000); + type.Add(SteAttributeKey.Value, CreateString(1)); + type.Add(SteAttributeKey.Value, CreateString(20)); + type.Add(SteAttributeKey.Value, s_moderateSizeString); + type.Add(SteAttributeKey.Value, CreateString(1).ToCharArray()); + type.Add(SteAttributeKey.Value, CreateString(25).ToCharArray()); + type.Add(SteAttributeKey.Value, s_moderateSizeCharArray); + type.Add(SteAttributeKey.Value, new SqlChars(CreateString(1).ToCharArray())); + type.Add(SteAttributeKey.Value, new SqlChars(CreateString(30).ToCharArray())); + type.Add(SteAttributeKey.Value, new SqlChars(s_moderateSizeCharArray)); + type.Add(SteAttributeKey.Value, null); + type.Add(SteAttributeKey.Value, DBNull.Value); list.Add(new SteSimpleTypeBoundaries(type)); // Character (UNICODE) - type = new SteSimplePermutationGenerator - { - { SteAttributeKey.SqlDbType, SqlDbType.NChar }, - { SteAttributeKey.SqlDbType, SqlDbType.NText }, - { SteAttributeKey.SqlDbType, SqlDbType.NVarChar }, - { SteAttributeKey.MaxLength, 1 }, - { SteAttributeKey.MaxLength, 35 }, - { SteAttributeKey.MaxLength, 4000 }, - { SteAttributeKey.Value, CreateString(1) }, - { SteAttributeKey.Value, CreateString(15) }, - { SteAttributeKey.Value, s_moderateSizeString }, - { SteAttributeKey.Value, CreateString(1).ToCharArray() }, - { SteAttributeKey.Value, CreateString(20).ToCharArray() }, - { SteAttributeKey.Value, s_moderateSizeCharArray }, - { SteAttributeKey.Value, new SqlChars(CreateString(1).ToCharArray()) }, - { SteAttributeKey.Value, new SqlChars(CreateString(25).ToCharArray()) }, - { SteAttributeKey.Value, new SqlChars(s_moderateSizeCharArray) }, - { SteAttributeKey.Value, null }, - { SteAttributeKey.Value, DBNull.Value } - }; + type = new SteSimplePermutationGenerator(); + type.Add(SteAttributeKey.SqlDbType, SqlDbType.NChar); + type.Add(SteAttributeKey.SqlDbType, SqlDbType.NText); + type.Add(SteAttributeKey.SqlDbType, SqlDbType.NVarChar); + type.Add(SteAttributeKey.MaxLength, 1); + type.Add(SteAttributeKey.MaxLength, 35); + type.Add(SteAttributeKey.MaxLength, 4000); + type.Add(SteAttributeKey.Value, CreateString(1)); + type.Add(SteAttributeKey.Value, CreateString(15)); + type.Add(SteAttributeKey.Value, s_moderateSizeString); + type.Add(SteAttributeKey.Value, CreateString(1).ToCharArray()); + type.Add(SteAttributeKey.Value, CreateString(20).ToCharArray()); + type.Add(SteAttributeKey.Value, s_moderateSizeCharArray); + type.Add(SteAttributeKey.Value, new SqlChars(CreateString(1).ToCharArray())); + type.Add(SteAttributeKey.Value, new SqlChars(CreateString(25).ToCharArray())); + type.Add(SteAttributeKey.Value, new SqlChars(s_moderateSizeCharArray)); + type.Add(SteAttributeKey.Value, null); + type.Add(SteAttributeKey.Value, DBNull.Value); list.Add(new SteSimpleTypeBoundaries(type)); // DateTime - type = new SteSimplePermutationGenerator - { - { SteAttributeKey.SqlDbType, SqlDbType.DateTime }, - { SteAttributeKey.SqlDbType, SqlDbType.SmallDateTime }, - { SteAttributeKey.Value, new DateTime(1753, 1, 1) }, - { SteAttributeKey.Value, new SqlDateTime(new DateTime(1753, 1, 1)) }, // min SqlDateTime - { SteAttributeKey.Value, null }, - { SteAttributeKey.Value, DBNull.Value } - }; + type = new SteSimplePermutationGenerator(); + type.Add(SteAttributeKey.SqlDbType, SqlDbType.DateTime); + type.Add(SteAttributeKey.SqlDbType, SqlDbType.SmallDateTime); + type.Add(SteAttributeKey.Value, new DateTime(1753, 1, 1)); + type.Add(SteAttributeKey.Value, new SqlDateTime(new DateTime(1753, 1, 1))); // min SqlDateTime + type.Add(SteAttributeKey.Value, null); + type.Add(SteAttributeKey.Value, DBNull.Value); list.Add(new SteSimpleTypeBoundaries(type)); // Decimal // the TVP test isn't robust in the face of OverflowExceptions on input, so a number of these // values are commented out and other numbers substituted. - type = new SteSimplePermutationGenerator - { - { SteAttributeKey.SqlDbType, SqlDbType.Decimal }, - { SteAttributeKey.Precision, (byte)38 }, - { SteAttributeKey.Scale, (byte)0 }, - { SteAttributeKey.Scale, (byte)10 }, - { SteAttributeKey.Value, (decimal)0 }, - { SteAttributeKey.Value, decimal.MaxValue / 10000000000 }, - { SteAttributeKey.Value, new SqlDecimal(0) }, - { SteAttributeKey.Value, ((SqlDecimal)1234567890123456.789012345678M) * 100 }, // Bigger than a Decimal - { SteAttributeKey.Value, null }, - { SteAttributeKey.Value, DBNull.Value } - }; + type = new SteSimplePermutationGenerator(); + type.Add(SteAttributeKey.SqlDbType, SqlDbType.Decimal); + type.Add(SteAttributeKey.Precision, (byte)38); + type.Add(SteAttributeKey.Scale, (byte)0); + type.Add(SteAttributeKey.Scale, (byte)10); + type.Add(SteAttributeKey.Value, (decimal)0); + type.Add(SteAttributeKey.Value, decimal.MaxValue / 10000000000); + type.Add(SteAttributeKey.Value, new SqlDecimal(0)); + type.Add(SteAttributeKey.Value, ((SqlDecimal)1234567890123456.789012345678M) * 100); // Bigger than a Decimal + type.Add(SteAttributeKey.Value, null); + type.Add(SteAttributeKey.Value, DBNull.Value); list.Add(new SteSimpleTypeBoundaries(type)); // Float - type = new SteSimplePermutationGenerator - { - { SteAttributeKey.SqlDbType, SqlDbType.Float }, - { SteAttributeKey.Value, (double)0 }, - { SteAttributeKey.Value, double.MaxValue }, - { SteAttributeKey.Value, double.MinValue }, - { SteAttributeKey.Value, new SqlDouble(double.MaxValue) }, - { SteAttributeKey.Value, new SqlDouble(double.MinValue) }, - { SteAttributeKey.Value, null }, - { SteAttributeKey.Value, DBNull.Value } - }; + type = new SteSimplePermutationGenerator(); + type.Add(SteAttributeKey.SqlDbType, SqlDbType.Float); + type.Add(SteAttributeKey.Value, (double)0); + type.Add(SteAttributeKey.Value, double.MaxValue); + type.Add(SteAttributeKey.Value, double.MinValue); + type.Add(SteAttributeKey.Value, new SqlDouble(double.MaxValue)); + type.Add(SteAttributeKey.Value, new SqlDouble(double.MinValue)); + type.Add(SteAttributeKey.Value, null); + type.Add(SteAttributeKey.Value, DBNull.Value); list.Add(new SteSimpleTypeBoundaries(type)); // Int - type = new SteSimplePermutationGenerator - { - { SteAttributeKey.SqlDbType, SqlDbType.Int }, - { SteAttributeKey.Value, (int)0 }, - { SteAttributeKey.Value, int.MaxValue }, - { SteAttributeKey.Value, int.MinValue }, - { SteAttributeKey.Value, new SqlInt32(int.MaxValue) }, - { SteAttributeKey.Value, new SqlInt32(int.MinValue) }, - { SteAttributeKey.Value, null }, - { SteAttributeKey.Value, DBNull.Value } - }; + type = new SteSimplePermutationGenerator(); + type.Add(SteAttributeKey.SqlDbType, SqlDbType.Int); + type.Add(SteAttributeKey.Value, (int)0); + type.Add(SteAttributeKey.Value, int.MaxValue); + type.Add(SteAttributeKey.Value, int.MinValue); + type.Add(SteAttributeKey.Value, new SqlInt32(int.MaxValue)); + type.Add(SteAttributeKey.Value, new SqlInt32(int.MinValue)); + type.Add(SteAttributeKey.Value, null); + type.Add(SteAttributeKey.Value, DBNull.Value); list.Add(new SteSimpleTypeBoundaries(type)); // Money types - type = new SteSimplePermutationGenerator - { - { SteAttributeKey.SqlDbType, SqlDbType.Money }, - { SteAttributeKey.SqlDbType, SqlDbType.SmallMoney }, - { SteAttributeKey.Value, (decimal)0 }, - { SteAttributeKey.Value, (decimal)unchecked(((long)0x8000000000000000L) / 10000) }, - { SteAttributeKey.Value, (decimal)0x7FFFFFFFFFFFFFFFL / 10000 }, - { SteAttributeKey.Value, new decimal(-214748.3648) }, // smallmoney min - { SteAttributeKey.Value, new decimal(214748.3647) }, // smallmoney max - { SteAttributeKey.Value, new SqlMoney(((decimal)int.MaxValue) / 10000) }, - { SteAttributeKey.Value, new SqlMoney(((decimal)int.MinValue) / 10000) }, - { SteAttributeKey.Value, null }, - { SteAttributeKey.Value, DBNull.Value } - }; + type = new SteSimplePermutationGenerator(); + type.Add(SteAttributeKey.SqlDbType, SqlDbType.Money); + type.Add(SteAttributeKey.SqlDbType, SqlDbType.SmallMoney); + type.Add(SteAttributeKey.Value, (decimal)0); + type.Add(SteAttributeKey.Value, (decimal)unchecked(((long)0x8000000000000000L) / 10000)); + type.Add(SteAttributeKey.Value, (decimal)0x7FFFFFFFFFFFFFFFL / 10000); + type.Add(SteAttributeKey.Value, new decimal(-214748.3648)); // smallmoney min + type.Add(SteAttributeKey.Value, new decimal(214748.3647)); // smallmoney max + type.Add(SteAttributeKey.Value, new SqlMoney(((decimal)int.MaxValue) / 10000)); + type.Add(SteAttributeKey.Value, new SqlMoney(((decimal)int.MinValue) / 10000)); + type.Add(SteAttributeKey.Value, null); + type.Add(SteAttributeKey.Value, DBNull.Value); list.Add(new SteSimpleTypeBoundaries(type)); // Real - type = new SteSimplePermutationGenerator - { - { SteAttributeKey.SqlDbType, SqlDbType.Real }, - { SteAttributeKey.Value, (float)0 }, - { SteAttributeKey.Value, float.MaxValue }, - { SteAttributeKey.Value, float.MinValue }, - { SteAttributeKey.Value, new SqlSingle(float.MaxValue) }, - { SteAttributeKey.Value, new SqlSingle(float.MinValue) }, - { SteAttributeKey.Value, null }, - { SteAttributeKey.Value, DBNull.Value } - }; + type = new SteSimplePermutationGenerator(); + type.Add(SteAttributeKey.SqlDbType, SqlDbType.Real); + type.Add(SteAttributeKey.Value, (float)0); + type.Add(SteAttributeKey.Value, float.MaxValue); + type.Add(SteAttributeKey.Value, float.MinValue); + type.Add(SteAttributeKey.Value, new SqlSingle(float.MaxValue)); + type.Add(SteAttributeKey.Value, new SqlSingle(float.MinValue)); + type.Add(SteAttributeKey.Value, null); + type.Add(SteAttributeKey.Value, DBNull.Value); list.Add(new SteSimpleTypeBoundaries(type)); // SmallInt - type = new SteSimplePermutationGenerator - { - { SteAttributeKey.SqlDbType, SqlDbType.SmallInt }, - { SteAttributeKey.Value, (short)0 }, - { SteAttributeKey.Value, short.MaxValue }, - { SteAttributeKey.Value, short.MinValue }, - { SteAttributeKey.Value, new SqlInt16(short.MaxValue) }, - { SteAttributeKey.Value, new SqlInt16(short.MinValue) }, - { SteAttributeKey.Value, null }, - { SteAttributeKey.Value, DBNull.Value } - }; + type = new SteSimplePermutationGenerator(); + type.Add(SteAttributeKey.SqlDbType, SqlDbType.SmallInt); + type.Add(SteAttributeKey.Value, (short)0); + type.Add(SteAttributeKey.Value, short.MaxValue); + type.Add(SteAttributeKey.Value, short.MinValue); + type.Add(SteAttributeKey.Value, new SqlInt16(short.MaxValue)); + type.Add(SteAttributeKey.Value, new SqlInt16(short.MinValue)); + type.Add(SteAttributeKey.Value, null); + type.Add(SteAttributeKey.Value, DBNull.Value); list.Add(new SteSimpleTypeBoundaries(type)); // UniqueIdentifier - type = new SteSimplePermutationGenerator - { - { SteAttributeKey.SqlDbType, SqlDbType.UniqueIdentifier }, - { SteAttributeKey.Value, new Guid() }, - { SteAttributeKey.Value, null }, - { SteAttributeKey.Value, DBNull.Value } - }; + type = new SteSimplePermutationGenerator(); + type.Add(SteAttributeKey.SqlDbType, SqlDbType.UniqueIdentifier); + type.Add(SteAttributeKey.Value, new Guid()); + type.Add(SteAttributeKey.Value, null); + type.Add(SteAttributeKey.Value, DBNull.Value); list.Add(new SteSimpleTypeBoundaries(type)); // UDT @@ -278,7 +251,7 @@ static SteSimpleTypeBoundaries() //UdtsOnly = list.AsReadOnly(); } - private readonly SteSimplePermutationGenerator _generator; + private SteSimplePermutationGenerator _generator; public SteSimpleTypeBoundaries(SteSimplePermutationGenerator generator) { @@ -298,11 +271,11 @@ public override IEnumerator GetEnumerator(IEnumerable s_valueKey = new List(new SteAttributeKey[] { SteAttributeKey.Value }); + private static IList __valueKey = new List(new SteAttributeKey[] { SteAttributeKey.Value }); - private readonly SteStructuredTypeBoundaries _parent; - private readonly bool _isMultiValued; - private readonly IList _metaDataKeysOfInterest; // metadata keys that should be used + private SteStructuredTypeBoundaries _parent; + private bool _isMultiValued; + private IList _metaDataKeysOfInterest; // metadata keys that should be used private object[][] _separateValueList; // use the value list separately? private IList> _fieldEnumerators; // List of enumerators over subordinate types private bool[] _completed; // Which enumerators have already completed? private LogicalPosition _logicalPosition; // Logical positioning of self private int _typeNumber; // used to uniquely separate each type for this session - private readonly string _typeNameBase; + private string _typeNameBase; private StePermutation _current; - private readonly StePermutation _rowCountColumn; + private StePermutation _rowCountColumn; public SteStructuredTypeBoundariesEnumerator( SteStructuredTypeBoundaries parent, IEnumerable keysOfInterest, bool isMultiValued) @@ -435,7 +408,13 @@ public StePermutation Current } } - object IEnumerator.Current => Current; + object IEnumerator.Current + { + get + { + return this.Current; + } + } public void Dispose() { @@ -490,7 +469,7 @@ public bool MoveNext() { if (LogicalPosition.OnElement == _logicalPosition) { - List fields = new(); + List fields = new List(); foreach (IEnumerator field in _fieldEnumerators) { fields.Add(field.Current); @@ -539,7 +518,7 @@ private void CreateSeparateValueList() int i = 0; foreach (SteSimpleTypeBoundaries field in _parent.ColumnTypes) { - valueSources[i] = field.GetEnumerator(s_valueKey); + valueSources[i] = field.GetEnumerator(__valueKey); valueList[i] = new ArrayList(); i++; } @@ -598,7 +577,7 @@ private void CreateSeparateValueList() private StePermutation CreateTopLevelPermutation(IList fields) { - StePermutation perm = new(); + StePermutation perm = new StePermutation(); if (0 <= _metaDataKeysOfInterest.IndexOf(SteAttributeKey.SqlDbType)) { perm.Add(SteAttributeKey.SqlDbType, SqlDbType.Structured); @@ -650,23 +629,21 @@ static SteStructuredTypeBoundaries() AllColumnTypes = new SteStructuredTypeBoundaries(SteSimpleTypeBoundaries.s_allTypes, true); UdtsOnly = new SteStructuredTypeBoundaries(SteSimpleTypeBoundaries.s_udtsOnly, true); - AllTypes = new List - { - AllColumnTypes, - AllColumnTypesExceptUdts, - UdtsOnly - }; + AllTypes = new List(); + AllTypes.Add(AllColumnTypes); + AllTypes.Add(AllColumnTypesExceptUdts); + AllTypes.Add(UdtsOnly); } // instance fields - private readonly IList _columnTypes; - private readonly bool _isMultiValued; + private IList _columnTypes; + private bool _isMultiValued; // ctor public SteStructuredTypeBoundaries(IList columnTypes, bool isMultiValued) { _columnTypes = columnTypes; - _isMultiValued = isMultiValued; + _isMultiValued = true; } private IList ColumnTypes @@ -681,7 +658,7 @@ public override IEnumerable DefaultKeys { get { - List result = new(); + List result = new List(); foreach (SteSimpleTypeBoundaries column in _columnTypes) { foreach (SteAttributeKey columnKey in column.DefaultKeys) @@ -724,7 +701,8 @@ public override IEnumerator GetEnumerator(IEnumerable enumerator) { - if (enumerator is SteStructuredTypeBoundariesEnumerator myEnum) + SteStructuredTypeBoundariesEnumerator myEnum = enumerator as SteStructuredTypeBoundariesEnumerator; + if (null != myEnum) { return myEnum.SeparateValues; } diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ParameterTest/StreamInputParam.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ParameterTest/StreamInputParam.cs index 91676446d8..3d15b4346b 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ParameterTest/StreamInputParam.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ParameterTest/StreamInputParam.cs @@ -15,7 +15,7 @@ namespace Microsoft.Data.SqlClient.ManualTesting.Tests { public static class StreamInputParam { - private static readonly Random s_rand = new(9999); + private static Random s_rand = new Random(9999); private static string s_connStr = null; private static bool s_useSP = false; @@ -25,11 +25,12 @@ internal class CustomStreamException : Exception internal class CustomStream : Stream { - private readonly byte[] _data; - private readonly bool _sync; + byte[] _data; + bool _sync; int _pos = 0; - private readonly int _errorPos = 0; - readonly Random _r = new(8888); + int _errorPos = 0; + + Random r = new Random(8888); public CustomStream(byte[] data, bool sync, int errorPos) { @@ -89,7 +90,7 @@ private int ReadInternal(byte[] buffer, int offset, int count) } else { - nRead = 1 + _r.Next(Math.Min(count, _data.Length - _pos) - 1); + nRead = 1 + r.Next(Math.Min(count, _data.Length - _pos) - 1); } if (_errorPos >= _pos && _errorPos < _pos + nRead) throw new CustomStreamException(); @@ -107,7 +108,7 @@ public override int Read(byte[] buffer, int offset, int count) public override Task ReadAsync(byte[] buffer, int offset, int count, System.Threading.CancellationToken cancellationToken) { Debug.Assert(!_sync, "Custom stream reader: Async read in sync mode"); - TaskCompletionSource tcs = new(); + TaskCompletionSource tcs = new TaskCompletionSource(); tcs.SetResult(ReadInternal(buffer, offset, count)); return tcs.Task; } @@ -157,103 +158,98 @@ private static void TestCustomStream(int dataLen, bool sync, bool oldTypes, int private static void TestStreamHelper(byte[] val, object stream, bool sync, bool oldTypes, int paramLen, bool expectException, bool addWithValue) { - using SqlConnection conn = new(s_connStr); - conn.Open(); - using SqlCommand command = new() - { - CommandText = "create table #blobs (id INT, blob VARBINARY(MAX))", - Connection = conn - }; - _ = command.ExecuteNonQuery(); - try + using (SqlConnection conn = new SqlConnection(s_connStr)) { - SqlCommand ins; - if (!s_useSP) - { - ins = new SqlCommand("insert into #blobs (id,blob) values (1,@blob)", conn); - } - else + conn.Open(); + (new SqlCommand("create table #blobs (id INT, blob VARBINARY(MAX))", conn)).ExecuteNonQuery(); + try { - new SqlCommand("create procedure #myProc (@blob varbinary(MAX)) as begin insert into #blobs values (1, @blob) end", conn).ExecuteNonQuery(); - ins = new SqlCommand("#myProc", conn) + SqlCommand ins; + if (!s_useSP) { - CommandType = CommandType.StoredProcedure - }; - } - if (addWithValue) - { - ins.Parameters.AddWithValue("@blob", stream); - } - else - { - ins.Parameters.Add("@blob", oldTypes ? SqlDbType.Image : SqlDbType.VarBinary, paramLen); - ins.Parameters["@blob"].Direction = ParameterDirection.Input; - ins.Parameters["@blob"].Value = stream; - } - bool exc = false; - if (sync) - { - try + ins = new SqlCommand("insert into #blobs (id,blob) values (1,@blob)", conn); + } + else { - ins.ExecuteNonQuery(); + new SqlCommand("create procedure #myProc (@blob varbinary(MAX)) as begin insert into #blobs values (1, @blob) end", conn).ExecuteNonQuery(); + ins = new SqlCommand("#myProc", conn); + ins.CommandType = CommandType.StoredProcedure; } - catch (CustomStreamException) + if (addWithValue) { - exc = true; + ins.Parameters.AddWithValue("@blob", stream); } - } - else - { - try + else { - ins.ExecuteNonQueryAsync().Wait(); + ins.Parameters.Add("@blob", oldTypes ? SqlDbType.Image : SqlDbType.VarBinary, paramLen); + ins.Parameters["@blob"].Direction = ParameterDirection.Input; + ins.Parameters["@blob"].Value = stream; } - catch (AggregateException ae) + bool exc = false; + if (sync) { - if (ae.InnerException is CustomStreamException) + try + { + ins.ExecuteNonQuery(); + } + catch (CustomStreamException) { exc = true; } - else + } + else + { + try { - throw; + ins.ExecuteNonQueryAsync().Wait(); + } + catch (AggregateException ae) + { + if (ae.InnerException is CustomStreamException) + { + exc = true; + } + else + { + throw; + } } } - } - Debug.Assert(exc == expectException, "Exception!=Expectation"); + Debug.Assert(exc == expectException, "Exception!=Expectation"); - byte[] back = (new SqlCommand("select blob from #blobs where id=1", conn)).ExecuteScalar() as byte[]; - if (!expectException) - { - AssertEqual(back, val, paramLen); + byte[] back = (new SqlCommand("select blob from #blobs where id=1", conn)).ExecuteScalar() as byte[]; + if (!expectException) + { + AssertEqual(back, val, paramLen); + } } - } - finally - { - (new SqlCommand("drop table #blobs", conn)).ExecuteNonQuery(); - if (s_useSP) + finally { - (new SqlCommand("drop procedure #myProc", conn)).ExecuteNonQuery(); + (new SqlCommand("drop table #blobs", conn)).ExecuteNonQuery(); + if (s_useSP) + { + (new SqlCommand("drop procedure #myProc", conn)).ExecuteNonQuery(); + } } } } - private static string s_xmlstr = null; + private static string _xmlstr = null; private static string XmlStr { get { - if (s_xmlstr == null) + if (_xmlstr == null) { int N = 10000; - XmlDocument doc = new(); + XmlDocument doc = new XmlDocument(); XmlNode root = doc.AppendChild(doc.CreateElement("root")); for (int i = 0; i < N; i++) root.AppendChild(doc.CreateElement("e" + i.ToString())); - s_xmlstr = doc.OuterXml; + _xmlstr = doc.OuterXml; } - return s_xmlstr; + return _xmlstr; } } @@ -265,7 +261,7 @@ private static void TestXml2Text(bool sync, bool oldTypes, int paramLen, bool nv private static void TestTextReader(int dataLen, bool sync, bool oldTypes, int paramLen, bool nvarchar, bool addWithValue = false) { - StringBuilder sb = new(); + StringBuilder sb = new StringBuilder(); for (int i = 0; i < dataLen; i++) sb.Append((char)('A' + s_rand.Next(20))); string s = sb.ToString(); @@ -275,7 +271,7 @@ private static void TestTextReader(int dataLen, bool sync, bool oldTypes, int pa private static void TestCustomTextReader(int dataLen, bool sync, bool oldTypes, int paramLen, bool nvarchar, bool error, bool addWithValue = false) { - StringBuilder sb = new(); + StringBuilder sb = new StringBuilder(); for (int i = 0; i < dataLen; i++) sb.Append((char)('A' + s_rand.Next(20))); string s = sb.ToString(); @@ -288,92 +284,88 @@ private static void TestCustomTextReader(int dataLen, bool sync, bool oldTypes, private static void TestTextWrite(string s, object reader, bool sync, bool oldTypes, int paramLen, bool nvarchar, bool expectException, bool addWithValue) { - using SqlConnection conn = new(s_connStr); - conn.Open(); - SqlCommand command = new() - { - Connection = conn, - CommandText = $"create table #blobs (id INT, blob {(nvarchar ? "NVARCHAR" : "VARCHAR")}(MAX))" - }; - _ = command.ExecuteNonQuery(); - try + using (SqlConnection conn = new SqlConnection(s_connStr)) { - SqlCommand ins; - if (!s_useSP) - { - ins = new SqlCommand("insert into #blobs (id,blob) values (1,@blob)", conn); - } - else - { - new SqlCommand( - string.Format("create procedure #myProc (@blob {0}(MAX)) as begin insert into #blobs values (1, @blob) end", nvarchar ? "NVARCHAR" : "VARCHAR"), - conn).ExecuteNonQuery(); - ins = new SqlCommand("#myProc", conn) - { - CommandType = CommandType.StoredProcedure - }; - } - if (addWithValue) - { - ins.Parameters.AddWithValue("@blob", reader); - } - else - { - ins.Parameters.Add("@blob", nvarchar ? - (oldTypes ? SqlDbType.NText : SqlDbType.NVarChar) : - (oldTypes ? SqlDbType.Text : SqlDbType.VarChar), paramLen); - ins.Parameters["@blob"].Direction = ParameterDirection.Input; - ins.Parameters["@blob"].Value = reader; - } + conn.Open(); - bool exc = false; - if (sync) + (new SqlCommand(string.Format("create table #blobs (id INT, blob {0}(MAX))", nvarchar ? "NVARCHAR" : "VARCHAR"), conn)).ExecuteNonQuery(); + try { - try + SqlCommand ins; + if (!s_useSP) { - ins.ExecuteNonQuery(); + ins = new SqlCommand("insert into #blobs (id,blob) values (1,@blob)", conn); } - catch (CustomStreamException) + else { - exc = true; + new SqlCommand( + string.Format("create procedure #myProc (@blob {0}(MAX)) as begin insert into #blobs values (1, @blob) end", nvarchar ? "NVARCHAR" : "VARCHAR"), + conn).ExecuteNonQuery(); + ins = new SqlCommand("#myProc", conn); + ins.CommandType = CommandType.StoredProcedure; } - } - else - { - try + if (addWithValue) { - ins.ExecuteNonQueryAsync().Wait(); + ins.Parameters.AddWithValue("@blob", reader); } - catch (AggregateException ae) + else { - if (ae.InnerException is CustomStreamException) + ins.Parameters.Add("@blob", nvarchar ? + (oldTypes ? SqlDbType.NText : SqlDbType.NVarChar) : + (oldTypes ? SqlDbType.Text : SqlDbType.VarChar), paramLen); + ins.Parameters["@blob"].Direction = ParameterDirection.Input; + ins.Parameters["@blob"].Value = reader; + } + + bool exc = false; + if (sync) + { + try + { + ins.ExecuteNonQuery(); + } + catch (CustomStreamException) { exc = true; } - else + } + else + { + try { - throw; + ins.ExecuteNonQueryAsync().Wait(); + } + catch (AggregateException ae) + { + if (ae.InnerException is CustomStreamException) + { + exc = true; + } + else + { + throw; + } } } - } - Debug.Assert(exc == expectException, "Exception!=Expectation"); + Debug.Assert(exc == expectException, "Exception!=Expectation"); - string back = (new SqlCommand("select blob from #blobs where id=1", conn)).ExecuteScalar() as string; - if (paramLen > 0) - { - s = s.Substring(0, Math.Min(paramLen, s.Length)); - } - if (!expectException) - { - Debug.Assert(back == s, "Strings are not equal"); + string back = (new SqlCommand("select blob from #blobs where id=1", conn)).ExecuteScalar() as string; + if (paramLen > 0) + { + s = s.Substring(0, Math.Min(paramLen, s.Length)); + } + if (!expectException) + { + Debug.Assert(back == s, "Strings are not equal"); + } } - } - finally - { - (new SqlCommand("drop table #blobs", conn)).ExecuteNonQuery(); - if (s_useSP) + finally { - (new SqlCommand("drop procedure #myProc", conn)).ExecuteNonQuery(); + (new SqlCommand("drop table #blobs", conn)).ExecuteNonQuery(); + if (s_useSP) + { + (new SqlCommand("drop procedure #myProc", conn)).ExecuteNonQuery(); + } } } } @@ -381,167 +373,160 @@ private static void TestTextWrite(string s, object reader, bool sync, bool oldTy private static void TestXML(bool sync, bool lengthLimited, bool addWithValue = false) { - using SqlConnection conn = new(s_connStr); - conn.Open(); - SqlCommand command = new() - { - Connection = conn, - CommandText = "create table #blobs (id INT, blob XML)" - }; - _ = command.ExecuteNonQuery(); - try + using (SqlConnection conn = new SqlConnection(s_connStr)) { - SqlCommand ins; - if (!s_useSP) - { - ins = new SqlCommand("insert into #blobs (id,blob) values (1,@blob)", conn); - } - else + conn.Open(); + + (new SqlCommand("create table #blobs (id INT, blob XML)", conn)).ExecuteNonQuery(); + try { - new SqlCommand("create procedure #myProc (@blob XML) as begin insert into #blobs values (1, @blob) end", conn).ExecuteNonQuery(); - ins = new SqlCommand("#myProc", conn) + SqlCommand ins; + if (!s_useSP) { - CommandType = CommandType.StoredProcedure - }; - } + ins = new SqlCommand("insert into #blobs (id,blob) values (1,@blob)", conn); + } + else + { + new SqlCommand("create procedure #myProc (@blob XML) as begin insert into #blobs values (1, @blob) end", conn).ExecuteNonQuery(); + ins = new SqlCommand("#myProc", conn); + ins.CommandType = CommandType.StoredProcedure; + } - StringBuilder comment = new(); - if (lengthLimited) - { - comment.Append(""); - } - XmlReader reader = XmlReader.Create(new StringReader(XmlStr + comment.ToString())); + StringBuilder comment = new StringBuilder(); + if (lengthLimited) + { + comment.Append(""); + } + XmlReader reader = XmlReader.Create(new StringReader(XmlStr + comment.ToString())); - if (addWithValue) - { - ins.Parameters.AddWithValue("@blob", reader); - } - else - { - ins.Parameters.Add("@blob", SqlDbType.Xml, lengthLimited ? XmlStr.Length : -1); - ins.Parameters["@blob"].Direction = ParameterDirection.Input; - ins.Parameters["@blob"].Value = reader; - } - if (sync) - { - ins.ExecuteNonQuery(); - } - else - { - ins.ExecuteNonQueryAsync().Wait(); - } - SqlCommand stringCommand = new() - { - Connection = conn, - CommandText = "select blob from #blobs where id=1" - }; - string back = stringCommand.ExecuteScalar() as string; - Debug.Assert(back == XmlStr, "String!=xml"); - if (back != XmlStr) - { - Console.WriteLine("[{0}]", back); - Console.WriteLine("[{0}]", XmlStr); + if (addWithValue) + { + ins.Parameters.AddWithValue("@blob", reader); + } + else + { + ins.Parameters.Add("@blob", SqlDbType.Xml, lengthLimited ? XmlStr.Length : -1); + ins.Parameters["@blob"].Direction = ParameterDirection.Input; + ins.Parameters["@blob"].Value = reader; + } + if (sync) + { + ins.ExecuteNonQuery(); + } + else + { + ins.ExecuteNonQueryAsync().Wait(); + } + string back = (new SqlCommand("select blob from #blobs where id=1", conn)).ExecuteScalar() as string; + Debug.Assert(back == XmlStr, "String!=xml"); + if (back != XmlStr) + { + Console.WriteLine("[{0}]", back); + Console.WriteLine("[{0}]", XmlStr); + } } - } - finally - { - using SqlCommand dropCommand = new() - { - Connection = conn, - CommandText = "drop table #blobs" - }; - dropCommand.ExecuteNonQuery(); - if (s_useSP) + finally { - dropCommand.CommandText = "drop procedure #myProc"; - dropCommand.ExecuteNonQuery(); + (new SqlCommand("drop table #blobs", conn)).ExecuteNonQuery(); + if (s_useSP) + { + (new SqlCommand("drop procedure #myProc", conn)).ExecuteNonQuery(); + } } + Console.WriteLine("TestXml (Sync {0} LimitLength {1} ) is OK", sync, lengthLimited); } - Console.WriteLine("TestXml (Sync {0} LimitLength {1} ) is OK", sync, lengthLimited); } private static void ImmediateCancelBin() { Console.WriteLine("Test immediate cancel for binary stream"); - CancellationTokenSource cts = new(); - using SqlConnection conn = new(s_connStr); - conn.OpenAsync().Wait(); - using SqlCommand cmd = conn.CreateCommand(); - cmd.CommandText = "create table #blobs (Id int, blob varbinary(max))"; - cmd.ExecuteNonQuery(); - Random rand = new(10000); - int dataSize = 10000000; - byte[] data = new byte[dataSize]; - rand.NextBytes(data); - MemoryStream ms = new(data, false); - // Include a delay to allow time for cancellation - cmd.CommandText = "WAITFOR DELAY '00:00:05'; insert into #blobs (Id, blob) values (1, @blob)"; - cmd.Parameters.Add("@blob", SqlDbType.VarBinary, dataSize); - cmd.Parameters["@blob"].Direction = ParameterDirection.Input; - cmd.Parameters["@blob"].Value = ms; - - try - { - Task.WaitAll(cmd.ExecuteNonQueryAsync(cts.Token), Task.Run(() => cts.Cancel())); - Console.WriteLine("FAIL: Expected AggregateException on Task wait for Cancelled Task!"); - } - catch (AggregateException ae) + CancellationTokenSource cts = new CancellationTokenSource(); + using (SqlConnection conn = new SqlConnection(s_connStr)) { - if (ae.InnerException is InvalidOperationException || - (ae.InnerException is SqlException && - ae.InnerException.Message.Contains("Operation cancelled by user."))) - { - Console.WriteLine("PASS: Task is cancelled"); - } - else - { - throw ae.InnerException; + conn.OpenAsync().Wait(); + using (SqlCommand cmd = conn.CreateCommand()) + { + cmd.CommandText = "create table #blobs (Id int, blob varbinary(max))"; + cmd.ExecuteNonQuery(); + Random rand = new Random(10000); + int dataSize = 10000000; + byte[] data = new byte[dataSize]; + rand.NextBytes(data); + MemoryStream ms = new MemoryStream(data, false); + // Include a delay to allow time for cancellation + cmd.CommandText = "WAITFOR DELAY '00:00:05'; insert into #blobs (Id, blob) values (1, @blob)"; + cmd.Parameters.Add("@blob", SqlDbType.VarBinary, dataSize); + cmd.Parameters["@blob"].Direction = ParameterDirection.Input; + cmd.Parameters["@blob"].Value = ms; + + try + { + Task.WaitAll(cmd.ExecuteNonQueryAsync(cts.Token), Task.Run(() => cts.Cancel())); + Console.WriteLine("FAIL: Expected AggregateException on Task wait for Cancelled Task!"); + } + catch (AggregateException ae) + { + if (ae.InnerException is InvalidOperationException || + (ae.InnerException is SqlException && + ae.InnerException.Message.Contains("Operation cancelled by user."))) + { + Console.WriteLine("PASS: Task is cancelled"); + } + else + { + throw ae.InnerException; + } + } + finally + { + ms.Close(); + } } } - finally - { - ms.Close(); - } } private static void ImmediateCancelText() { Console.WriteLine("Test immediate cancel for text stream"); - CancellationTokenSource cts = new(); - using SqlConnection conn = new(s_connStr); - conn.OpenAsync().Wait(); - using SqlCommand cmd = conn.CreateCommand(); - cmd.CommandText = "create table #blobs (Id int, blob varchar(max))"; - cmd.ExecuteNonQuery(); - StringBuilder sb = new(); - for (int i = 0; i < 1000000; i++) - sb.Append(i); - // Include a delay to allow time for cancellation - cmd.CommandText = "WAITFOR DELAY '00:00:05'; insert into #blobs (Id, blob) values (1, @blob)"; - cmd.Parameters.Add("@blob", SqlDbType.VarChar, -1); - cmd.Parameters["@blob"].Direction = ParameterDirection.Input; - cmd.Parameters["@blob"].Value = new StringReader(sb.ToString()); - - try - { - Task.WaitAll(cmd.ExecuteNonQueryAsync(cts.Token), Task.Run(() => cts.Cancel())); - Console.WriteLine("FAIL: Expected AggregateException on Task wait for Cancelled Task!"); - } - catch (AggregateException ae) + CancellationTokenSource cts = new CancellationTokenSource(); + using (SqlConnection conn = new SqlConnection(s_connStr)) { - if (ae.InnerException is InvalidOperationException || - (ae.InnerException is SqlException && - ae.InnerException.Message.Contains("Operation cancelled by user."))) - { - Console.WriteLine("PASS: Task is cancelled"); - } - else - { - throw ae.InnerException; + conn.OpenAsync().Wait(); + using (SqlCommand cmd = conn.CreateCommand()) + { + cmd.CommandText = "create table #blobs (Id int, blob varchar(max))"; + cmd.ExecuteNonQuery(); + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < 1000000; i++) + sb.Append(i); + // Include a delay to allow time for cancellation + cmd.CommandText = "WAITFOR DELAY '00:00:05'; insert into #blobs (Id, blob) values (1, @blob)"; + cmd.Parameters.Add("@blob", SqlDbType.VarChar, -1); + cmd.Parameters["@blob"].Direction = ParameterDirection.Input; + cmd.Parameters["@blob"].Value = new StringReader(sb.ToString()); + + try + { + Task.WaitAll(cmd.ExecuteNonQueryAsync(cts.Token), Task.Run(() => cts.Cancel())); + Console.WriteLine("FAIL: Expected AggregateException on Task wait for Cancelled Task!"); + } + catch (AggregateException ae) + { + if (ae.InnerException is InvalidOperationException || + (ae.InnerException is SqlException && + ae.InnerException.Message.Contains("Operation cancelled by user."))) + { + Console.WriteLine("PASS: Task is cancelled"); + } + else + { + throw ae.InnerException; + } + } } } } @@ -549,34 +534,38 @@ private static void ImmediateCancelText() private static void ImmediateCancelXml() { Console.WriteLine("Test immediate cancel for xml stream"); - CancellationTokenSource cts = new(); - using SqlConnection conn = new(s_connStr); - conn.OpenAsync().Wait(); - using SqlCommand cmd = conn.CreateCommand(); - cmd.CommandText = "create table #blobs (Id int, blob xml)"; - cmd.ExecuteNonQuery(); - // Include a delay to allow time for cancellation - cmd.CommandText = "WAITFOR DELAY '00:00:05'; insert into #blobs (Id, blob) values (1, @blob)"; - cmd.Parameters.Add("@blob", SqlDbType.Xml, -1); - cmd.Parameters["@blob"].Direction = ParameterDirection.Input; - cmd.Parameters["@blob"].Value = XmlReader.Create(new StringReader(XmlStr)); - - try + CancellationTokenSource cts = new CancellationTokenSource(); + using (SqlConnection conn = new SqlConnection(s_connStr)) { - Task.WaitAll(cmd.ExecuteNonQueryAsync(cts.Token), Task.Run(() => cts.Cancel())); - Console.WriteLine("FAIL: Expected AggregateException on Task wait for Cancelled Task!"); - } - catch (AggregateException ae) - { - if (ae.InnerException is InvalidOperationException || - (ae.InnerException is SqlException && - ae.InnerException.Message.Contains("Operation cancelled by user."))) - { - Console.WriteLine("PASS: Task is cancelled"); - } - else + conn.OpenAsync().Wait(); + using (SqlCommand cmd = conn.CreateCommand()) { - throw ae.InnerException; + cmd.CommandText = "create table #blobs (Id int, blob xml)"; + cmd.ExecuteNonQuery(); + // Include a delay to allow time for cancellation + cmd.CommandText = "WAITFOR DELAY '00:00:05'; insert into #blobs (Id, blob) values (1, @blob)"; + cmd.Parameters.Add("@blob", SqlDbType.Xml, -1); + cmd.Parameters["@blob"].Direction = ParameterDirection.Input; + cmd.Parameters["@blob"].Value = XmlReader.Create(new StringReader(XmlStr)); + + try + { + Task.WaitAll(cmd.ExecuteNonQueryAsync(cts.Token), Task.Run(() => cts.Cancel())); + Console.WriteLine("FAIL: Expected AggregateException on Task wait for Cancelled Task!"); + } + catch (AggregateException ae) + { + if (ae.InnerException is InvalidOperationException || + (ae.InnerException is SqlException && + ae.InnerException.Message.Contains("Operation cancelled by user."))) + { + Console.WriteLine("PASS: Task is cancelled"); + } + else + { + throw ae.InnerException; + } + } } } } @@ -584,77 +573,83 @@ private static void ImmediateCancelXml() private static void PrepareCommand() { Console.Write("Test command preparation "); - using (SqlConnection conn = new(s_connStr)) + using (SqlConnection conn = new SqlConnection(s_connStr)) { conn.Open(); - using SqlCommand cmd = conn.CreateCommand(); - cmd.CommandText = "create table #blobs (Id int, blob varbinary(max))"; - cmd.ExecuteNonQuery(); - Random rand = new(10000); - int dataSize = 100000; - byte[] data = new byte[dataSize]; - rand.NextBytes(data); - MemoryStream ms = new(data, false); - - cmd.CommandText = "insert into #blobs (Id, blob) values (1, @blob)"; - - cmd.Parameters.Add("@blob", SqlDbType.VarBinary, dataSize); - cmd.Parameters["@blob"].Direction = ParameterDirection.Input; - cmd.Parameters["@blob"].Value = ms; - cmd.Prepare(); - cmd.ExecuteNonQuery(); - conn.Close(); - ms.Close(); + using (SqlCommand cmd = conn.CreateCommand()) + { + cmd.CommandText = "create table #blobs (Id int, blob varbinary(max))"; + cmd.ExecuteNonQuery(); + Random rand = new Random(10000); + int dataSize = 100000; + byte[] data = new byte[dataSize]; + rand.NextBytes(data); + MemoryStream ms = new MemoryStream(data, false); + + cmd.CommandText = "insert into #blobs (Id, blob) values (1, @blob)"; + + cmd.Parameters.Add("@blob", SqlDbType.VarBinary, dataSize); + cmd.Parameters["@blob"].Direction = ParameterDirection.Input; + cmd.Parameters["@blob"].Value = ms; + cmd.Prepare(); + cmd.ExecuteNonQuery(); + conn.Close(); + ms.Close(); + } } Console.WriteLine("PASS"); } private static void CommandReuse() { - foreach (Func func in new Func[] { + foreach (var func in new Func[] { (cmd,token) => cmd.ExecuteNonQueryAsync(token), (cmd,token) => cmd.ExecuteReaderAsync(token), (cmd,token) => cmd.ExecuteXmlReaderAsync(token) }) { - CancellationTokenSource cts = new(); - using SqlConnection conn = new(s_connStr); - conn.OpenAsync().Wait(); - Console.WriteLine("Test reuse of command after cancel"); - using SqlCommand cmd = conn.CreateCommand(); - cmd.CommandText = "create table #blobs (Id int, blob varbinary(max))"; - cmd.ExecuteNonQuery(); - Random rand = new(10000); - int dataSize = 100000; - byte[] binarydata = new byte[dataSize]; - rand.NextBytes(binarydata); - MemoryStream ms = new(binarydata, false); - // Include a delay to allow time for cancellation - cmd.CommandText = "WAITFOR DELAY '00:00:05'; insert into #blobs (Id, blob) values (1, @blob)"; - - cmd.Parameters.Add("@blob", SqlDbType.VarBinary, dataSize); - cmd.Parameters["@blob"].Direction = ParameterDirection.Input; - cmd.Parameters["@blob"].Value = ms; - - try + CancellationTokenSource cts = new CancellationTokenSource(); + using (SqlConnection conn = new SqlConnection(s_connStr)) { - Task.WaitAll(func(cmd, cts.Token), Task.Run(() => cts.Cancel())); - Console.WriteLine("FAIL: Expected AggregateException on Task wait for Cancelled Task!"); - } - catch (AggregateException ae) - { - if (!ae.InnerException.Message.Contains("Operation cancelled by user.")) + conn.OpenAsync().Wait(); + Console.WriteLine("Test reuse of command after cancel"); + using (SqlCommand cmd = conn.CreateCommand()) { - Console.WriteLine("FAIL: Unexpected exception message: " + ae.InnerException.Message); + cmd.CommandText = "create table #blobs (Id int, blob varbinary(max))"; + cmd.ExecuteNonQuery(); + Random rand = new Random(10000); + int dataSize = 100000; + byte[] binarydata = new byte[dataSize]; + rand.NextBytes(binarydata); + MemoryStream ms = new MemoryStream(binarydata, false); + // Include a delay to allow time for cancellation + cmd.CommandText = "WAITFOR DELAY '00:00:05'; insert into #blobs (Id, blob) values (1, @blob)"; + + cmd.Parameters.Add("@blob", SqlDbType.VarBinary, dataSize); + cmd.Parameters["@blob"].Direction = ParameterDirection.Input; + cmd.Parameters["@blob"].Value = ms; + + try + { + Task.WaitAll(func(cmd, cts.Token), Task.Run(() => cts.Cancel())); + Console.WriteLine("FAIL: Expected AggregateException on Task wait for Cancelled Task!"); + } + catch (AggregateException ae) + { + if (!ae.InnerException.Message.Contains("Operation cancelled by user.")) + { + Console.WriteLine("FAIL: Unexpected exception message: " + ae.InnerException.Message); + } + } + finally + { + ms.Close(); + } + cmd.Parameters.Clear(); + cmd.CommandText = "select 'PASS'"; + Console.WriteLine(cmd.ExecuteScalar()); } } - finally - { - ms.Close(); - } - cmd.Parameters.Clear(); - cmd.CommandText = "select 'PASS'"; - Console.WriteLine(cmd.ExecuteScalar()); } } @@ -670,7 +665,7 @@ internal static void Run(string connection) bool oldTypes = false; do { - using (AsyncDebugScope debugScope = new()) + using (AsyncDebugScope debugScope = new AsyncDebugScope()) { for (int run = 0; run < 2; run++) { diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ParameterTest/TvpTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ParameterTest/TvpTest.cs index 4c7f198793..084fe11789 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ParameterTest/TvpTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ParameterTest/TvpTest.cs @@ -24,7 +24,7 @@ namespace Microsoft.Data.SqlClient.ManualTesting.Tests public class TvpTest { private const string TvpName = "@tvp"; - private static readonly IList s_boundariesTestKeys = new List( + private static readonly IList BoundariesTestKeys = new List( new SteAttributeKey[] { SteAttributeKey.SqlDbType, SteAttributeKey.MultiValued, @@ -40,7 +40,7 @@ public class TvpTest }).AsReadOnly(); // data value and server consts - private readonly string _connStr; + private string _connStr; // Synapse: The statement failed. Column 'blob' has a data type that cannot participate in a columnstore index. [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup), nameof(DataTestUtility.IsNotAzureSynapse))] @@ -66,7 +66,7 @@ public void TestPacketNumberWraparound() var enumerator = new WraparoundRowEnumerator(1000000); - Stopwatch stopwatch = new(); + Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); int returned = Task.WaitAny( Task.Factory.StartNew( @@ -214,7 +214,7 @@ private bool RunTestCoreAndCompareWithBaseline() Console.Out.Dispose(); // Recover the standard output stream - StreamWriter standardOutput = new(Console.OpenStandardOutput()); + StreamWriter standardOutput = new StreamWriter(Console.OpenStandardOutput()); standardOutput.AutoFlush = true; Console.SetOut(standardOutput); @@ -288,7 +288,10 @@ private sealed class CarriageReturnLineFeedReplacer : TextWriter internal CarriageReturnLineFeedReplacer(TextWriter output) { - _output = output ?? throw new ArgumentNullException(nameof(output)); + if (output == null) + throw new ArgumentNullException(nameof(output)); + + _output = output; } public int LineFeedCount @@ -344,8 +347,8 @@ public override void Write(char value) #region Main test methods private void ColumnBoundariesTest() { - _ = SteStructuredTypeBoundaries.AllColumnTypesExceptUdts.GetEnumerator( - s_boundariesTestKeys); + IEnumerator boundsMD = SteStructuredTypeBoundaries.AllColumnTypesExceptUdts.GetEnumerator( + BoundariesTestKeys); TestTVPPermutations(SteStructuredTypeBoundaries.AllColumnTypesExceptUdts, false); //Console.WriteLine("+++++++++++ UDT TVP tests ++++++++++++++"); //TestTVPPermutations(SteStructuredTypeBoundaries.UdtsOnly, true); @@ -353,12 +356,12 @@ private void ColumnBoundariesTest() private void TestTVPPermutations(SteStructuredTypeBoundaries bounds, bool runOnlyDataRecordTest) { - IEnumerator boundsMD = bounds.GetEnumerator(s_boundariesTestKeys); + IEnumerator boundsMD = bounds.GetEnumerator(BoundariesTestKeys); object[][] baseValues = SteStructuredTypeBoundaries.GetSeparateValues(boundsMD); IList dtList = GenerateDataTables(baseValues); - TransactionOptions opts = new(); + TransactionOptions opts = new TransactionOptions(); opts.IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted; // for each unique pattern of metadata @@ -371,10 +374,8 @@ private void TestTVPPermutations(SteStructuredTypeBoundaries bounds, bool runOnl // Set up base command SqlCommand cmd; SqlParameter param; - cmd = new SqlCommand(GetProcName(tvpPerm)) - { - CommandType = CommandType.StoredProcedure - }; + cmd = new SqlCommand(GetProcName(tvpPerm)); + cmd.CommandType = CommandType.StoredProcedure; param = cmd.Parameters.Add(TvpName, SqlDbType.Structured); param.TypeName = GetTypeName(tvpPerm); @@ -437,263 +438,268 @@ private void TestTVPPermutations(SteStructuredTypeBoundaries bounds, bool runOnl private void QueryHintsTest() { - using SqlConnection conn = new(_connStr); - conn.Open(); - - Guid randomizer = Guid.NewGuid(); - string typeName = string.Format("dbo.[QHint_{0}]", randomizer); - string procName = string.Format("dbo.[QHint_Proc_{0}]", randomizer); - string createTypeSql = string.Format( - "CREATE TYPE {0} AS TABLE(" - + " c1 Int DEFAULT -1," - + " c2 NVarChar(40) DEFAULT N'DEFUALT'," - + " c3 DateTime DEFAULT '1/1/2006'," - + " c4 Int DEFAULT -1)", - typeName); - string createProcSql = string.Format( - "CREATE PROC {0}(@tvp {1} READONLY) AS SELECT TOP(2) * FROM @tvp ORDER BY c1", procName, typeName); - string dropSql = string.Format("DROP PROC {0}; DROP TYPE {1}", procName, typeName); - - try + using (SqlConnection conn = new SqlConnection(_connStr)) { - SqlCommand cmd = new(createTypeSql, conn); - cmd.ExecuteNonQuery(); + conn.Open(); - cmd.CommandText = createProcSql; - cmd.ExecuteNonQuery(); + Guid randomizer = Guid.NewGuid(); + string typeName = string.Format("dbo.[QHint_{0}]", randomizer); + string procName = string.Format("dbo.[QHint_Proc_{0}]", randomizer); + string createTypeSql = string.Format( + "CREATE TYPE {0} AS TABLE(" + + " c1 Int DEFAULT -1," + + " c2 NVarChar(40) DEFAULT N'DEFUALT'," + + " c3 DateTime DEFAULT '1/1/2006'," + + " c4 Int DEFAULT -1)", + typeName); + string createProcSql = string.Format( + "CREATE PROC {0}(@tvp {1} READONLY) AS SELECT TOP(2) * FROM @tvp ORDER BY c1", procName, typeName); + string dropSql = string.Format("DROP PROC {0}; DROP TYPE {1}", procName, typeName); - cmd.CommandText = procName; - cmd.CommandType = CommandType.StoredProcedure; - SqlParameter param = cmd.Parameters.Add("@tvp", SqlDbType.Structured); + try + { + SqlCommand cmd = new SqlCommand(createTypeSql, conn); + cmd.ExecuteNonQuery(); + + cmd.CommandText = createProcSql; + cmd.ExecuteNonQuery(); - SqlMetaData[] columnMetadata; - List rows = new(); - SqlDataRecord record; + cmd.CommandText = procName; + cmd.CommandType = CommandType.StoredProcedure; + SqlParameter param = cmd.Parameters.Add("@tvp", SqlDbType.Structured); - Console.WriteLine("------- Sort order + uniqueness #1: simple -------"); - columnMetadata = new SqlMetaData[] { + SqlMetaData[] columnMetadata; + List rows = new List(); + SqlDataRecord record; + + Console.WriteLine("------- Sort order + uniqueness #1: simple -------"); + columnMetadata = new SqlMetaData[] { new SqlMetaData("", SqlDbType.Int, false, true, SortOrder.Ascending, 0), new SqlMetaData("", SqlDbType.NVarChar, 40, false, true, SortOrder.Descending, 1), new SqlMetaData("", SqlDbType.DateTime, false, true, SortOrder.Ascending, 2), new SqlMetaData("", SqlDbType.Int, false, true, SortOrder.Descending, 3), }; - record = new SqlDataRecord(columnMetadata); - record.SetValues(0, "Z-value", DateTime.Parse("03/01/2000"), 5); - rows.Add(record); + record = new SqlDataRecord(columnMetadata); + record.SetValues(0, "Z-value", DateTime.Parse("03/01/2000"), 5); + rows.Add(record); - record = new SqlDataRecord(columnMetadata); - record.SetValues(1, "Y-value", DateTime.Parse("02/01/2000"), 6); - rows.Add(record); + record = new SqlDataRecord(columnMetadata); + record.SetValues(1, "Y-value", DateTime.Parse("02/01/2000"), 6); + rows.Add(record); - record = new SqlDataRecord(columnMetadata); - record.SetValues(1, "X-value", DateTime.Parse("01/01/2000"), 7); - rows.Add(record); + record = new SqlDataRecord(columnMetadata); + record.SetValues(1, "X-value", DateTime.Parse("01/01/2000"), 7); + rows.Add(record); - record = new SqlDataRecord(columnMetadata); - record.SetValues(1, "X-value", DateTime.Parse("04/01/2000"), 8); - rows.Add(record); + record = new SqlDataRecord(columnMetadata); + record.SetValues(1, "X-value", DateTime.Parse("04/01/2000"), 8); + rows.Add(record); - record = new SqlDataRecord(columnMetadata); - record.SetValues(1, "X-value", DateTime.Parse("04/01/2000"), 4); - rows.Add(record); + record = new SqlDataRecord(columnMetadata); + record.SetValues(1, "X-value", DateTime.Parse("04/01/2000"), 4); + rows.Add(record); - param.Value = rows; - using (SqlDataReader rdr = cmd.ExecuteReader()) - { - WriteReader(rdr); - } - rows.Clear(); + param.Value = rows; + using (SqlDataReader rdr = cmd.ExecuteReader()) + { + WriteReader(rdr); + } + rows.Clear(); - Console.WriteLine("------- Sort order + uniqueness #2: mixed order -------"); - columnMetadata = new SqlMetaData[] { + Console.WriteLine("------- Sort order + uniqueness #2: mixed order -------"); + columnMetadata = new SqlMetaData[] { new SqlMetaData("", SqlDbType.Int, false, true, SortOrder.Descending, 3), new SqlMetaData("", SqlDbType.NVarChar, 40, false, true, SortOrder.Descending, 0), new SqlMetaData("", SqlDbType.DateTime, false, true, SortOrder.Ascending, 2), new SqlMetaData("", SqlDbType.Int, false, true, SortOrder.Ascending, 1), }; - record = new SqlDataRecord(columnMetadata); - record.SetValues(6, "Z-value", DateTime.Parse("01/01/2000"), 1); - rows.Add(record); + record = new SqlDataRecord(columnMetadata); + record.SetValues(6, "Z-value", DateTime.Parse("01/01/2000"), 1); + rows.Add(record); - record = new SqlDataRecord(columnMetadata); - record.SetValues(6, "Z-value", DateTime.Parse("01/01/2000"), 2); - rows.Add(record); + record = new SqlDataRecord(columnMetadata); + record.SetValues(6, "Z-value", DateTime.Parse("01/01/2000"), 2); + rows.Add(record); - record = new SqlDataRecord(columnMetadata); - record.SetValues(6, "Y-value", DateTime.Parse("01/01/2000"), 3); - rows.Add(record); + record = new SqlDataRecord(columnMetadata); + record.SetValues(6, "Y-value", DateTime.Parse("01/01/2000"), 3); + rows.Add(record); - record = new SqlDataRecord(columnMetadata); - record.SetValues(6, "Y-value", DateTime.Parse("02/01/2000"), 3); - rows.Add(record); + record = new SqlDataRecord(columnMetadata); + record.SetValues(6, "Y-value", DateTime.Parse("02/01/2000"), 3); + rows.Add(record); - record = new SqlDataRecord(columnMetadata); - record.SetValues(5, "X-value", DateTime.Parse("03/01/2000"), 3); - rows.Add(record); + record = new SqlDataRecord(columnMetadata); + record.SetValues(5, "X-value", DateTime.Parse("03/01/2000"), 3); + rows.Add(record); - record = new SqlDataRecord(columnMetadata); - record.SetValues(4, "X-value", DateTime.Parse("01/01/2000"), 3); - rows.Add(record); + record = new SqlDataRecord(columnMetadata); + record.SetValues(4, "X-value", DateTime.Parse("01/01/2000"), 3); + rows.Add(record); - param.Value = rows; - using (SqlDataReader rdr = cmd.ExecuteReader()) - { - WriteReader(rdr); - } - rows.Clear(); + param.Value = rows; + using (SqlDataReader rdr = cmd.ExecuteReader()) + { + WriteReader(rdr); + } + rows.Clear(); - Console.WriteLine("------- default column #1: outer subset -------"); - columnMetadata = new SqlMetaData[] { + Console.WriteLine("------- default column #1: outer subset -------"); + columnMetadata = new SqlMetaData[] { new SqlMetaData("", SqlDbType.Int, true, false, SortOrder.Unspecified, -1), new SqlMetaData("", SqlDbType.NVarChar, 40, false, false, SortOrder.Unspecified, -1), new SqlMetaData("", SqlDbType.DateTime, false, false, SortOrder.Unspecified, -1), new SqlMetaData("", SqlDbType.Int, true, false, SortOrder.Unspecified, -1), }; - record = new SqlDataRecord(columnMetadata); - record.SetValues(6, "Z-value", DateTime.Parse("01/01/2000"), 1); - rows.Add(record); + record = new SqlDataRecord(columnMetadata); + record.SetValues(6, "Z-value", DateTime.Parse("01/01/2000"), 1); + rows.Add(record); - record = new SqlDataRecord(columnMetadata); - record.SetValues(6, "Z-value", DateTime.Parse("01/01/2000"), 2); - rows.Add(record); + record = new SqlDataRecord(columnMetadata); + record.SetValues(6, "Z-value", DateTime.Parse("01/01/2000"), 2); + rows.Add(record); - record = new SqlDataRecord(columnMetadata); - record.SetValues(6, "Y-value", DateTime.Parse("01/01/2000"), 3); - rows.Add(record); + record = new SqlDataRecord(columnMetadata); + record.SetValues(6, "Y-value", DateTime.Parse("01/01/2000"), 3); + rows.Add(record); - record = new SqlDataRecord(columnMetadata); - record.SetValues(6, "Y-value", DateTime.Parse("02/01/2000"), 3); - rows.Add(record); + record = new SqlDataRecord(columnMetadata); + record.SetValues(6, "Y-value", DateTime.Parse("02/01/2000"), 3); + rows.Add(record); - record = new SqlDataRecord(columnMetadata); - record.SetValues(5, "X-value", DateTime.Parse("03/01/2000"), 3); - rows.Add(record); + record = new SqlDataRecord(columnMetadata); + record.SetValues(5, "X-value", DateTime.Parse("03/01/2000"), 3); + rows.Add(record); - record = new SqlDataRecord(columnMetadata); - record.SetValues(4, "X-value", DateTime.Parse("01/01/2000"), 3); - rows.Add(record); + record = new SqlDataRecord(columnMetadata); + record.SetValues(4, "X-value", DateTime.Parse("01/01/2000"), 3); + rows.Add(record); - param.Value = rows; - using (SqlDataReader rdr = cmd.ExecuteReader()) - { - WriteReader(rdr); - } - rows.Clear(); + param.Value = rows; + using (SqlDataReader rdr = cmd.ExecuteReader()) + { + WriteReader(rdr); + } + rows.Clear(); - Console.WriteLine("------- default column #1: middle subset -------"); - columnMetadata = new SqlMetaData[] { + Console.WriteLine("------- default column #1: middle subset -------"); + columnMetadata = new SqlMetaData[] { new SqlMetaData("", SqlDbType.Int, false, false, SortOrder.Unspecified, -1), new SqlMetaData("", SqlDbType.NVarChar, 40, true, false, SortOrder.Unspecified, -1), new SqlMetaData("", SqlDbType.DateTime, true, false, SortOrder.Unspecified, -1), new SqlMetaData("", SqlDbType.Int, false, false, SortOrder.Unspecified, -1), }; - record = new SqlDataRecord(columnMetadata); - record.SetValues(6, "Z-value", DateTime.Parse("01/01/2000"), 1); - rows.Add(record); + record = new SqlDataRecord(columnMetadata); + record.SetValues(6, "Z-value", DateTime.Parse("01/01/2000"), 1); + rows.Add(record); - record = new SqlDataRecord(columnMetadata); - record.SetValues(6, "Z-value", DateTime.Parse("01/01/2000"), 2); - rows.Add(record); + record = new SqlDataRecord(columnMetadata); + record.SetValues(6, "Z-value", DateTime.Parse("01/01/2000"), 2); + rows.Add(record); - record = new SqlDataRecord(columnMetadata); - record.SetValues(6, "Y-value", DateTime.Parse("01/01/2000"), 3); - rows.Add(record); + record = new SqlDataRecord(columnMetadata); + record.SetValues(6, "Y-value", DateTime.Parse("01/01/2000"), 3); + rows.Add(record); - record = new SqlDataRecord(columnMetadata); - record.SetValues(6, "Y-value", DateTime.Parse("02/01/2000"), 3); - rows.Add(record); + record = new SqlDataRecord(columnMetadata); + record.SetValues(6, "Y-value", DateTime.Parse("02/01/2000"), 3); + rows.Add(record); - record = new SqlDataRecord(columnMetadata); - record.SetValues(5, "X-value", DateTime.Parse("03/01/2000"), 3); - rows.Add(record); + record = new SqlDataRecord(columnMetadata); + record.SetValues(5, "X-value", DateTime.Parse("03/01/2000"), 3); + rows.Add(record); - record = new SqlDataRecord(columnMetadata); - record.SetValues(4, "X-value", DateTime.Parse("01/01/2000"), 3); - rows.Add(record); + record = new SqlDataRecord(columnMetadata); + record.SetValues(4, "X-value", DateTime.Parse("01/01/2000"), 3); + rows.Add(record); - param.Value = rows; - using (SqlDataReader rdr = cmd.ExecuteReader()) - { - WriteReader(rdr); - } - rows.Clear(); + param.Value = rows; + using (SqlDataReader rdr = cmd.ExecuteReader()) + { + WriteReader(rdr); + } + rows.Clear(); - Console.WriteLine("------- default column #1: all -------"); - columnMetadata = new SqlMetaData[] { + Console.WriteLine("------- default column #1: all -------"); + columnMetadata = new SqlMetaData[] { new SqlMetaData("", SqlDbType.Int, true, false, SortOrder.Unspecified, -1), new SqlMetaData("", SqlDbType.NVarChar, 40, true, false, SortOrder.Unspecified, -1), new SqlMetaData("", SqlDbType.DateTime, true, false, SortOrder.Unspecified, -1), new SqlMetaData("", SqlDbType.Int, true, false, SortOrder.Unspecified, -1), }; - record = new SqlDataRecord(columnMetadata); - record.SetValues(6, "Z-value", DateTime.Parse("01/01/2000"), 1); - rows.Add(record); + record = new SqlDataRecord(columnMetadata); + record.SetValues(6, "Z-value", DateTime.Parse("01/01/2000"), 1); + rows.Add(record); + + record = new SqlDataRecord(columnMetadata); + record.SetValues(6, "Z-value", DateTime.Parse("01/01/2000"), 2); + rows.Add(record); - record = new SqlDataRecord(columnMetadata); - record.SetValues(6, "Z-value", DateTime.Parse("01/01/2000"), 2); - rows.Add(record); + record = new SqlDataRecord(columnMetadata); + record.SetValues(6, "Y-value", DateTime.Parse("01/01/2000"), 3); + rows.Add(record); - record = new SqlDataRecord(columnMetadata); - record.SetValues(6, "Y-value", DateTime.Parse("01/01/2000"), 3); - rows.Add(record); + record = new SqlDataRecord(columnMetadata); + record.SetValues(6, "Y-value", DateTime.Parse("02/01/2000"), 3); + rows.Add(record); - record = new SqlDataRecord(columnMetadata); - record.SetValues(6, "Y-value", DateTime.Parse("02/01/2000"), 3); - rows.Add(record); + record = new SqlDataRecord(columnMetadata); + record.SetValues(5, "X-value", DateTime.Parse("03/01/2000"), 3); + rows.Add(record); - record = new SqlDataRecord(columnMetadata); - record.SetValues(5, "X-value", DateTime.Parse("03/01/2000"), 3); - rows.Add(record); + record = new SqlDataRecord(columnMetadata); + record.SetValues(4, "X-value", DateTime.Parse("01/01/2000"), 3); + rows.Add(record); - record = new SqlDataRecord(columnMetadata); - record.SetValues(4, "X-value", DateTime.Parse("01/01/2000"), 3); - rows.Add(record); + param.Value = rows; + using (SqlDataReader rdr = cmd.ExecuteReader()) + { + WriteReader(rdr); + } + rows.Clear(); - param.Value = rows; - using (SqlDataReader rdr = cmd.ExecuteReader()) + } + catch (Exception e) { - WriteReader(rdr); + Console.WriteLine(e.Message); + } + finally + { + SqlCommand cmd = new SqlCommand(dropSql, conn); + cmd.ExecuteNonQuery(); } - rows.Clear(); } - catch (Exception e) - { - Console.WriteLine(e.Message); - } - finally - { - SqlCommand cmd = new(dropSql, conn); - cmd.ExecuteNonQuery(); - } } private static async Task RunPacketNumberWraparound(WraparoundRowEnumerator enumerator) { - using var connection = new SqlConnection(DataTestUtility.TCPConnectionString); - using var cmd = new SqlCommand("unimportant") + using (var connection = new SqlConnection(DataTestUtility.TCPConnectionString)) + using (var cmd = new SqlCommand("unimportant") { - CommandType = CommandType.StoredProcedure, + CommandType = System.Data.CommandType.StoredProcedure, Connection = connection, - }; - await cmd.Connection.OpenAsync(); - cmd.Parameters.Add(new SqlParameter("@rows", SqlDbType.Structured) + }) { - TypeName = "unimportant", - Value = enumerator, - }); - try - { - await cmd.ExecuteNonQueryAsync(); - } - catch (Exception) - { - // ignore the errors caused by the sproc and table type not existing + await cmd.Connection.OpenAsync(); + cmd.Parameters.Add(new SqlParameter("@rows", SqlDbType.Structured) + { + TypeName = "unimportant", + Value = enumerator, + }); + try + { + await cmd.ExecuteNonQueryAsync(); + } + catch (Exception) + { + // ignore the errors caused by the sproc and table type not existing + } } } @@ -703,6 +709,7 @@ private static async Task RunPacketNumberWraparound(WraparoundRowEnumerator enum private bool AllowableDifference(string source, object result, StePermutation metadata) { + object value; bool returnValue = false; // turn result into a string @@ -726,7 +733,7 @@ private bool AllowableDifference(string source, object result, StePermutation me { returnValue = true; } - else if (metadata.TryGetValue(SteAttributeKey.MaxLength, out object value) && value != SteTypeBoundaries.s_doNotUseMarker) + else if (metadata.TryGetValue(SteAttributeKey.MaxLength, out value) && value != SteTypeBoundaries.s_doNotUseMarker) { int maxLength = (int)value; @@ -753,6 +760,7 @@ private bool AllowableDifference(string source, object result, StePermutation me private bool AllowableDifference(byte[] source, object result, StePermutation metadata) { + object value; bool returnValue = false; // turn result into byte array @@ -772,7 +780,7 @@ private bool AllowableDifference(byte[] source, object result, StePermutation me { returnValue = true; } - else if (metadata.TryGetValue(SteAttributeKey.MaxLength, out object value) && value != SteTypeBoundaries.s_doNotUseMarker) + else if (metadata.TryGetValue(SteAttributeKey.MaxLength, out value) && value != SteTypeBoundaries.s_doNotUseMarker) { int maxLength = (int)value; @@ -799,6 +807,8 @@ private bool AllowableDifference(byte[] source, object result, StePermutation me private bool AllowableDifference(SqlDecimal source, object result, StePermutation metadata) { + object value; + object value2; bool returnValue = false; // turn result into SqlDecimal @@ -822,7 +832,7 @@ private bool AllowableDifference(SqlDecimal source, object result, StePermutatio { returnValue = true; } - else if (metadata.TryGetValue(SteAttributeKey.SqlDbType, out object value) && + else if (metadata.TryGetValue(SteAttributeKey.SqlDbType, out value) && SteTypeBoundaries.s_doNotUseMarker != value && (SqlDbType.SmallMoney == (SqlDbType)value || SqlDbType.Money == (SqlDbType)value)) @@ -846,7 +856,7 @@ private bool AllowableDifference(SqlDecimal source, object result, StePermutatio SqlDbType.Decimal == (SqlDbType)value) { if (metadata.TryGetValue(SteAttributeKey.Scale, out value) && - metadata.TryGetValue(SteAttributeKey.Precision, out object value2) && + metadata.TryGetValue(SteAttributeKey.Precision, out value2) && SteTypeBoundaries.s_doNotUseMarker != value && SteTypeBoundaries.s_doNotUseMarker != value2) { @@ -895,55 +905,55 @@ private bool CompareValue(object result, object source, StePermutation metadata) break; case TypeCode.Object: { - if (source is char[] charSource) + if (source is char[]) { - source = new string(charSource); + source = new string((char[])source); isMatch = AllowableDifference((string)source, result, metadata); } - else if (source is byte[] byteSource) + else if (source is byte[]) { - isMatch = AllowableDifference(byteSource, result, metadata); + isMatch = AllowableDifference((byte[])source, result, metadata); } - else if (source is SqlBytes sqlBytesSource) + else if (source is SqlBytes) { - isMatch = AllowableDifference(sqlBytesSource.Value, result, metadata); + isMatch = AllowableDifference(((SqlBytes)source).Value, result, metadata); } - else if (source is SqlChars sqlCharSource) + else if (source is SqlChars) { - source = new string(sqlCharSource.Value); + source = new string(((SqlChars)source).Value); isMatch = AllowableDifference((string)source, result, metadata); } - else if (source is SqlInt64 @int && result is long) + else if (source is SqlInt64 && result is long) { - isMatch = result.Equals(@int.Value); + isMatch = result.Equals(((SqlInt64)source).Value); } - else if (source is SqlInt32 shortSource && result is int) + else if (source is SqlInt32 && result is int) { - isMatch = result.Equals(shortSource.Value); + isMatch = result.Equals(((SqlInt32)source).Value); } - else if (source is SqlInt16 intSource && result is short) + else if (source is SqlInt16 && result is short) { - isMatch = result.Equals(intSource.Value); + isMatch = result.Equals(((SqlInt16)source).Value); } - else if (source is SqlSingle singleSource && result is float) + else if (source is SqlSingle && result is float) { - isMatch = result.Equals(singleSource.Value); + isMatch = result.Equals(((SqlSingle)source).Value); } - else if (source is SqlDouble @double && result is double) + else if (source is SqlDouble && result is double) { - isMatch = result.Equals(@double.Value); + isMatch = result.Equals(((SqlDouble)source).Value); } - else if (source is SqlDateTime timeSource && result is DateTime) + else if (source is SqlDateTime && result is DateTime) { - isMatch = result.Equals(timeSource.Value); + isMatch = result.Equals(((SqlDateTime)source).Value); } - else if (source is SqlMoney sqlMoneySource) + else if (source is SqlMoney) { - isMatch = AllowableDifference(new SqlDecimal(sqlMoneySource.Value), result, metadata); + isMatch = AllowableDifference(new SqlDecimal(((SqlMoney)source).Value), result, metadata); } - else if (source is SqlDecimal @decimal) + else if (source is SqlDecimal) { - isMatch = AllowableDifference(@decimal, result, metadata); + isMatch = AllowableDifference((SqlDecimal)source, result, metadata); } } break; @@ -985,11 +995,11 @@ private IList CreateListOfRecords(StePermutation tvpPerm, object[ i++; } - List records = new(baseValues.Length); + List records = new List(baseValues.Length); for (int rowOrd = 0; rowOrd < baseValues.Length; rowOrd++) { object[] row = baseValues[rowOrd]; - SqlDataRecord rec = new(fieldMetadata); + SqlDataRecord rec = new SqlDataRecord(fieldMetadata); records.Add(rec); // Call SetValue *after* Add to ensure record is put in list for (int colOrd = 0; colOrd < row.Length; colOrd++) { @@ -1014,7 +1024,7 @@ private IList CreateListOfRecords(StePermutation tvpPerm, object[ private DataTable CreateNewTable(object[] row, ref Type[] lastRowTypes) { - DataTable dt = new(); + DataTable dt = new DataTable(); for (int i = 0; i < row.Length; i++) { object value = row[i]; @@ -1047,7 +1057,7 @@ private void CreateServerObjects(StePermutation tvpPerm) { // Create the table type tsql - StringBuilder tsql = new(); + StringBuilder tsql = new StringBuilder(); tsql.Append("CREATE TYPE "); tsql.Append(GetTypeName(tvpPerm)); tsql.Append(" AS TABLE("); @@ -1187,17 +1197,19 @@ private void CreateServerObjects(StePermutation tvpPerm) tsql.Append(")"); - using SqlConnection conn = new(_connStr); - conn.Open(); + using (SqlConnection conn = new SqlConnection(_connStr)) + { + conn.Open(); - // execute it to create the type - SqlCommand cmd = new(tsql.ToString(), conn); - cmd.ExecuteNonQuery(); + // execute it to create the type + SqlCommand cmd = new SqlCommand(tsql.ToString(), conn); + cmd.ExecuteNonQuery(); - // and create the proc that uses the type - cmd.CommandText = string.Format("CREATE PROC {0}(@tvp {1} READONLY) AS SELECT * FROM @tvp order by {2}", - GetProcName(tvpPerm), GetTypeName(tvpPerm), colOrdinal - 1); - cmd.ExecuteNonQuery(); + // and create the proc that uses the type + cmd.CommandText = string.Format("CREATE PROC {0}(@tvp {1} READONLY) AS SELECT * FROM @tvp order by {2}", + GetProcName(tvpPerm), GetTypeName(tvpPerm), colOrdinal - 1); + cmd.ExecuteNonQuery(); + } } private bool DoesRowMatchMetadata(object[] row, DataTable table) @@ -1223,54 +1235,62 @@ private bool DoesRowMatchMetadata(object[] row, DataTable table) private void DropServerObjects(StePermutation tvpPerm) { string dropText = "DROP PROC " + GetProcName(tvpPerm) + "; DROP TYPE " + GetTypeName(tvpPerm); - using SqlConnection conn = new(_connStr); - conn.Open(); - - SqlCommand cmd = new(dropText, conn); - try + using (SqlConnection conn = new SqlConnection(_connStr)) { - cmd.ExecuteNonQuery(); - } - catch (SqlException e) - { - Console.WriteLine("SqlException dropping objects: {0}", e.Number); + conn.Open(); + + SqlCommand cmd = new SqlCommand(dropText, conn); + try + { + cmd.ExecuteNonQuery(); + } + catch (SqlException e) + { + Console.WriteLine("SqlException dropping objects: {0}", e.Number); + } } } private void ExecuteAndVerify(SqlCommand cmd, StePermutation tvpPerm, object[][] objValues, DataTable dtValues) { - using SqlConnection conn = new(_connStr); - conn.Open(); - cmd.Connection = conn; - if (DataTestUtility.IsNotAzureServer()) + using (SqlConnection conn = new SqlConnection(_connStr)) { - // Choose the 2628 error message instead of 8152 in SQL Server 2016 & 2017 - using SqlCommand cmdFix = new("DBCC TRACEON(460)", conn); - cmdFix.ExecuteNonQuery(); - } + conn.Open(); + cmd.Connection = conn; + if (DataTestUtility.IsNotAzureServer()) + { + // Choose the 2628 error message instead of 8152 in SQL Server 2016 & 2017 + using (SqlCommand cmdFix = new SqlCommand("DBCC TRACEON(460)", conn)) + { + cmdFix.ExecuteNonQuery(); + } + } - try - { - using SqlDataReader rdr = cmd.ExecuteReader(); - VerifyColumnBoundaries(rdr, GetFields(tvpPerm), objValues, dtValues); - } - catch (SqlException se) - { - Console.WriteLine("SqlException. Error Code: {0}", se.Number); - } - catch (InvalidOperationException ioe) - { - Console.WriteLine("InvalidOp: {0}", ioe.Message); - } - catch (ArgumentException ae) - { - Console.WriteLine("ArgumentException: {0}", ae.Message); + try + { + using (SqlDataReader rdr = cmd.ExecuteReader()) + { + VerifyColumnBoundaries(rdr, GetFields(tvpPerm), objValues, dtValues); + } + } + catch (SqlException se) + { + Console.WriteLine("SqlException. Error Code: {0}", se.Number); + } + catch (InvalidOperationException ioe) + { + Console.WriteLine("InvalidOp: {0}", ioe.Message); + } + catch (ArgumentException ae) + { + Console.WriteLine("ArgumentException: {0}", ae.Message); + } } } private IList GenerateDataTables(object[][] values) { - List dtList = new(); + List dtList = new List(); Type[] valueTypes = new Type[values[0].Length]; foreach (object[] row in values) { @@ -1332,21 +1352,22 @@ private bool IsNull(object value) { return null == value || DBNull.Value == value || - (value is INullable nullable && - nullable.IsNull); + (value is INullable && + ((INullable)value).IsNull); } private SqlMetaData PermToSqlMetaData(StePermutation perm) { + object attr; SqlDbType sqlDbType; int maxLength = 0; byte precision = 0; byte scale = 0; - string typeName; + string typeName = null; Type type = null; long localeId = 0; SqlCompareOptions opts = SqlCompareOptions.IgnoreCase | SqlCompareOptions.IgnoreKanaType | SqlCompareOptions.IgnoreWidth; - if (perm.TryGetValue(SteAttributeKey.SqlDbType, out object attr) && (attr != SteTypeBoundaries.s_doNotUseMarker)) + if (perm.TryGetValue(SteAttributeKey.SqlDbType, out attr) && (attr != SteTypeBoundaries.s_doNotUseMarker)) { sqlDbType = (SqlDbType)attr; } @@ -1507,7 +1528,7 @@ private void DumpSqlParam(SqlParameter param) internal class TvpRestartableReader : DbDataReader { - private readonly IList _sourceData; + private IList _sourceData; int _currentRow; internal TvpRestartableReader(IList source) : base() @@ -1590,7 +1611,7 @@ override public DataTable GetSchemaTable() { SqlDataRecord rec = _sourceData[0]; - DataTable schemaTable = new(); + DataTable schemaTable = new DataTable(); schemaTable.Columns.Add(new DataColumn(SchemaTableColumn.ColumnName, typeof(string))); schemaTable.Columns.Add(new DataColumn(SchemaTableColumn.ColumnOrdinal, typeof(int))); schemaTable.Columns.Add(new DataColumn(SchemaTableColumn.ColumnSize, typeof(int))); @@ -1761,7 +1782,7 @@ internal class WraparoundRowEnumerator : IEnumerable, IEnumerator { private int _count; private int _maxCount; - private readonly SqlDataRecord _record; + private SqlDataRecord _record; public WraparoundRowEnumerator(int maxCount) { @@ -1790,8 +1811,8 @@ public bool MoveNext() object IEnumerator.Current => Current; - public int Count { get => _count; set => _count = value; } - public int MaxCount { get => _maxCount; set => _maxCount = value; } + public int Count { get => this._count; set => this._count = value; } + public int MaxCount { get => this._maxCount; set => this._maxCount = value; } public IEnumerator GetEnumerator() => this; diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/RandomStressTest/RandomStressTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/RandomStressTest/RandomStressTest.cs index 86b5438a1a..c7bc44b872 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/RandomStressTest/RandomStressTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/RandomStressTest/RandomStressTest.cs @@ -26,7 +26,7 @@ public class RandomStressTest : IDisposable private string _operationCanceledErrorMessage; private string _severeErrorMessage; - private SqlRandomTypeInfoCollection _2008Types; + private SqlRandomTypeInfoCollection _katmaiTypes; private ManualResetEvent _endEvent; private int _runningThreads; @@ -59,7 +59,7 @@ public void TestMain() _connectionStrings = connStrings.ToArray(); - _2008Types = SqlRandomTypeInfoCollection.CreateSql2008Collection(); + _katmaiTypes = SqlRandomTypeInfoCollection.CreateSql2008Collection(); _endEvent = new ManualResetEvent(false); if (_randPool.ReproMode) @@ -110,7 +110,7 @@ private void TestThread() using (var testScope = rootScope.NewScope()) { // run only once if repro file is provided - RunTest(con, testScope, _2008Types, watch); + RunTest(con, testScope, _katmaiTypes, watch); } } else @@ -119,7 +119,7 @@ private void TestThread() { using (var testScope = rootScope.NewScope()) { - RunTest(con, testScope, _2008Types, watch); + RunTest(con, testScope, _katmaiTypes, watch); } if (rootScope.Current.Next(100) == 0) diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/SqlDependencyTest/SqlDependencyTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/SqlDependencyTest/SqlDependencyTest.cs index 38cd77a89e..7bc2494b42 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/SqlDependencyTest/SqlDependencyTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/SqlDependencyTest/SqlDependencyTest.cs @@ -3,115 +3,12 @@ // See the LICENSE file in the project root for more information. using System; -using System.Reflection; using Xunit; namespace Microsoft.Data.SqlClient.ManualTesting.Tests { public class SqlDependencyTest { - [Fact] - public void AddCommandDependency() - { - SqlDependency sqlDependency = new SqlDependency(); - SqlCommand sqlCommand = new SqlCommand("command"); - sqlDependency.AddCommandDependency(sqlCommand); - } - - [Fact] - public void AddCommandDependencyHasChanges() - { - SqlDependency dep = new SqlDependency(); - SqlCommand cmd = new SqlCommand("command"); - Type sqlDependencyType = typeof(SqlDependency); - FieldInfo dependencyFiredField = sqlDependencyType.GetField("_dependencyFired", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); - dependencyFiredField.SetValue(dep, true); - - dep.AddCommandDependency(cmd); - } - - [Fact] - public void AddCommandDependencyNull_Throws() - { - SqlDependency sqlDependency = new SqlDependency(); - ArgumentNullException ex = Assert.Throws(() => sqlDependency.AddCommandDependency(null)); - Assert.Contains("null", ex.Message, StringComparison.OrdinalIgnoreCase); - } - - [Fact] - public void ConstructorInvalidTimeout_Throws() - { - SqlCommand sqlCommand = new SqlCommand("command"); - ArgumentOutOfRangeException ex = Assert.Throws(() => - { - SqlDependency sqlDependency = new SqlDependency(sqlCommand, "", -1); - }); - Assert.Contains("timeout", ex.Message, StringComparison.OrdinalIgnoreCase); - } - - [Fact] - public void ConstructorSqlCommandWithNotification_Throws() - { - SqlCommand sqlCommand = new SqlCommand("command"); - sqlCommand.Notification = new Sql.SqlNotificationRequest(); - InvalidOperationException ex = Assert.Throws(() => - { - SqlDependency sqlDependency = new SqlDependency(sqlCommand); - }); - Assert.Contains("sqlcommand", ex.Message, StringComparison.OrdinalIgnoreCase); - } - - [Fact] - public void HasChanges() - { - SqlDependency sqlDependency = new SqlDependency(); - Assert.False(sqlDependency.HasChanges); - } - - [Fact] - public void OnChangeRemove() - { - SqlDependency dep = new SqlDependency(); - OnChangeEventHandler tempDelegate = delegate (object o, SqlNotificationEventArgs args) - { - Console.WriteLine("Notification callback. Type={0}, Info={1}, Source={2}", args.Type, args.Info, args.Source); - }; - dep.OnChange += tempDelegate; - dep.OnChange -= tempDelegate; - } - - [Fact] - public void OnChangeAddDuplicate_Throws() - { - SqlDependency dep = new SqlDependency(); - OnChangeEventHandler tempDelegate = delegate (object o, SqlNotificationEventArgs args) - { - Console.WriteLine("Notification callback. Type={0}, Info={1}, Source={2}", args.Type, args.Info, args.Source); - }; - dep.OnChange += tempDelegate; - - InvalidOperationException ex = Assert.Throws(() => - { - dep.OnChange += tempDelegate; - }); - Assert.Contains("same", ex.Message, StringComparison.OrdinalIgnoreCase); - } - - [Fact] - public void OnChangeAddHasChanges() - { - SqlDependency dep = new SqlDependency(); - Type sqlDependencyType = typeof(SqlDependency); - FieldInfo dependencyFiredField = sqlDependencyType.GetField("_dependencyFired", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); - dependencyFiredField.SetValue(dep, true); - - OnChangeEventHandler tempDelegate = delegate (object o, SqlNotificationEventArgs args) - { - Console.WriteLine("Notification callback. Type={0}, Info={1}, Source={2}", args.Type, args.Info, args.Source); - }; - dep.OnChange += tempDelegate; - } - [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup), nameof(DataTestUtility.IsNotAzureServer))] public void SqlDependencyStartStopTest() { @@ -125,51 +22,5 @@ public void SqlDependencyStartStopTest() Assert.True(false, e.Message); } } - - [Fact] - public void SqlDepdencyStartEmptyConnectionString_Throws() - { - SqlDependency sqlDependency = new SqlDependency(); - ArgumentException ex = Assert.Throws(() => SqlDependency.Start("", null)); - Assert.Contains("connectionstring", ex.Message, StringComparison.OrdinalIgnoreCase); - } - - [Fact] - public void SqlDepdencyStartNullConnectionString_Throws() - { - SqlDependency sqlDependency = new SqlDependency(); - ArgumentNullException ex = Assert.Throws(() => SqlDependency.Start(null, null)); - Assert.Contains("connectionstring", ex.Message, StringComparison.OrdinalIgnoreCase); - } - - [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup), nameof(DataTestUtility.IsNotAzureServer))] - public void SqlDependencyStartStopDefaultTest() - { - try - { - SqlDependency.Start(DataTestUtility.TCPConnectionString, null); - SqlDependency.Stop(DataTestUtility.TCPConnectionString, null); - } - catch (Exception e) - { - Assert.True(false, e.Message); - } - } - - [Fact] - public void SqlDepdencyStopEmptyConnectionString_Throws() - { - SqlDependency sqlDependency = new SqlDependency(); - ArgumentException ex = Assert.Throws(() => SqlDependency.Stop("", null)); - Assert.Contains("connectionstring", ex.Message, StringComparison.OrdinalIgnoreCase); - } - - [Fact] - public void SqlDepdencyStopNullConnectionString_Throws() - { - SqlDependency sqlDependency = new SqlDependency(); - ArgumentNullException ex = Assert.Throws(() => SqlDependency.Stop(null, null)); - Assert.Contains("connectionstring", ex.Message, StringComparison.OrdinalIgnoreCase); - } } } diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/TracingTests/EventCounterTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/TracingTests/EventCounterTest.cs index 511ff315df..0a5e44bd9f 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/TracingTests/EventCounterTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/TracingTests/EventCounterTest.cs @@ -149,8 +149,7 @@ public void EventCounter_StasisCounters_Functional() [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup))] public void EventCounter_ReclaimedConnectionsCounter_Functional() { - // clean pools and pool groups - ClearConnectionPools(); + SqlConnection.ClearAllPools(); var stringBuilder = new SqlConnectionStringBuilder(DataTestUtility.TCPConnectionString) { Pooling = true, MaxPoolSize = 1 }; long rc = SqlClientEventSourceProps.ReclaimedConnections; @@ -159,7 +158,6 @@ public void EventCounter_ReclaimedConnectionsCounter_Functional() // Specifying the generation number makes it to run faster by avoiding a full GC process GC.Collect(gcNumber); GC.WaitForPendingFinalizers(); - System.Threading.Thread.Sleep(200); // give the pooler some time to reclaim the connection and avoid the conflict. using (SqlConnection conn = new SqlConnection(stringBuilder.ToString())) { @@ -222,32 +220,26 @@ private static InternalConnectionWrapper CreateEmancipatedConnection(string conn private void ClearConnectionPools() { //ClearAllPoos kills all the existing pooled connection thus deactivating all the active pools - long liveConnectionPools = SqlClientEventSourceProps.ActiveConnectionPools + + var liveConnectionPools = SqlClientEventSourceProps.ActiveConnectionPools + SqlClientEventSourceProps.InactiveConnectionPools; SqlConnection.ClearAllPools(); Assert.InRange(SqlClientEventSourceProps.InactiveConnectionPools, 0, liveConnectionPools); Assert.Equal(0, SqlClientEventSourceProps.ActiveConnectionPools); - long icp = SqlClientEventSourceProps.InactiveConnectionPools; - - // The 1st PruneConnectionPoolGroups call cleans the dangling inactive connection pools. + //the 1st PruneConnectionPoolGroups call cleans the dangling inactive connection pools PruneConnectionPoolGroups(); - // If the pool isn't empty, it's because there are active connections or distributed transactions that need it. - Assert.InRange(SqlClientEventSourceProps.InactiveConnectionPools, 0, icp); + Assert.Equal(0, SqlClientEventSourceProps.InactiveConnectionPools); //the 2nd call deactivates the dangling connection pool groups - long liveConnectionPoolGroups = SqlClientEventSourceProps.ActiveConnectionPoolGroups + + var liveConnectionPoolGroups = SqlClientEventSourceProps.ActiveConnectionPoolGroups + SqlClientEventSourceProps.InactiveConnectionPoolGroups; - long acpg = SqlClientEventSourceProps.ActiveConnectionPoolGroups; PruneConnectionPoolGroups(); Assert.InRange(SqlClientEventSourceProps.InactiveConnectionPoolGroups, 0, liveConnectionPoolGroups); - // If the pool entry isn't empty, it's because there are active pools that need it. - Assert.InRange(SqlClientEventSourceProps.ActiveConnectionPoolGroups, 0, acpg); + Assert.Equal(0, SqlClientEventSourceProps.ActiveConnectionPoolGroups); - long icpg = SqlClientEventSourceProps.InactiveConnectionPoolGroups; //the 3rd call cleans the dangling connection pool groups PruneConnectionPoolGroups(); - Assert.InRange(SqlClientEventSourceProps.InactiveConnectionPoolGroups, 0, icpg); + Assert.Equal(0, SqlClientEventSourceProps.InactiveConnectionPoolGroups); } private static void PruneConnectionPoolGroups() diff --git a/src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.TestUtilities/config.default.json b/src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.TestUtilities/config.default.json index b49cf6a9ec..043b73c4c9 100644 --- a/src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.TestUtilities/config.default.json +++ b/src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.TestUtilities/config.default.json @@ -16,7 +16,6 @@ "AzureKeyVaultClientSecret": "", "SupportsIntegratedSecurity": true, "LocalDbAppName": "", - "LocalDbSharedInstanceName":"", "SupportsFileStream": false, "FileStreamDirectory": "", "UseManagedSNIOnWindows": false, diff --git a/src/Microsoft.Data.SqlClient/tests/tools/TDS/TDS.Servers/GenericTDSServer.cs b/src/Microsoft.Data.SqlClient/tests/tools/TDS/TDS.Servers/GenericTDSServer.cs index 421e3b275a..30e362c931 100644 --- a/src/Microsoft.Data.SqlClient/tests/tools/TDS/TDS.Servers/GenericTDSServer.cs +++ b/src/Microsoft.Data.SqlClient/tests/tools/TDS/TDS.Servers/GenericTDSServer.cs @@ -739,8 +739,11 @@ protected virtual TDSMessageCollection CheckTDSVersion(ITDSServerSession session private byte[] _GenerateRandomBytes(int count) { byte[] randomBytes = new byte[count]; - RandomNumberGenerator rng = RandomNumberGenerator.Create(); - rng.GetBytes(randomBytes); + + RNGCryptoServiceProvider gen = new RNGCryptoServiceProvider(); + // Generate bytes + gen.GetBytes(randomBytes); + return randomBytes; } diff --git a/src/Microsoft.Data.SqlClient/tests/tools/TDS/TDS/Login7/TDSLogin7FedAuthOptionToken.cs b/src/Microsoft.Data.SqlClient/tests/tools/TDS/TDS/Login7/TDSLogin7FedAuthOptionToken.cs index 412664ae1a..57cb75bc57 100644 --- a/src/Microsoft.Data.SqlClient/tests/tools/TDS/TDS/Login7/TDSLogin7FedAuthOptionToken.cs +++ b/src/Microsoft.Data.SqlClient/tests/tools/TDS/TDS/Login7/TDSLogin7FedAuthOptionToken.cs @@ -366,8 +366,11 @@ private bool ReadSecurityTokenLogin(Stream source, uint optionDataLength) private byte[] _GenerateRandomBytes(int count) { byte[] randomBytes = new byte[count]; - RandomNumberGenerator rng = RandomNumberGenerator.Create(); - rng.GetBytes(randomBytes); + + RNGCryptoServiceProvider gen = new RNGCryptoServiceProvider(); + // Generate bytes + gen.GetBytes(randomBytes); + return randomBytes; } } diff --git a/src/Microsoft.Data.SqlClient/tests/tools/TDS/TDS/TDSVersion.cs b/src/Microsoft.Data.SqlClient/tests/tools/TDS/TDS/TDSVersion.cs index 0f27264406..e9e94932e5 100644 --- a/src/Microsoft.Data.SqlClient/tests/tools/TDS/TDS/TDSVersion.cs +++ b/src/Microsoft.Data.SqlClient/tests/tools/TDS/TDS/TDSVersion.cs @@ -12,19 +12,19 @@ namespace Microsoft.SqlServer.TDS public static class TDSVersion { /// - /// 2005 (Yukon) TDS version + /// Yukon TDS version /// public static Version SqlServer2005 = new Version(7, 2, 9, 2); /// - /// 2008 (Katmai) TDS version + /// Katmai TDS version /// public static Version SqlServer2008 = new Version(7, 3, 11, 3); /// - /// 2012 (Denali) TDS version + /// Denali TDS version /// - public static Version SqlServer2012 = new Version(7, 4, 0, 4); + public static Version SqlServer2010 = new Version(7, 4, 0, 4); /// /// Map SQL Server build version to TDS version @@ -36,14 +36,17 @@ public static Version GetTDSVersion(Version buildVersion) // Check build version Major part if (buildVersion.Major == 11) { - return SqlServer2012; + // Denali + return SqlServer2010; } else if (buildVersion.Major == 10) { + // Katmai return SqlServer2008; } else if (buildVersion.Major == 9) { + // Yukon return SqlServer2005; } else @@ -79,7 +82,7 @@ public static Version Resolve(Version tdsServer, Version tdsClient) /// public static bool IsSupported(Version tdsVersion) { - return tdsVersion >= SqlServer2005 && tdsVersion <= SqlServer2012; + return tdsVersion >= SqlServer2005 && tdsVersion <= SqlServer2010; } } } diff --git a/tools/props/Versions.props b/tools/props/Versions.props index f13965c102..bff13d74bb 100644 --- a/tools/props/Versions.props +++ b/tools/props/Versions.props @@ -6,12 +6,12 @@ 4.0.0.0 - 5.0.0-dev + 4.0.0-dev $(NugetPackageVersion) - 4.0.0 + 4.0.0-preview1.21232.1 4.3.1 4.3.0 @@ -29,7 +29,7 @@ 5.0.0 - 4.0.0 + 4.0.0-preview1.21232.1 5.0.0 5.0.0 5.0.0 @@ -67,7 +67,6 @@ 5.0.0-beta.20206.4 2.0.8 161.41011.9 - 10.50.1600.1 0.12.1 diff --git a/tools/specs/Microsoft.Data.SqlClient.nuspec b/tools/specs/Microsoft.Data.SqlClient.nuspec index 750ee2f48a..03b767d75c 100644 --- a/tools/specs/Microsoft.Data.SqlClient.nuspec +++ b/tools/specs/Microsoft.Data.SqlClient.nuspec @@ -28,7 +28,7 @@ When using NuGet 3.x this package requires at least version 3.4. sqlclient microsoft.data.sqlclient - + @@ -42,7 +42,7 @@ When using NuGet 3.x this package requires at least version 3.4. - + @@ -60,7 +60,7 @@ When using NuGet 3.x this package requires at least version 3.4. - + @@ -78,7 +78,7 @@ When using NuGet 3.x this package requires at least version 3.4. - +