Enabling database properties general tab with real time values from SMO (#2093)

* initial commit with all required db handler and props, also getting the data from ADS

* database properties view updated

* Delete Microsoft.SqlTools.ServiceLayer.sln

This file should be ignored

* Removed unwanted file

* Using DatabaseHandler for properties as one handler per object

* removed unused and unnecessary changes

* minimal updates

* moving type conversion to UI side, properties with original types.

* conversion number fixed

* Adding Localized strings

* using existing objectUrn logic to get the smo object

* Adding Integration tests for database properties verification

* refactoring

* updating test
This commit is contained in:
Sai Avishkar Sreerama
2023-06-21 19:41:18 -05:00
committed by GitHub
parent 532f7b0912
commit 5c7dae40e6
9 changed files with 141 additions and 15 deletions

View File

@@ -12429,6 +12429,14 @@ namespace Microsoft.SqlTools.ServiceLayer
}
}
public static string databaseBackupDate_None
{
get
{
return Keys.GetString(Keys.databaseBackupDate_None);
}
}
public static string BasicAzureEdition
{
get
@@ -17847,6 +17855,9 @@ namespace Microsoft.SqlTools.ServiceLayer
public const string prototype_file_noApplicableFileGroup = "prototype_file_noApplicableFileGroup";
public const string databaseBackupDate_None = "databaseBackupDate_None";
public const string BasicAzureEdition = "BasicAzureEdition";

View File

@@ -6756,6 +6756,10 @@ The Query Processor estimates that implementing the following index could improv
<value>No Applicable Filegroup</value>
<comment></comment>
</data>
<data name="databaseBackupDate_None" xml:space="preserve">
<value>None</value>
<comment></comment>
</data>
<data name="BasicAzureEdition" xml:space="preserve">
<value>Basic</value>
<comment></comment>

View File

@@ -2800,6 +2800,7 @@ general_containmentType_None = None
general_containmentType_Partial = Partial
filegroups_filestreamFiles = FILESTREAM Files
prototype_file_noApplicableFileGroup = No Applicable Filegroup
databaseBackupDate_None = None
############################################################################
# Azure SQL DB

View File

@@ -8316,6 +8316,11 @@ The Query Processor estimates that implementing the following index could improv
<target state="new">Hyperscale</target>
<note></note>
</trans-unit>
<trans-unit id="databaseBackupDate_None">
<source>None</source>
<target state="new">None</target>
<note></note>
</trans-unit>
</body>
</file>
</xliff>

View File

@@ -98,7 +98,9 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
public override Task<InitializeViewResult> InitializeObjectView(InitializeViewRequestParams requestParams)
{
// create a default data context and database object
using (var dataContainer = CreateDatabaseDataContainer(requestParams.ConnectionUri, ConfigAction.Create))
ConfigAction configAction = requestParams.IsNewObject ? ConfigAction.Create : ConfigAction.Update;
var databaseInfo = !requestParams.IsNewObject ? new DatabaseInfo() { Name = requestParams.Database } : null;
using (var dataContainer = CreateDatabaseDataContainer(requestParams, configAction, databaseInfo))
{
if (dataContainer.Server == null)
{
@@ -120,6 +122,27 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
IsAzureDB = isAzureDB
};
// Collect the Database properties information
if (!requestParams.IsNewObject)
{
var smoDatabase = dataContainer.SqlDialogSubject as Database;
databaseViewInfo.ObjectInfo = new DatabaseInfo()
{
Name = smoDatabase.Name,
CollationName = smoDatabase.Collation,
DateCreated = smoDatabase.CreateDate.ToString(),
LastDatabaseBackup = smoDatabase.LastBackupDate == DateTime.MinValue ? SR.databaseBackupDate_None : smoDatabase.LastBackupDate.ToString(),
LastDatabaseLogBackup = smoDatabase.LastLogBackupDate == DateTime.MinValue ? SR.databaseBackupDate_None : smoDatabase.LastLogBackupDate.ToString(),
MemoryAllocatedToMemoryOptimizedObjectsInMb = DatabaseUtils.ConvertKbtoMb(smoDatabase.MemoryAllocatedToMemoryOptimizedObjectsInKB),
MemoryUsedByMemoryOptimizedObjectsInMb = DatabaseUtils.ConvertKbtoMb(smoDatabase.MemoryUsedByMemoryOptimizedObjectsInKB),
NumberOfUsers = smoDatabase.Users.Count,
Owner = smoDatabase.Owner,
SizeInMb = smoDatabase.Size,
SpaceAvailableInMb = DatabaseUtils.ConvertKbtoMb(smoDatabase.SpaceAvailable),
Status = smoDatabase.Status.ToString()
};
}
// azure sql db doesn't have a sysadmin fixed role
var compatibilityLevelEnabled = !isDw && (dataContainer.LoggedInUserIsSysadmin || isAzureDB);
if (isAzureDB)
@@ -200,7 +223,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
public override Task Save(DatabaseViewContext context, DatabaseInfo obj)
{
ConfigureDatabase(
context.Parameters.ConnectionUri,
context.Parameters,
obj,
context.Parameters.IsNewObject ? ConfigAction.Create : ConfigAction.Update,
RunType.RunNow);
@@ -210,39 +233,37 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
public override Task<string> Script(DatabaseViewContext context, DatabaseInfo obj)
{
var script = ConfigureDatabase(
context.Parameters.ConnectionUri,
context.Parameters,
obj,
context.Parameters.IsNewObject ? ConfigAction.Create : ConfigAction.Update,
RunType.ScriptToWindow);
return Task.FromResult(script);
}
private CDataContainer CreateDatabaseDataContainer(string connectionUri, ConfigAction configAction, DatabaseInfo? database = null)
private CDataContainer CreateDatabaseDataContainer(InitializeViewRequestParams requestParams, ConfigAction configAction, DatabaseInfo? database = null)
{
ConnectionInfo connectionInfo = this.GetConnectionInfo(connectionUri);
ConnectionInfo connectionInfo = this.GetConnectionInfo(requestParams.ConnectionUri);
CDataContainer dataContainer = CDataContainer.CreateDataContainer(connectionInfo, databaseExists: configAction != ConfigAction.Create);
if (dataContainer.Server == null)
{
throw new InvalidOperationException(serverNotExistsError);
}
string objectUrn = (configAction != ConfigAction.Create && database != null)
? string.Format(System.Globalization.CultureInfo.InvariantCulture,
"Server/Database[@Name='{0}']",
Urn.EscapeString(database.Name))
: string.Format(System.Globalization.CultureInfo.InvariantCulture,
"Server");
string objectUrn = configAction != ConfigAction.Create && database != null
? string.Format(System.Globalization.CultureInfo.InvariantCulture, "Server/Database[@Name='{0}']", Urn.EscapeString(database.Name))
: string.Format(System.Globalization.CultureInfo.InvariantCulture, "Server");
dataContainer.SqlDialogSubject = dataContainer.Server.GetSmoObject(objectUrn);
return dataContainer;
}
private string ConfigureDatabase(string connectionUri, DatabaseInfo database, ConfigAction configAction, RunType runType)
private string ConfigureDatabase(InitializeViewRequestParams requestParams, DatabaseInfo database, ConfigAction configAction, RunType runType)
{
if (database.Name == null)
{
throw new ArgumentException("Database name not provided.");
}
using (var dataContainer = CreateDatabaseDataContainer(connectionUri, configAction, database))
using (var dataContainer = CreateDatabaseDataContainer(requestParams, configAction, database))
{
if (dataContainer.Server == null)
{

View File

@@ -15,7 +15,15 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
public string? RecoveryModel { get; set; }
public string? CompatibilityLevel { get; set; }
public string? ContainmentType { get; set; }
public string? DateCreated { get; set; }
public string? LastDatabaseBackup { get; set; }
public string? LastDatabaseLogBackup { get; set; }
public double? MemoryAllocatedToMemoryOptimizedObjectsInMb { get; set; }
public double? MemoryUsedByMemoryOptimizedObjectsInMb { get; set; }
public int? NumberOfUsers { get; set; }
public double? SizeInMb { get; set; }
public double? SpaceAvailableInMb { get; set; }
public string? Status { get; set; }
public string? AzureBackupRedundancyLevel { get; set; }
public string? AzureServiceLevelObjective { get; set; }
public string? AzureEdition { get; set; }

View File

@@ -345,5 +345,15 @@ namespace Microsoft.SqlTools.ServiceLayer.Utility
return new string(nameChars);
}
private static readonly HashSet<char> illegalFilenameCharacters = new HashSet<char>(new char[] { '\\', '/', ':', '*', '?', '"', '<', '>', '|' });
/// <summary>
/// Converts value in KBs to MBs
/// </summary>
/// <param name="valueInKb">value in kilo bytes</param>
/// <returns>Returns as double type</returns>
public static double ConvertKbtoMb(double valueInKb)
{
return (Math.Round(valueInKb / 1024, 2));
}
}
}