Moving out legacy schemas into their own folder (#1866)

This commit is contained in:
Aasim Khan
2023-02-17 14:31:25 -08:00
committed by GitHub
parent b3ae394fa6
commit e8d24f8e47
10 changed files with 342 additions and 3 deletions

View File

@@ -41,6 +41,18 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes
/// </summary>
public Type TypeToReverse { get; set; } = default!;
/// <summary>
/// Indicates if the filter is a "not" filter. Eg (not(@IsSystemObject = 0))
/// </summary>
public bool IsNotFilter { get; set; } = false;
/// <summary>
/// Indicates the type of the filter. It can be EQUALS, DATETIME, FALSE or CONTAINS
/// More information can be found here:
/// https://learn.microsoft.com/en-us/sql/powershell/query-expressions-and-uniform-resource-names?view=sql-server-ver16#examples
/// </summary>
public FilterType FilterType { get; set; } = FilterType.EQUALS;
/// <summary>
/// Returns true if the filter can be apply to the given type and Server type
/// </summary>
@@ -82,8 +94,35 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes
propertyValue = (int)Convert.ChangeType(value, Type);
}
string filterText = string.Empty;
switch (FilterType)
{
case FilterType.EQUALS:
filterText = $"@{Property} = {propertyValue}";
break;
case FilterType.DATETIME:
filterText = $"@{Property} = datetime({propertyValue})";
break;
case FilterType.CONTAINS:
filterText = $"contains(@{Property}, {propertyValue})";
break;
case FilterType.FALSE:
filterText = $"@{Property} = false()";
break;
case FilterType.ISNULL:
filterText = $"isnull(@{Property})";
break;
}
string orPrefix = filter.Length == 0 ? string.Empty : " or ";
filter.Append($"{orPrefix}@{Property} = {propertyValue}");
if (IsNotFilter)
{
filter.Append($"{orPrefix}not({filterText})");
}
else
{
filter.Append($"{orPrefix}{filterText}");
}
}
if (filter.Length != 0)
@@ -93,4 +132,13 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes
return string.Empty;
}
}
public enum FilterType
{
EQUALS,
DATETIME,
CONTAINS,
FALSE,
ISNULL
}
}

View File

@@ -22,6 +22,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes
Assemblies,
AsymmetricKeys,
BrokerPriorities,
BuiltInSchemas,
Certificates,
ColumnEncryptionKeys,
ColumnMasterKeys,

View File

