Skip to content

Commit ee2d196

Browse files
committed
Revert "User Story 38481: Fix unique db object name issues"
This reverts commit 82ce7cf.
1 parent 82ce7cf commit ee2d196

26 files changed

+188
-378
lines changed

src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/ApiShould.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -148,8 +148,8 @@ public void SqlParameterProperties(string connection)
148148
const string firstColumnName = @"firstColumn";
149149
const string secondColumnName = @"secondColumn";
150150
const string thirdColumnName = @"thirdColumn";
151-
string inputProcedureName = DataTestUtility.GetShortName("InputProc").ToString();
152-
string outputProcedureName = DataTestUtility.GetShortName("OutputProc").ToString();
151+
string inputProcedureName = DataTestUtility.GetUniqueName("InputProc").ToString();
152+
string outputProcedureName = DataTestUtility.GetUniqueName("OutputProc").ToString();
153153
const int charColumnSize = 100;
154154
const int decimalColumnPrecision = 10;
155155
const int decimalColumnScale = 4;
@@ -694,7 +694,7 @@ public void TestExecuteReader(string connection)
694694
[ClassData(typeof(AEConnectionStringProvider))]
695695
public async void TestExecuteReaderAsyncWithLargeQuery(string connectionString)
696696
{
697-
string randomName = DataTestUtility.GetShortName(Guid.NewGuid().ToString().Replace("-", ""), false);
697+
string randomName = DataTestUtility.GetUniqueName(Guid.NewGuid().ToString().Replace("-", ""), false);
698698
if (randomName.Length > 50)
699699
{
700700
randomName = randomName.Substring(0, 50);
@@ -878,8 +878,8 @@ public void TestEnclaveStoredProceduresWithAndWithoutParameters(string connectio
878878
using SqlCommand sqlCommand = new("", sqlConnection, transaction: null,
879879
columnEncryptionSetting: SqlCommandColumnEncryptionSetting.Enabled);
880880

881-
string procWithoutParams = DataTestUtility.GetShortName("EnclaveWithoutParams", withBracket: false);
882-
string procWithParam = DataTestUtility.GetShortName("EnclaveWithParams", withBracket: false);
881+
string procWithoutParams = DataTestUtility.GetUniqueName("EnclaveWithoutParams", withBracket: false);
882+
string procWithParam = DataTestUtility.GetUniqueName("EnclaveWithParams", withBracket: false);
883883

884884
try
885885
{

src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/CspProviderExt.cs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,55 @@ public void TestRoundTripWithCSPAndCertStoreProvider()
157157
}
158158
}
159159

160+
[ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringSetupForAE))]
161+
[ClassData(typeof(AEConnectionStringProvider))]
162+
public void TestEncryptDecryptWithCSP(string connectionString)
163+
{
164+
string providerName = @"Microsoft Enhanced RSA and AES Cryptographic Provider";
165+
string keyIdentifier = DataTestUtility.GetUniqueNameForSqlServer("CSP");
166+
167+
try
168+
{
169+
CertificateUtilityWin.RSAPersistKeyInCsp(providerName, keyIdentifier);
170+
string cspPath = String.Concat(providerName, @"/", keyIdentifier);
171+
172+
SQLSetupStrategyCspExt sqlSetupStrategyCsp = new SQLSetupStrategyCspExt(cspPath);
173+
string tableName = sqlSetupStrategyCsp.CspProviderTable.Name;
174+
175+
try
176+
{
177+
using SqlConnection sqlConn = new(connectionString);
178+
sqlConn.Open();
179+
180+
Table.DeleteData(tableName, sqlConn);
181+
182+
// insert 1 row data
183+
Customer customer = new Customer(45, "Microsoft", "Corporation");
184+
185+
DatabaseHelper.InsertCustomerData(sqlConn, null, tableName, customer);
186+
187+
// Test INPUT parameter on an encrypted parameter
188+
using SqlCommand sqlCommand = new(@$"SELECT CustomerId, FirstName, LastName FROM [{tableName}] WHERE FirstName = @firstName",
189+
sqlConn, null, SqlCommandColumnEncryptionSetting.Enabled);
190+
SqlParameter customerFirstParam = sqlCommand.Parameters.AddWithValue(@"firstName", @"Microsoft");
191+
Console.WriteLine(@"Exception: {0}");
192+
customerFirstParam.Direction = System.Data.ParameterDirection.Input;
193+
194+
using SqlDataReader sqlDataReader = sqlCommand.ExecuteReader();
195+
ValidateResultSet(sqlDataReader);
196+
}
197+
finally
198+
{
199+
// clean up database resources
200+
sqlSetupStrategyCsp.Dispose();
201+
}
202+
}
203+
finally
204+
{
205+
CertificateUtilityWin.RSADeleteKeyInCsp(providerName, keyIdentifier);
206+
}
207+
}
208+
160209
/// <summary>
161210
/// Validates that the results are the ones expected.
162211
/// </summary>

