mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-02-16 10:58:30 -05:00
Introduce support for "Command Timeout" connection property (#1765)
This commit is contained in:
@@ -101,6 +101,16 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection
|
|||||||
GroupName = "Initialization"
|
GroupName = "Initialization"
|
||||||
},
|
},
|
||||||
new ConnectionOption
|
new ConnectionOption
|
||||||
|
{
|
||||||
|
Name = "commandTimeout",
|
||||||
|
DisplayName = "Command timeout",
|
||||||
|
Description =
|
||||||
|
"The length of time (in seconds) to wait for a command to complete on the server before terminating the attempt and generating an error",
|
||||||
|
ValueType = ConnectionOption.ValueTypeNumber,
|
||||||
|
DefaultValue = "30",
|
||||||
|
GroupName = "Initialization"
|
||||||
|
},
|
||||||
|
new ConnectionOption
|
||||||
{
|
{
|
||||||
Name = "currentLanguage",
|
Name = "currentLanguage",
|
||||||
DisplayName = "Current language",
|
DisplayName = "Current language",
|
||||||
|
|||||||
@@ -1403,6 +1403,10 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection
|
|||||||
{
|
{
|
||||||
connectionBuilder.ConnectTimeout = connectionDetails.ConnectTimeout.Value;
|
connectionBuilder.ConnectTimeout = connectionDetails.ConnectTimeout.Value;
|
||||||
}
|
}
|
||||||
|
if (connectionDetails.CommandTimeout.HasValue)
|
||||||
|
{
|
||||||
|
connectionBuilder.CommandTimeout = connectionDetails.CommandTimeout.Value;
|
||||||
|
}
|
||||||
if (connectionDetails.ConnectRetryCount.HasValue)
|
if (connectionDetails.ConnectRetryCount.HasValue)
|
||||||
{
|
{
|
||||||
connectionBuilder.ConnectRetryCount = connectionDetails.ConnectRetryCount.Value;
|
connectionBuilder.ConnectRetryCount = connectionDetails.ConnectRetryCount.Value;
|
||||||
@@ -1554,6 +1558,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection
|
|||||||
ConnectRetryCount = builder.ConnectRetryCount,
|
ConnectRetryCount = builder.ConnectRetryCount,
|
||||||
ConnectRetryInterval = builder.ConnectRetryInterval,
|
ConnectRetryInterval = builder.ConnectRetryInterval,
|
||||||
ConnectTimeout = builder.ConnectTimeout,
|
ConnectTimeout = builder.ConnectTimeout,
|
||||||
|
CommandTimeout = builder.CommandTimeout,
|
||||||
CurrentLanguage = builder.CurrentLanguage,
|
CurrentLanguage = builder.CurrentLanguage,
|
||||||
DatabaseName = builder.InitialCatalog,
|
DatabaseName = builder.InitialCatalog,
|
||||||
ColumnEncryptionSetting = builder.ColumnEncryptionSetting.ToString(),
|
ColumnEncryptionSetting = builder.ColumnEncryptionSetting.ToString(),
|
||||||
@@ -1731,11 +1736,13 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection
|
|||||||
{
|
{
|
||||||
// capture original values
|
// capture original values
|
||||||
int? originalTimeout = connInfo.ConnectionDetails.ConnectTimeout;
|
int? originalTimeout = connInfo.ConnectionDetails.ConnectTimeout;
|
||||||
|
int? originalCommandTimeout = connInfo.ConnectionDetails.CommandTimeout;
|
||||||
bool? originalPersistSecurityInfo = connInfo.ConnectionDetails.PersistSecurityInfo;
|
bool? originalPersistSecurityInfo = connInfo.ConnectionDetails.PersistSecurityInfo;
|
||||||
bool? originalPooling = connInfo.ConnectionDetails.Pooling;
|
bool? originalPooling = connInfo.ConnectionDetails.Pooling;
|
||||||
|
|
||||||
// increase the connection timeout to at least 30 seconds and and build connection string
|
// increase the connection and command timeout to at least 30 seconds and and build connection string
|
||||||
connInfo.ConnectionDetails.ConnectTimeout = Math.Max(30, originalTimeout ?? 0);
|
connInfo.ConnectionDetails.ConnectTimeout = Math.Max(30, originalTimeout ?? 0);
|
||||||
|
connInfo.ConnectionDetails.CommandTimeout = Math.Max(30, originalCommandTimeout ?? 0);
|
||||||
// enable PersistSecurityInfo to handle issues in SMO where the connection context is lost in reconnections
|
// enable PersistSecurityInfo to handle issues in SMO where the connection context is lost in reconnections
|
||||||
connInfo.ConnectionDetails.PersistSecurityInfo = true;
|
connInfo.ConnectionDetails.PersistSecurityInfo = true;
|
||||||
// turn off connection pool to avoid hold locks on server resources after calling SqlConnection Close method
|
// turn off connection pool to avoid hold locks on server resources after calling SqlConnection Close method
|
||||||
@@ -1747,6 +1754,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection
|
|||||||
|
|
||||||
// restore original values
|
// restore original values
|
||||||
connInfo.ConnectionDetails.ConnectTimeout = originalTimeout;
|
connInfo.ConnectionDetails.ConnectTimeout = originalTimeout;
|
||||||
|
connInfo.ConnectionDetails.CommandTimeout = originalCommandTimeout;
|
||||||
connInfo.ConnectionDetails.PersistSecurityInfo = originalPersistSecurityInfo;
|
connInfo.ConnectionDetails.PersistSecurityInfo = originalPersistSecurityInfo;
|
||||||
connInfo.ConnectionDetails.Pooling = originalPooling;
|
connInfo.ConnectionDetails.Pooling = originalPooling;
|
||||||
|
|
||||||
|
|||||||
@@ -233,6 +233,22 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection.Contracts
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the length of time (in seconds) to wait for a command to complete on the server before terminating the attempt and generating an error.
|
||||||
|
/// </summary>
|
||||||
|
public int? CommandTimeout
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return GetOptionValue<int?>("commandTimeout");
|
||||||
|
}
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
SetOptionValue("commandTimeout", value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The number of reconnections attempted after identifying that there was an idle connection failure.
|
/// The number of reconnections attempted after identifying that there was an idle connection failure.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -608,6 +624,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection.Contracts
|
|||||||
&& ConnectRetryCount == other.ConnectRetryCount
|
&& ConnectRetryCount == other.ConnectRetryCount
|
||||||
&& ConnectRetryInterval == other.ConnectRetryInterval
|
&& ConnectRetryInterval == other.ConnectRetryInterval
|
||||||
&& ConnectTimeout == other.ConnectTimeout
|
&& ConnectTimeout == other.ConnectTimeout
|
||||||
|
&& CommandTimeout == other.CommandTimeout
|
||||||
&& string.Equals(CurrentLanguage, other.CurrentLanguage, System.StringComparison.InvariantCultureIgnoreCase)
|
&& string.Equals(CurrentLanguage, other.CurrentLanguage, System.StringComparison.InvariantCultureIgnoreCase)
|
||||||
&& string.Equals(DatabaseDisplayName, other.DatabaseDisplayName, System.StringComparison.InvariantCultureIgnoreCase)
|
&& string.Equals(DatabaseDisplayName, other.DatabaseDisplayName, System.StringComparison.InvariantCultureIgnoreCase)
|
||||||
&& string.Equals(DatabaseName, other.DatabaseName, System.StringComparison.InvariantCultureIgnoreCase)
|
&& string.Equals(DatabaseName, other.DatabaseName, System.StringComparison.InvariantCultureIgnoreCase)
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection.Contracts
|
|||||||
HostNameInCertificate = details.HostNameInCertificate,
|
HostNameInCertificate = details.HostNameInCertificate,
|
||||||
PersistSecurityInfo = details.PersistSecurityInfo,
|
PersistSecurityInfo = details.PersistSecurityInfo,
|
||||||
ConnectTimeout = details.ConnectTimeout,
|
ConnectTimeout = details.ConnectTimeout,
|
||||||
|
CommandTimeout = details.CommandTimeout,
|
||||||
ConnectRetryCount = details.ConnectRetryCount,
|
ConnectRetryCount = details.ConnectRetryCount,
|
||||||
ConnectRetryInterval = details.ConnectRetryInterval,
|
ConnectRetryInterval = details.ConnectRetryInterval,
|
||||||
ApplicationName = details.ApplicationName,
|
ApplicationName = details.ApplicationName,
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Connection
|
|||||||
Assert.AreEqual(details.ConnectRetryInterval, expectedForInt);
|
Assert.AreEqual(details.ConnectRetryInterval, expectedForInt);
|
||||||
Assert.AreEqual(details.ConnectRetryCount, expectedForInt);
|
Assert.AreEqual(details.ConnectRetryCount, expectedForInt);
|
||||||
Assert.AreEqual(details.ConnectTimeout, expectedForInt);
|
Assert.AreEqual(details.ConnectTimeout, expectedForInt);
|
||||||
|
Assert.AreEqual(details.CommandTimeout, expectedForInt);
|
||||||
Assert.AreEqual(details.LoadBalanceTimeout, expectedForInt);
|
Assert.AreEqual(details.LoadBalanceTimeout, expectedForInt);
|
||||||
Assert.AreEqual(details.MaxPoolSize, expectedForInt);
|
Assert.AreEqual(details.MaxPoolSize, expectedForInt);
|
||||||
Assert.AreEqual(details.MinPoolSize, expectedForInt);
|
Assert.AreEqual(details.MinPoolSize, expectedForInt);
|
||||||
@@ -82,6 +83,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Connection
|
|||||||
details.ConnectRetryInterval = expectedForInt + index++;
|
details.ConnectRetryInterval = expectedForInt + index++;
|
||||||
details.ConnectRetryCount = expectedForInt + index++;
|
details.ConnectRetryCount = expectedForInt + index++;
|
||||||
details.ConnectTimeout = expectedForInt + index++;
|
details.ConnectTimeout = expectedForInt + index++;
|
||||||
|
details.CommandTimeout = expectedForInt + index++;
|
||||||
details.LoadBalanceTimeout = expectedForInt + index++;
|
details.LoadBalanceTimeout = expectedForInt + index++;
|
||||||
details.MaxPoolSize = expectedForInt + index++;
|
details.MaxPoolSize = expectedForInt + index++;
|
||||||
details.MinPoolSize = expectedForInt + index++;
|
details.MinPoolSize = expectedForInt + index++;
|
||||||
@@ -115,6 +117,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Connection
|
|||||||
Assert.AreEqual(details.ConnectRetryInterval, expectedForInt + index++);
|
Assert.AreEqual(details.ConnectRetryInterval, expectedForInt + index++);
|
||||||
Assert.AreEqual(details.ConnectRetryCount, expectedForInt + index++);
|
Assert.AreEqual(details.ConnectRetryCount, expectedForInt + index++);
|
||||||
Assert.AreEqual(details.ConnectTimeout, expectedForInt + index++);
|
Assert.AreEqual(details.ConnectTimeout, expectedForInt + index++);
|
||||||
|
Assert.AreEqual(details.CommandTimeout, expectedForInt + index++);
|
||||||
Assert.AreEqual(details.LoadBalanceTimeout, expectedForInt + index++);
|
Assert.AreEqual(details.LoadBalanceTimeout, expectedForInt + index++);
|
||||||
Assert.AreEqual(details.MaxPoolSize, expectedForInt + index++);
|
Assert.AreEqual(details.MaxPoolSize, expectedForInt + index++);
|
||||||
Assert.AreEqual(details.MinPoolSize, expectedForInt + index++);
|
Assert.AreEqual(details.MinPoolSize, expectedForInt + index++);
|
||||||
@@ -157,6 +160,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Connection
|
|||||||
details.ConnectRetryInterval = expectedForInt + index++;
|
details.ConnectRetryInterval = expectedForInt + index++;
|
||||||
details.ConnectRetryCount = expectedForInt + index++;
|
details.ConnectRetryCount = expectedForInt + index++;
|
||||||
details.ConnectTimeout = expectedForInt + index++;
|
details.ConnectTimeout = expectedForInt + index++;
|
||||||
|
details.CommandTimeout = expectedForInt + index++;
|
||||||
details.LoadBalanceTimeout = expectedForInt + index++;
|
details.LoadBalanceTimeout = expectedForInt + index++;
|
||||||
details.MaxPoolSize = expectedForInt + index++;
|
details.MaxPoolSize = expectedForInt + index++;
|
||||||
details.MinPoolSize = expectedForInt + index++;
|
details.MinPoolSize = expectedForInt + index++;
|
||||||
@@ -199,7 +203,6 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Connection
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void SettingConnectiomTimeoutToLongShouldStillReturnInt()
|
public void SettingConnectiomTimeoutToLongShouldStillReturnInt()
|
||||||
{
|
{
|
||||||
@@ -229,6 +232,35 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Connection
|
|||||||
Assert.AreEqual(details.ConnectTimeout, expectedValue);
|
Assert.AreEqual(details.ConnectTimeout, expectedValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void SettingCommandTimeoutToLongShouldStillReturnInt()
|
||||||
|
{
|
||||||
|
ConnectionDetails details = new ConnectionDetails();
|
||||||
|
|
||||||
|
long timeout = 30;
|
||||||
|
int? expectedValue = 30;
|
||||||
|
details.Options["commandTimeout"] = timeout;
|
||||||
|
|
||||||
|
Assert.AreEqual(details.CommandTimeout, expectedValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void CommandTimeoutShouldReturnNullIfNotSet()
|
||||||
|
{
|
||||||
|
ConnectionDetails details = new ConnectionDetails();
|
||||||
|
int? expectedValue = null;
|
||||||
|
Assert.AreEqual(details.CommandTimeout, expectedValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void CommandTimeoutShouldReturnNullIfSetToNull()
|
||||||
|
{
|
||||||
|
ConnectionDetails details = new ConnectionDetails();
|
||||||
|
details.Options["commandTimeout"] = null;
|
||||||
|
int? expectedValue = null;
|
||||||
|
Assert.AreEqual(details.CommandTimeout, expectedValue);
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void SettingEncrypShouldReturnExpectedEncryptOption()
|
public void SettingEncrypShouldReturnExpectedEncryptOption()
|
||||||
{
|
{
|
||||||
@@ -262,6 +294,21 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Connection
|
|||||||
Assert.That(details.Encrypt, Is.EqualTo("Mandatory"), "Encrypt should be mandatory.");
|
Assert.That(details.Encrypt, Is.EqualTo("Mandatory"), "Encrypt should be mandatory.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void SettingCommandTimeoutToLongWhichCannotBeConvertedToIntShouldNotCrash()
|
||||||
|
{
|
||||||
|
ConnectionDetails details = new ConnectionDetails();
|
||||||
|
|
||||||
|
long timeout = long.MaxValue;
|
||||||
|
int? expectedValue = null;
|
||||||
|
string? expectedEncryptValue = "Strict";
|
||||||
|
details.Options["commandTimeout"] = timeout;
|
||||||
|
details.Options["encrypt"] = expectedEncryptValue;
|
||||||
|
|
||||||
|
Assert.That(details.CommandTimeout, Is.EqualTo(expectedValue), "Command Timeout not as expected");
|
||||||
|
Assert.That(details.Encrypt, Is.EqualTo("Strict"), "Encrypt should be strict.");
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void ConnectionSettingsComparableShouldConsiderAdvancedOptions()
|
public void ConnectionSettingsComparableShouldConsiderAdvancedOptions()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -538,6 +538,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Connection
|
|||||||
new object[] {"PersistSecurityInfo", true, "Persist Security Info"},
|
new object[] {"PersistSecurityInfo", true, "Persist Security Info"},
|
||||||
new object[] {"PersistSecurityInfo", false, "Persist Security Info"},
|
new object[] {"PersistSecurityInfo", false, "Persist Security Info"},
|
||||||
new object[] {"ConnectTimeout", 15, "Connect Timeout"},
|
new object[] {"ConnectTimeout", 15, "Connect Timeout"},
|
||||||
|
new object[] {"CommandTimeout", 30, "Command Timeout"},
|
||||||
new object[] {"ConnectRetryCount", 1, "Connect Retry Count"},
|
new object[] {"ConnectRetryCount", 1, "Connect Retry Count"},
|
||||||
new object[] {"ConnectRetryInterval", 10, "Connect Retry Interval"},
|
new object[] {"ConnectRetryInterval", 10, "Connect Retry Interval"},
|
||||||
new object[] {"ApplicationName", "vscode-mssql", "Application Name"},
|
new object[] {"ApplicationName", "vscode-mssql", "Application Name"},
|
||||||
@@ -1687,7 +1688,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Connection
|
|||||||
// If we make a connection to a live database
|
// If we make a connection to a live database
|
||||||
ConnectionService service = ConnectionService.Instance;
|
ConnectionService service = ConnectionService.Instance;
|
||||||
|
|
||||||
var connectionString = "Server=tcp:{servername},1433;Initial Catalog={databasename};Persist Security Info=False;User ID={your_username};Password={your_password};MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;HostNameInCertificate={servername}";
|
var connectionString = "Server=tcp:{servername},1433;Initial Catalog={databasename};Persist Security Info=False;User ID={your_username};Password={your_password};MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;Command Timeout=30;HostNameInCertificate={servername}";
|
||||||
|
|
||||||
var details = service.ParseConnectionString(connectionString);
|
var details = service.ParseConnectionString(connectionString);
|
||||||
Assert.That(details.ServerName, Is.EqualTo("tcp:{servername},1433"), "Unexpected server name");
|
Assert.That(details.ServerName, Is.EqualTo("tcp:{servername},1433"), "Unexpected server name");
|
||||||
@@ -1700,6 +1701,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Connection
|
|||||||
Assert.That(details.TrustServerCertificate, Is.False, "Unexpected database name value");
|
Assert.That(details.TrustServerCertificate, Is.False, "Unexpected database name value");
|
||||||
Assert.That(details.HostNameInCertificate, Is.EqualTo("{servername}"), "Unexpected Host Name in Certificate value");
|
Assert.That(details.HostNameInCertificate, Is.EqualTo("{servername}"), "Unexpected Host Name in Certificate value");
|
||||||
Assert.That(details.ConnectTimeout, Is.EqualTo(30), "Unexpected Connect Timeout value");
|
Assert.That(details.ConnectTimeout, Is.EqualTo(30), "Unexpected Connect Timeout value");
|
||||||
|
Assert.That(details.CommandTimeout, Is.EqualTo(30), "Unexpected CommandTimeout Timeout value");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -1711,7 +1713,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Connection
|
|||||||
// If we make a connection to a live database
|
// If we make a connection to a live database
|
||||||
ConnectionService service = ConnectionService.Instance;
|
ConnectionService service = ConnectionService.Instance;
|
||||||
|
|
||||||
var connectionString = "Server=tcp:{servername},1433;Initial Catalog={databasename};Persist Security Info=False;User ID={your_username};Password={your_password};MultipleActiveResultSets=False;Encrypt=Strict;TrustServerCertificate=False;Connection Timeout=30;HostNameInCertificate={servername}";
|
var connectionString = "Server=tcp:{servername},1433;Initial Catalog={databasename};Persist Security Info=False;User ID={your_username};Password={your_password};MultipleActiveResultSets=False;Encrypt=Strict;TrustServerCertificate=False;Connection Timeout=30;Command Timeout=30;HostNameInCertificate={servername}";
|
||||||
|
|
||||||
var details = service.ParseConnectionString(connectionString);
|
var details = service.ParseConnectionString(connectionString);
|
||||||
Assert.That(details.ServerName, Is.EqualTo("tcp:{servername},1433"), "Unexpected server name");
|
Assert.That(details.ServerName, Is.EqualTo("tcp:{servername},1433"), "Unexpected server name");
|
||||||
@@ -1724,6 +1726,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Connection
|
|||||||
Assert.That(details.TrustServerCertificate, Is.False, "Unexpected database name value");
|
Assert.That(details.TrustServerCertificate, Is.False, "Unexpected database name value");
|
||||||
Assert.That(details.HostNameInCertificate, Is.EqualTo("{servername}"), "Unexpected Host Name in Certificate value");
|
Assert.That(details.HostNameInCertificate, Is.EqualTo("{servername}"), "Unexpected Host Name in Certificate value");
|
||||||
Assert.That(details.ConnectTimeout, Is.EqualTo(30), "Unexpected Connect Timeout value");
|
Assert.That(details.ConnectTimeout, Is.EqualTo(30), "Unexpected Connect Timeout value");
|
||||||
|
Assert.That(details.CommandTimeout, Is.EqualTo(30), "Unexpected Command Timeout value");
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
|||||||
Reference in New Issue
Block a user