@@ -680,6 +680,78 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
public override bool PutFoldersAfterNodes => true;
public override IEnumerable<string> ApplicableParents() { return new[] { nameof(NodeTypes.Database) }; }
public override IEnumerable<INodeFilter> Filters
{
get
{
var filters = new List<INodeFilter>();
filters.Add(new NodePropertyFilter
{
Property = "Name",
Type = typeof(string),
IsNotFilter = true,
Values = new List<object> { "db_accessadmin" },
});
filters.Add(new NodePropertyFilter
{
Property = "Name",
Type = typeof(string),
IsNotFilter = true,
Values = new List<object> { "db_backupoperator" },
});
filters.Add(new NodePropertyFilter
{
Property = "Name",
Type = typeof(string),
IsNotFilter = true,
Values = new List<object> { "db_datareader" },
});
filters.Add(new NodePropertyFilter
{
Property = "Name",
Type = typeof(string),
IsNotFilter = true,
Values = new List<object> { "db_datawriter" },
});
filters.Add(new NodePropertyFilter
{
Property = "Name",
Type = typeof(string),
IsNotFilter = true,
Values = new List<object> { "db_ddladmin" },
});
filters.Add(new NodePropertyFilter
{
Property = "Name",
Type = typeof(string),
IsNotFilter = true,
Values = new List<object> { "db_denydatareader" },
});
filters.Add(new NodePropertyFilter
{
Property = "Name",
Type = typeof(string),
IsNotFilter = true,
Values = new List<object> { "db_denydatawriter" },
});
filters.Add(new NodePropertyFilter
{
Property = "Name",
Type = typeof(string),
IsNotFilter = true,
Values = new List<object> { "db_owner" },
});
filters.Add(new NodePropertyFilter
{
Property = "Name",
Type = typeof(string),
IsNotFilter = true,
Values = new List<object> { "db_securityadmin" },
});
return filters;
}
}
protected override void OnExpandPopulateFolders(IList<TreeNode> currentChildren, TreeNode parent)
{
if (!WorkspaceService<SqlToolsSettings>.Instance.CurrentSettings.SqlTools.ObjectExplorer.GroupBySchema)
@@ -708,6 +780,15 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
IsSystemObject = false,
ValidFor = ValidForFlag.AllOnPrem|ValidForFlag.AzureV12,
SortPriority = SmoTreeNode.NextSortPriority,
});
}
if (WorkspaceService<SqlToolsSettings>.Instance.CurrentSettings.SqlTools.ObjectExplorer.GroupBySchema)
{
currentChildren.Add(new FolderNode {
NodeValue = SR.SchemaHierarchy_BuiltInSchema,
NodeTypeId = NodeTypes.BuiltInSchemas,
IsSystemObject = false,
SortPriority = SmoTreeNode.NextSortPriority,
});
}
currentChildren.Add(new FolderNode {
@@ -767,6 +848,96 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
}
}
[Export(typeof(ChildFactory))]
[Shared]
internal partial class BuiltInSchemasChildFactory : SmoChildFactoryBase
{
public override IEnumerable<string> ApplicableParents() { return new[] { nameof(NodeTypes.BuiltInSchemas) }; }
public override IEnumerable<INodeFilter> Filters
{
get
{
var filters = new List<INodeFilter>();
filters.Add(new NodeOrFilter
{
FilterList = new List<NodePropertyFilter> {
new NodePropertyFilter
{
Property = "Name",
Type = typeof(string),
Values = new List<object> { "db_accessadmin" },
},
new NodePropertyFilter
{
Property = "Name",
Type = typeof(string),
Values = new List<object> { "db_backupoperator" },
},
new NodePropertyFilter
{
Property = "Name",
Type = typeof(string),
Values = new List<object> { "db_datareader" },
},
new NodePropertyFilter
{
Property = "Name",
Type = typeof(string),
Values = new List<object> { "db_datawriter" },
},
new NodePropertyFilter
{
Property = "Name",
Type = typeof(string),
Values = new List<object> { "db_ddladmin" },
},
new NodePropertyFilter
{
Property = "Name",
Type = typeof(string),
Values = new List<object> { "db_denydatareader" },
},
new NodePropertyFilter
{
Property = "Name",
Type = typeof(string),
Values = new List<object> { "db_denydatawriter" },
},
new NodePropertyFilter
{
Property = "Name",
Type = typeof(string),
Values = new List<object> { "db_owner" },
},
new NodePropertyFilter
{
Property = "Name",
Type = typeof(string),
Values = new List<object> { "db_securityadmin" },
},
}
});
return filters;
}
}
internal override Type[] ChildQuerierTypes
{
get
{
return new [] { typeof(SqlSchemaQuerier), };
}
}
public override TreeNode CreateChild(TreeNode parent, object context)
{
var child = new ExpandableSchemaTreeNode();
InitializeChild(parent, child, context);
return child;
}
}
[Export(typeof(ChildFactory))]
[Shared]
internal partial class ExpandableSchemaChildFactory : SmoChildFactoryBase

View File

