mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-01-15 17:23:32 -05:00
320 lines
9.4 KiB
Plaintext
320 lines
9.4 KiB
Plaintext
<#@ template debug="false" hostspecific="true" language="C#" #>
|
|
<#@ output extension=".cs" #>
|
|
<#@ assembly name="System.Xml.dll" #>
|
|
<#@ import namespace="System" #>
|
|
<#@ import namespace="System.Globalization" #>
|
|
<#@ import namespace="System.Text" #>
|
|
<#@ import namespace="System.Xml" #>
|
|
<#@ import namespace="System.Collections.Generic" #>
|
|
<#@ import namespace="System.IO" #>
|
|
// This file was generated by a T4 Template. Do not modify directly, instead update the SmoQueryModelDefinition.xml file
|
|
// and re-run the T4 template. This can be done in Visual Studio by right-click in and choosing "Run Custom Tool",
|
|
// or from the command-line on any platform by running "build.cmd -Target=CodeGen" or "build.sh -Target=CodeGen".
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Composition;
|
|
using System.Linq;
|
|
using Microsoft.SqlServer.Management.Smo;
|
|
using Microsoft.SqlServer.Management.Smo.Broker;
|
|
|
|
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
|
|
{
|
|
<#
|
|
var directory = Path.GetDirectoryName(Host.TemplateFile);
|
|
string xmlFile = Path.Combine(directory, "SmoQueryModelDefinition.xml");
|
|
|
|
/////////
|
|
// Now generate all the Query methods
|
|
/////////
|
|
var allNodes = GetNodes(xmlFile);
|
|
var indent = " ";
|
|
foreach (var nodeName in allNodes)
|
|
{
|
|
XmlElement nodeElement = GetNodeElement(xmlFile, nodeName);
|
|
IList<string> parents = GetParents(nodeElement, xmlFile, nodeName);
|
|
string nodeType = GetNodeType(nodeElement, nodeName);
|
|
var validFor = nodeElement.GetAttribute("ValidFor");
|
|
|
|
string queryBaseClass = "SmoQuerier";
|
|
PushIndent(indent);
|
|
WriteLine("");
|
|
WriteLine(string.Format("[Export(typeof({0}))]", queryBaseClass));
|
|
WriteLine(string.Format("internal partial class {0}Querier: {1}", nodeName, queryBaseClass));
|
|
WriteLine("{");
|
|
PushIndent(indent);
|
|
|
|
// Supported Types
|
|
WriteLine("Type[] supportedTypes = new Type[] { typeof("+ nodeType + ") };");
|
|
if (!string.IsNullOrWhiteSpace(validFor))
|
|
{
|
|
WriteLine("");
|
|
WriteLine(string.Format("public override ValidForFlag ValidFor {{ get {{ return {0}; }} }}", GetValidForFlags(validFor)));
|
|
WriteLine("");
|
|
}
|
|
|
|
WriteLine("");
|
|
WriteLine("public override Type[] SupportedObjectTypes { get { return supportedTypes; } }");
|
|
WriteLine("");
|
|
|
|
// Query impl
|
|
WriteLine("public override IEnumerable<SqlSmoObject> Query(SmoQueryContext context, string filter, bool refresh, IEnumerable<string> extraProperties)");
|
|
WriteLine("{");
|
|
PushIndent(indent);
|
|
|
|
// TODO Allow override of the navigation path
|
|
foreach(var parentType in parents)
|
|
{
|
|
string parentVar = string.Format("parent{0}", parentType);
|
|
WriteLine(string.Format("{0} {1} = context.Parent as {0};", parentType, parentVar));
|
|
WriteLine(string.Format("if ({0} != null)", parentVar));
|
|
WriteLine("{");
|
|
PushIndent(indent);
|
|
|
|
XmlElement navPathElement = GetNavPathElement(xmlFile, nodeName, parentType);
|
|
string navigationPath = GetNavigationPath(nodeElement, nodeName, navPathElement);
|
|
string subField = GetNavPathAttribute(navPathElement, "SubField");
|
|
string fieldType = GetNavPathAttribute(navPathElement, "FieldType");
|
|
|
|
|
|
WriteLine(string.Format("var retValue = {0}.{1};", parentVar, navigationPath));
|
|
WriteLine("if (retValue != null)");
|
|
WriteLine("{");
|
|
PushIndent(indent);
|
|
|
|
|
|
if (IsCollection(nodeElement))
|
|
{
|
|
WriteLine(string.Format("retValue.ClearAndInitialize(filter, extraProperties);"));
|
|
if (string.IsNullOrEmpty(subField) )
|
|
{
|
|
WriteLine(string.Format("return new SmoCollectionWrapper<{0}>(retValue).Where(c => PassesFinalFilters({1}, c));", nodeType, parentVar));
|
|
}
|
|
else
|
|
{
|
|
WriteLine(string.Format("List<{0}> subFieldResult = new List<{0}>();", nodeType));
|
|
WriteLine(string.Format("foreach({0} field in retValue)", fieldType));
|
|
WriteLine("{");
|
|
PushIndent(indent);
|
|
WriteLine(string.Format("{0} subField = field.{1};", nodeType, subField));
|
|
WriteLine(string.Format("if (subField != null)"));
|
|
WriteLine("{");
|
|
PushIndent(indent);
|
|
WriteLine(string.Format("subFieldResult.Add(subField);"));
|
|
PopIndent();
|
|
WriteLine("}");
|
|
PopIndent();
|
|
WriteLine("}");
|
|
WriteLine(string.Format("return subFieldResult.Where(c => PassesFinalFilters({1}, c));", nodeType, parentVar));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
WriteLine("if (refresh)");
|
|
WriteLine("{");
|
|
PushIndent(indent);
|
|
WriteLine(string.Format("{0}.{1}.Refresh();", parentVar, navigationPath));
|
|
PopIndent();
|
|
WriteLine("}");
|
|
WriteLine("return new SqlSmoObject[] { retValue };");
|
|
}
|
|
|
|
PopIndent();
|
|
WriteLine("}");
|
|
PopIndent();
|
|
WriteLine("}"); // close If
|
|
}
|
|
|
|
WriteLine("return Enumerable.Empty<SqlSmoObject>();");
|
|
|
|
PopIndent();
|
|
WriteLine("}"); // close Query method
|
|
PopIndent();
|
|
WriteLine("}"); // close Class
|
|
PopIndent();
|
|
}
|
|
#>
|
|
}
|
|
|
|
<#+
|
|
|
|
public static string[] GetNodes(string xmlFile)
|
|
{
|
|
List<string> typesList = new List<string>();
|
|
XmlDocument doc = new XmlDocument();
|
|
doc.Load(xmlFile);
|
|
XmlNodeList treeTypes = doc.SelectNodes("/SmoQueryModel/Node");
|
|
if (treeTypes != null)
|
|
{
|
|
foreach (var type in treeTypes)
|
|
{
|
|
XmlElement element = type as XmlElement;
|
|
if (element != null)
|
|
{
|
|
typesList.Add(element.GetAttribute("Name"));
|
|
}
|
|
}
|
|
}
|
|
return typesList.ToArray();
|
|
}
|
|
|
|
public static XmlElement GetNodeElement(string xmlFile, string nodeName)
|
|
{
|
|
XmlDocument doc = new XmlDocument();
|
|
doc.Load(xmlFile);
|
|
return (XmlElement)doc.SelectSingleNode(string.Format("/SmoQueryModel/Node[@Name='{0}']", nodeName));
|
|
}
|
|
|
|
public static XmlElement GetNavPathElement(string xmlFile, string nodeName, string parent)
|
|
{
|
|
XmlDocument doc = new XmlDocument();
|
|
doc.Load(xmlFile);
|
|
XmlElement navPathElement = (XmlElement)doc.SelectSingleNode(string.Format("/SmoQueryModel/Node[@Name='{0}']/NavigationPath[@Parent='{1}']", nodeName, parent));
|
|
|
|
return navPathElement;
|
|
}
|
|
|
|
public static string GetNavPathAttribute(XmlElement navPathElement, string attributeName)
|
|
{
|
|
return navPathElement == null ? null : navPathElement.GetAttribute(attributeName);
|
|
}
|
|
|
|
public static string GetNavigationPath(XmlElement nodeElement, string nodeName, XmlElement navPathElement)
|
|
{
|
|
string navPathField = GetNavPathAttribute(navPathElement, "Field");
|
|
if (!string.IsNullOrEmpty(navPathField))
|
|
{
|
|
return navPathField;
|
|
}
|
|
// else use pluralized type as this is the most common scenario
|
|
string nodeType = GetNodeType(nodeElement, nodeName);
|
|
|
|
string nodeTypeAccessor = IsCollection(nodeElement) ? string.Format("{0}s", nodeType) : nodeType;
|
|
return nodeTypeAccessor;
|
|
}
|
|
|
|
public static string GetNodeType(XmlElement nodeElement, string nodeName)
|
|
{
|
|
var type = nodeElement.GetAttribute("Type");
|
|
if (!string.IsNullOrEmpty(type))
|
|
{
|
|
return type;
|
|
}
|
|
// Otherwise assume the type is the node name without "Sql" at the start
|
|
var prefix = "Sql";
|
|
return nodeName.IndexOf(prefix) == 0 ? nodeName.Substring(prefix.Length) : nodeName;
|
|
}
|
|
|
|
public static bool IsCollection(XmlElement nodeElement)
|
|
{
|
|
var collection = nodeElement.GetAttribute("Collection");
|
|
bool result;
|
|
if (bool.TryParse(collection, out result))
|
|
{
|
|
return result;
|
|
}
|
|
// Default is true
|
|
return true;
|
|
}
|
|
|
|
public static IList<string> GetParents(XmlElement nodeElement, string xmlFile, string parentName)
|
|
{
|
|
var parentAttr = nodeElement.GetAttribute("Parent");
|
|
if (!string.IsNullOrEmpty(parentAttr))
|
|
{
|
|
return new string[] { parentAttr };
|
|
}
|
|
|
|
var parentNodes = GetChildren(xmlFile, parentName, "Parent");
|
|
if (parentNodes != null && parentNodes.Count > 0)
|
|
{
|
|
List<string> parents = new List<string>();
|
|
foreach(var node in parentNodes)
|
|
{
|
|
parents.Add(node.InnerText);
|
|
}
|
|
return parents;
|
|
}
|
|
|
|
// default to assuming a type is under Database
|
|
return new string[] { "Database" };
|
|
}
|
|
|
|
public static List<XmlElement> GetChildren(string xmlFile, string parentName, string childNode)
|
|
{
|
|
XmlElement nodeElement = GetNodeElement(xmlFile, parentName);
|
|
XmlDocument doc = new XmlDocument();
|
|
doc.Load(xmlFile);
|
|
|
|
List<XmlElement> retElements = new List<XmlElement>();
|
|
XmlNodeList nodeList = doc.SelectNodes(string.Format("/SmoQueryModel/Node[@Name='{0}']/{1}", parentName, childNode));
|
|
foreach (var item in nodeList)
|
|
{
|
|
XmlElement itemAsElement = item as XmlElement;
|
|
if (itemAsElement != null)
|
|
{
|
|
retElements.Add(itemAsElement);
|
|
}
|
|
}
|
|
return retElements;
|
|
}
|
|
|
|
public static string GetValidForFlags(string validForStr)
|
|
{
|
|
List<string> flags = new List<string>();
|
|
if (validForStr.Contains("Sql2005"))
|
|
{
|
|
flags.Add("ValidForFlag.Sql2005");
|
|
}
|
|
|
|
if (validForStr.Contains("Sql2008"))
|
|
{
|
|
flags.Add("ValidForFlag.Sql2008");
|
|
}
|
|
|
|
if (validForStr.Contains("Sql2012"))
|
|
{
|
|
flags.Add("ValidForFlag.Sql2012");
|
|
}
|
|
|
|
if (validForStr.Contains("Sql2014"))
|
|
{
|
|
flags.Add("ValidForFlag.Sql2014");
|
|
}
|
|
|
|
if (validForStr.Contains("Sql2016"))
|
|
{
|
|
flags.Add("ValidForFlag.Sql2016");
|
|
}
|
|
|
|
if (validForStr.Contains("Sql2017"))
|
|
{
|
|
flags.Add("ValidForFlag.Sql2017");
|
|
}
|
|
|
|
if (validForStr.Contains("AzureV12"))
|
|
{
|
|
flags.Add("ValidForFlag.AzureV12");
|
|
}
|
|
|
|
if (validForStr.Contains("AllOnPrem"))
|
|
{
|
|
flags.Add("ValidForFlag.AllOnPrem");
|
|
}
|
|
if (validForStr.Contains("AllAzure"))
|
|
{
|
|
flags.Add("ValidForFlag.AllAzure");
|
|
}
|
|
if (validForStr.Contains("NotSqlDw"))
|
|
{
|
|
flags.Add("ValidForFlag.NotSqlDw");
|
|
}
|
|
if (validForStr == "All")
|
|
{
|
|
flags.Add("ValidForFlag.All");
|
|
}
|
|
|
|
return string.Join("|", flags);
|
|
}
|
|
|
|
#> |