src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs

Lines changed: 37 additions & 165 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ public static bool TcpConnectionStringDoesNotUseAadAuth
8888
{
8989
get
9090
{
91-
SqlConnectionStringBuilder builder = new(TCPConnectionString);
91+
SqlConnectionStringBuilder builder = new (TCPConnectionString);
9292
return builder.Authentication == SqlAuthenticationMethod.SqlPassword || builder.Authentication == SqlAuthenticationMethod.NotSpecified;
9393
}
9494
}
@@ -415,176 +415,48 @@ public static bool DoesHostAddressContainBothIPv4AndIPv6()
415415
}
416416
}
417417

418-
// Generate a new GUID and return the characters from its 1st and 4th
419-
// parts, as shown here:
420-
//
421-
// 7ff01cb8-88c7-11f0-b433-00155d7e531e
422-
// ^^^^^^^^ ^^^^
423-
//
424-
// These 12 characters are concatenated together without any
425-
// separators. These 2 parts typically comprise a timestamp and clock
426-
// sequence, most likely to be unique for tests that generate names in
427-
// quick succession.
428-
private static string GetGuidParts()
429-
{
430-
var guid = Guid.NewGuid().ToString();
431-
// GOTCHA: The slice operator is inclusive of the start index and
432-
// exclusive of the end index!
433-
return guid.Substring(0, 8) + guid.Substring(19, 4);
434-
}
435-
436418
/// <summary>
437-
/// Generate a short unique database object name, whose maximum length
438-
/// is 30 characters, with the format:
439-
///
440-
/// <Prefix>_<GuidParts>
441-
///
442-
/// The Prefix will be truncated to satisfy the overall maximum length.
443-
///
444-
/// The GUID parts will be the characters from the 1st and 4th blocks
445-
/// from a traditional string representation, as shown here:
446-
///
447-
/// 7ff01cb8-88c7-11f0-b433-00155d7e531e
448-
/// ^^^^^^^^ ^^^^
449-
///
450-
/// These 2 parts typically comprise a timestamp and clock sequence,
451-
/// most likely to be unique for tests that generate names in quick
452-
/// succession. The 12 characters are concatenated together without any
453-
/// separators.
419+
/// Generate a unique name to use in Sql Server;
420+
/// some providers does not support names (Oracle supports up to 30).
454421
/// </summary>
455-
///
456-
/// <param name="prefix">
457-
/// The prefix to use when generating the unique name, truncated to at
458-
/// most 18 characters when withBracket is false, and 16 characters when
459-
/// withBracket is true.
460-
///
461-
/// This should not contain any characters that cannot be used in
462-
/// database object names. See:
463-
///
464-
/// https://learn.microsoft.com/en-us/sql/relational-databases/databases/database-identifiers?view=sql-server-ver17#rules-for-regular-identifiers
465-
/// </param>
466-
///
467-
/// <param name="withBracket">
468-
/// When true, the entire generated name will be enclosed in square
469-
/// brackets, for example:
470-
///
471-
/// [MyPrefix_7ff01cb811f0]
472-
/// </param>
473-
///
474-
/// <returns>
475-
/// A unique database object name, no more than 30 characters long.
476-
/// </returns>
477-
public static string GetShortName(string prefix, bool withBracket = true)
478-
{
479-
StringBuilder name = new(30);
480-
481-
if (withBracket)
482-
{
483-
name.Append('[');
484-
}
485-
486-
int maxPrefixLength = withBracket ? 16 : 18;
487-
if (prefix.Length > maxPrefixLength)
488-
{
489-
prefix = prefix.Substring(0, maxPrefixLength);
490-
}
491-
492-
name.Append(prefix);
493-
name.Append('_');
494-
name.Append(GetGuidParts());
495-
496-
if (withBracket)
497-
{
498-
name.Append(']');
499-
}
500-
501-
return name.ToString();
422+
/// <param name="prefix">The name length will be no more then (16 + prefix.Length + escapeLeft.Length + escapeRight.Length).</param>
423+
/// <param name="withBracket">Name without brackets.</param>
424+
/// <returns>Unique name by considering the Sql Server naming rules.</returns>
425+
public static string GetUniqueName(string prefix, bool withBracket = true)
426+
{
427+
string escapeLeft = withBracket ? "[" : string.Empty;
428+
string escapeRight = withBracket ? "]" : string.Empty;
429+
string uniqueName = string.Format("{0}{1}_{2}_{3}{4}",
430+
escapeLeft,
431+
prefix,
432+
DateTime.Now.Ticks.ToString("X", CultureInfo.InvariantCulture), // up to 8 characters
433+
Guid.NewGuid().ToString().Substring(0, 6), // take the first 6 characters only
434+
escapeRight);
435+
return uniqueName;
502436
}
503437

504438
/// <summary>
505-
/// Generate a long unique database object name, whose maximum length is
506-
/// 96 characters, with the format:
507-
///
508-
/// <Prefix>_<GuidParts>_<UserName>_<MachineName>
509-
///
510-
/// The Prefix will be truncated to satisfy the overall maximum length.
511-
///
512-
/// The GUID Parts will be the characters from the 1st and 4th blocks
513-
/// from a traditional string representation, as shown here:
514-
///
515-
/// 7ff01cb8-88c7-11f0-b433-00155d7e531e
516-
/// ^^^^^^^^ ^^^^
517-
///
518-
/// These 2 parts typically comprise a timestamp and clock sequence,
519-
/// most likely to be unique for tests that generate names in quick
520-
/// succession. The 12 characters are concatenated together without any
521-
/// separators.
522-
///
523-
/// The UserName and MachineName are obtained from the Environment,
524-
/// and will be truncated to satisfy the maximum overall length.
439+
/// Uses environment values `UserName` and `MachineName` in addition to the specified `prefix` and current date
440+
/// to generate a unique name to use in Sql Server;
441+
/// SQL Server supports long names (up to 128 characters), add extra info for troubleshooting.
525442
/// </summary>
526-
///
527-
/// <param name="prefix">
528-
/// The prefix to use when generating the unique name, truncated to at
529-
/// most 32 characters.
530-
///
531-
/// This should not contain any characters that cannot be used in
532-
/// database object names. See:
533-
///
534-
/// https://learn.microsoft.com/en-us/sql/relational-databases/databases/database-identifiers?view=sql-server-ver17#rules-for-regular-identifiers
535-
/// </param>
536-
///
537-
/// <param name="withBracket">
538-
/// When true, the entire generated name will be enclosed in square
539-
/// brackets, for example:
540-
///
541-
/// [MyPrefix_7ff01cb811f0_test_user_ci_agent_machine_name]
542-
/// </param>
543-
///
544-
/// <returns>
545-
/// A unique database object name, no more than 96 characters long.
546-
/// </returns>
547-
public static string GetLongName(string prefix, bool withBracket = true)
548-
{
549-
StringBuilder name = new(96);
550-
551-
if (withBracket)
552-
{
553-
name.Append('[');
554-
}
555-
556-
if (prefix.Length > 32)
557-
{
558-
prefix = prefix.Substring(0, 32);
559-
}
560-
561-
name.Append(prefix);
562-
name.Append('_');
563-
name.Append(GetGuidParts());
564-
name.Append('_');
565-
566-
var suffix =
567-
Environment.UserName + '_' +
568-
Environment.MachineName;
569-
570-
int maxSuffixLength = 96 - name.Length;
571-
if (withBracket)
572-
{
573-
--maxSuffixLength;
574-
}
575-
if (suffix.Length > maxSuffixLength)
576-
{
577-
suffix = suffix.Substring(0, maxSuffixLength);
578-
}
579-
580-
name.Append(suffix);
581-
582-
if (withBracket)
583-
{
584-
name.Append(']');
585-
}
586-
587-
return name.ToString();
443+
/// <param name="prefix">Add the prefix to the generate string.</param>
444+
/// <param name="withBracket">Database name must be pass with brackets by default.</param>
445+
/// <returns>Unique name by considering the Sql Server naming rules.</returns>
446+
public static string GetUniqueNameForSqlServer(string prefix, bool withBracket = true)
447+
{
448+
string extendedPrefix = string.Format(
449+
"{0}_{1}_{2}@{3}",
450+
prefix,
451+
Environment.UserName,
452+
Environment.MachineName,
453+
DateTime.Now.ToString("yyyy_MM_dd", CultureInfo.InvariantCulture));
454+
string name = GetUniqueName(extendedPrefix, withBracket);
455+
if (name.Length > 128)
456+
{
457+
throw new ArgumentOutOfRangeException("the name is too long - SQL Server names are limited to 128");
458+
}
459+
return name;
588460
}
589461

590462
public static bool IsSupportingDistributedTransactions()

src/Microsoft.Data.SqlClient/tests/ManualTests/ProviderAgnostic/ReaderTest/ReaderTest.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public static void TestMain()
1919
{
2020
string connectionString = DataTestUtility.TCPConnectionString;
2121

22-
string tempTable = DataTestUtility.GetLongName("table");
22+
string tempTable = DataTestUtility.GetUniqueNameForSqlServer("table");
2323

2424
DbProviderFactory provider = SqlClientFactory.Instance;
2525
try
@@ -275,7 +275,7 @@ public static void TestMain()
275275
[ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup), nameof(DataTestUtility.IsNotAzureSynapse))]
276276
public static void SqlDataReader_SqlBuffer_GetFieldValue()
277277
{
278-
string tableName = DataTestUtility.GetLongName("SqlBuffer_GetFieldValue");
278+
string tableName = DataTestUtility.GetUniqueNameForSqlServer("SqlBuffer_GetFieldValue");
279279
DateTimeOffset dtoffset = DateTimeOffset.Now;
280280
DateTime dt = DateTime.Now;
281281
//Exclude the millisecond because of rounding at some points by SQL Server.
@@ -374,7 +374,7 @@ public static void SqlDataReader_SqlBuffer_GetFieldValue()
374374
[ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup), nameof(DataTestUtility.IsNotAzureSynapse))]
375375
public static async Task SqlDataReader_SqlBuffer_GetFieldValue_Async()
376376
{
377-
string tableName = DataTestUtility.GetLongName("SqlBuffer_GetFieldValue_Async");
377+
string tableName = DataTestUtility.GetUniqueNameForSqlServer("SqlBuffer_GetFieldValue_Async");
378378
DateTimeOffset dtoffset = DateTimeOffset.Now;
379379
DateTime dt = DateTime.Now;
380380
//Exclude the millisecond because of rounding at some points by SQL Server.

src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/AdapterTest/AdapterTest.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ public class AdapterTest
5454
public AdapterTest()
5555
{
5656
// create random name for temp tables
57-
_tempTable = DataTestUtility.GetShortName("AdapterTest");
57+
_tempTable = DataTestUtility.GetUniqueName("AdapterTest");
5858
_tempTable = _tempTable.Replace('-', '_');
5959

6060
_randomGuid = Guid.NewGuid().ToString();
@@ -487,7 +487,7 @@ public void ParameterTest_AllTypes()
487487
[ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup), nameof(DataTestUtility.IsNotAzureSynapse))]
488488
public void ParameterTest_InOut()
489489
{
490-
string procName = DataTestUtility.GetShortName("P");
490+
string procName = DataTestUtility.GetUniqueName("P");
491491
// input, output
492492
string spCreateInOut =
493493
"CREATE PROCEDURE " + procName + " @in int, @inout int OUTPUT, @out nvarchar(8) OUTPUT " +
@@ -768,13 +768,13 @@ public void BulkUpdateTest()
768768
[ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup), nameof(DataTestUtility.IsNotAzureSynapse))]
769769
public void UpdateRefreshTest()
770770
{
771-
string identTableName = DataTestUtility.GetShortName("ID_");
771+
string identTableName = DataTestUtility.GetUniqueName("ID_");
772772
string createIdentTable =
773773
$"CREATE TABLE {identTableName} (id int IDENTITY," +
774774
"LastName nvarchar(50) NULL," +
775775
"Firstname nvarchar(50) NULL)";
776776

777-
string spName = DataTestUtility.GetShortName("sp_insert", withBracket: false);
777+
string spName = DataTestUtility.GetUniqueName("sp_insert", withBracket: false);
778778
string spCreateInsert =
779779
$"CREATE PROCEDURE {spName}" +
780780
"(@FirstName nvarchar(50), @LastName nvarchar(50), @id int OUTPUT) " +
@@ -1087,7 +1087,7 @@ public void AutoGenUpdateTest()
10871087
[ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup), nameof(DataTestUtility.IsNotAzureSynapse))]
10881088
public void AutoGenErrorTest()
10891089
{
1090-
string identTableName = DataTestUtility.GetShortName("ID_");
1090+
string identTableName = DataTestUtility.GetUniqueName("ID_");
10911091
string createIdentTable =
10921092
$"CREATE TABLE {identTableName} (id int IDENTITY," +
10931093
"LastName nvarchar(50) NULL," +

0 commit comments

Comments
 (0)