@@ -621,6 +621,8 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
var propertyType = filter.GetAttribute("Type");
var propertyValue = filter.GetAttribute("Value");
var validFor = filter.GetAttribute("ValidFor");
var filterType = filter.GetAttribute("FilterType");
var isNotFiler = filter.GetAttribute("IsNotFilter");
var typeToReverse = filter.GetAttribute("TypeToReverse");
List<XmlElement> filterValues = GetNodeFilterValues(xmlFile, parentName, propertyName, orFilter);
@@ -637,9 +639,24 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
{
WriteLine(indent + " ValidFor = {0},", GetValidForFlags(validFor));
}
if (!string.IsNullOrWhiteSpace(filterType))
{
WriteLine(indent + " FilterType = FilterType.{0},", filterType.ToUpper());
}
if (!string.IsNullOrWhiteSpace(isNotFiler))
{
WriteLine(indent + " IsNotFilter = {0},", isNotFiler);
}
if (propertyValue != null && (filterValues == null || filterValues.Count == 0))
{
WriteLine(indent + " Values = new List<object> {{ {0} }},", propertyValue);
if (propertyType.Equals("string"))
{
WriteLine(indent + " Values = new List<object> {{ \"{0}\" }},", propertyValue);
}
else
{
WriteLine(indent + " Values = new List<object> {{ {0} }},", propertyValue);
}
}
if (filterValues != null && filterValues.Count > 0)
{
@@ -650,7 +667,14 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
{
string separator = (i != filterValues.Count - 1) ? "," : "";
var filterValue = filterValues[i];
WriteLine(indent + " {{ {0} }}{1}", filterValue.InnerText, separator);
if(propertyType.Equals("string"))
{
WriteLine(indent + " {{ \"{0}\" }}{1}", filterValue.InnerText, separator);
}
else
{
WriteLine(indent + " {{ {0} }}{1}", filterValue.InnerText, separator);
}
}
WriteLine(indent + " }");

View File

@@ -64,9 +64,26 @@
<Node Name="Database" LocLabel="string.Empty" Image="Database" BaseClass="ModelBased" NodeType="Database" IsAsyncLoad="" Strategy="CreateModel" TreeNode="ExpandableSchemaTreeNode" PutFoldersAfterNodes="true">
<ConditionalChildQuerierType Name="SqlSchema" SettingsFlag="GroupBySchema"/>
<Filters>
<!--
Excluding built-in schemas for backward compatibility from the database node and moving them to legacy schema folder.
The list of schemas was obtained from:
https://learn.microsoft.com/en-us/sql/relational-databases/security/authentication-access/ownership-and-user-schema-separation?view=sql-server-ver16#built-in-schemas-for-backward-compatibility
-->
<Filter Property="Name" Value="db_accessadmin" Type="string" IsNotFilter="true"/>
<Filter Property="Name" Value="db_backupoperator" Type="string" IsNotFilter="true"/>
<Filter Property="Name" Value="db_datareader" Type="string" IsNotFilter="true"/>
<Filter Property="Name" Value="db_datawriter" Type="string" IsNotFilter="true"/>
<Filter Property="Name" Value="db_ddladmin" Type="string" IsNotFilter="true"/>
<Filter Property="Name" Value="db_denydatareader" Type="string" IsNotFilter="true"/>
<Filter Property="Name" Value="db_denydatawriter" Type="string" IsNotFilter="true"/>
<Filter Property="Name" Value="db_owner" Type="string" IsNotFilter="true"/>
<Filter Property="Name" Value="db_securityadmin" Type="string" IsNotFilter="true"/>
</Filters>
<Child Name="Tables" SettingsFlag="!GroupBySchema"/>
<Child Name="Views" SettingsFlag="!GroupBySchema"/>
<Child Name="Synonyms" SettingsFlag="!GroupBySchema"/>
<Child Name="BuiltInSchemas" SettingsFlag="GroupBySchema"/>
<Child Name="Programmability"/>
<Child Name="ExternalResources"/>
<Child Name="ServiceBroker"/>
@@ -74,6 +91,22 @@
<Child Name="Security"/>
</Node>
<Node Name="BuiltInSchemas" LocLabel="SR.SchemaHierarchy_BuiltInSchema" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlSchema" TreeNode="ExpandableSchemaTreeNode">
<Filters>
<Or>
<Filter Property="Name" Value="db_accessadmin" Type="string" />
<Filter Property="Name" Value="db_backupoperator" Type="string" />
<Filter Property="Name" Value="db_datareader" Type="string"/>
<Filter Property="Name" Value="db_datawriter" Type="string"/>
<Filter Property="Name" Value="db_ddladmin" Type="string"/>
<Filter Property="Name" Value="db_denydatareader" Type="string"/>
<Filter Property="Name" Value="db_denydatawriter" Type="string"/>
<Filter Property="Name" Value="db_owner" Type="string"/>
<Filter Property="Name" Value="db_securityadmin" Type="string"/>
</Or>
</Filters>
</Node>
<Node Name="ExpandableSchema" LocLabel="string.empty" BaseClass="ModelBased" Strategy="CreateModel">
<Child Name="Tables"/>
<Child Name="Views"/>