mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-01-14 01:25:40 -05:00
265 lines
8.7 KiB
C#
265 lines
8.7 KiB
C#
//
|
|
// Copyright (c) Microsoft. All rights reserved.
|
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
//
|
|
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Xml.Serialization;
|
|
|
|
namespace Microsoft.Kusto.ServiceLayer.ObjectExplorer.DataSourceModel
|
|
{
|
|
public class NodePathGenerator
|
|
{
|
|
private static ServerExplorerTree TreeRoot { get; set; }
|
|
|
|
private static Dictionary<string, HashSet<Node>> NodeTypeDictionary { get; set; }
|
|
|
|
internal static void Initialize()
|
|
{
|
|
if (TreeRoot != null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var assembly = typeof(ObjectExplorerService).Assembly;
|
|
var resource = assembly.GetManifestResourceStream("Microsoft.Kusto.ServiceLayer.ObjectExplorer.DataSourceModel.TreeNodeDefinition.xml");
|
|
var serializer = new XmlSerializer(typeof(ServerExplorerTree));
|
|
NodeTypeDictionary = new Dictionary<string, HashSet<Node>>();
|
|
using (var reader = new StreamReader(resource))
|
|
{
|
|
TreeRoot = (ServerExplorerTree)serializer.Deserialize(reader);
|
|
}
|
|
|
|
foreach (var node in TreeRoot.Nodes)
|
|
{
|
|
var containedType = node.ContainedType();
|
|
if (containedType != null && node.Label() != string.Empty)
|
|
{
|
|
if (!NodeTypeDictionary.ContainsKey(containedType))
|
|
{
|
|
NodeTypeDictionary.Add(containedType, new HashSet<Node>());
|
|
}
|
|
NodeTypeDictionary.GetValueOrDefault(containedType).Add(node);
|
|
}
|
|
}
|
|
var serverNode = TreeRoot.Nodes.FirstOrDefault(node => node.Name == "Server");
|
|
var serverSet = new HashSet<Node>();
|
|
serverSet.Add(serverNode);
|
|
NodeTypeDictionary.Add("Server", serverSet);
|
|
}
|
|
|
|
internal static HashSet<string> FindNodePaths(ObjectExplorerSession objectExplorerSession, string typeName, string schema, string name, string databaseName, List<string> parentNames = null)
|
|
{
|
|
if (TreeRoot == null)
|
|
{
|
|
Initialize();
|
|
}
|
|
|
|
var returnSet = new HashSet<string>();
|
|
var matchingNodes = NodeTypeDictionary.GetValueOrDefault(typeName);
|
|
if (matchingNodes == null)
|
|
{
|
|
return returnSet;
|
|
}
|
|
|
|
var path = name;
|
|
if (schema != null)
|
|
{
|
|
path = schema + "." + path;
|
|
}
|
|
|
|
path ??= "";
|
|
|
|
foreach (var matchingNode in matchingNodes)
|
|
{
|
|
var paths = GenerateNodePath(objectExplorerSession, matchingNode, databaseName, parentNames, path);
|
|
foreach (var newPath in paths)
|
|
{
|
|
returnSet.Add(newPath);
|
|
}
|
|
}
|
|
return returnSet;
|
|
}
|
|
|
|
private static HashSet<string> GenerateNodePath(ObjectExplorerSession objectExplorerSession, Node currentNode, string databaseName, List<string> parentNames, string path)
|
|
{
|
|
if (parentNames != null)
|
|
{
|
|
parentNames = parentNames.ToList();
|
|
}
|
|
|
|
if (currentNode.Name == "Server" || (currentNode.Name == "Database" && objectExplorerSession.Root.NodeType == "Database"))
|
|
{
|
|
var serverRoot = objectExplorerSession.Root;
|
|
if (objectExplorerSession.Root.NodeType == "Database")
|
|
{
|
|
serverRoot = objectExplorerSession.Root.Parent;
|
|
path = objectExplorerSession.Root.NodeValue + (path.Length > 0 ? ("/" + path) : "");
|
|
}
|
|
|
|
path = serverRoot.NodeValue + (path.Length > 0 ? ("/" + path) : "");
|
|
var returnSet = new HashSet<string>();
|
|
returnSet.Add(path);
|
|
return returnSet;
|
|
}
|
|
|
|
var currentLabel = currentNode.Label();
|
|
if (currentLabel != string.Empty)
|
|
{
|
|
path = currentLabel + "/" + path;
|
|
var returnSet = new HashSet<string>();
|
|
foreach (var parent in currentNode.ParentNodes())
|
|
{
|
|
var paths = GenerateNodePath(objectExplorerSession, parent, databaseName, parentNames, path);
|
|
foreach (var newPath in paths)
|
|
{
|
|
returnSet.Add(newPath);
|
|
}
|
|
}
|
|
return returnSet;
|
|
}
|
|
else
|
|
{
|
|
var returnSet = new HashSet<string>();
|
|
if (currentNode.ContainedType() == "Database")
|
|
{
|
|
path = databaseName + "/" + path;
|
|
}
|
|
else if (parentNames != null && parentNames.Count > 0)
|
|
{
|
|
var parentName = parentNames.Last();
|
|
parentNames.RemoveAt(parentNames.Count - 1);
|
|
path = parentName + "/" + path;
|
|
}
|
|
else
|
|
{
|
|
return returnSet;
|
|
}
|
|
|
|
foreach (var parentNode in currentNode.ParentNodes())
|
|
{
|
|
var newPaths = GenerateNodePath(objectExplorerSession, parentNode, databaseName, parentNames, path);
|
|
foreach (var newPath in newPaths)
|
|
{
|
|
returnSet.Add(newPath);
|
|
}
|
|
}
|
|
|
|
return returnSet;
|
|
}
|
|
}
|
|
|
|
[XmlRoot("ServerExplorerTree")]
|
|
public class ServerExplorerTree
|
|
{
|
|
[XmlElement("Node", typeof(Node))]
|
|
public List<Node> Nodes { get; set; }
|
|
|
|
public Node GetNode(string name)
|
|
{
|
|
foreach (var node in this.Nodes)
|
|
{
|
|
if (node.Name == name)
|
|
{
|
|
return node;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public class Node
|
|
{
|
|
[XmlAttribute]
|
|
public string Name { get; set; }
|
|
|
|
[XmlAttribute]
|
|
public string LocLabel { get; set; }
|
|
|
|
[XmlAttribute]
|
|
public string TreeNode { get; set; }
|
|
|
|
[XmlAttribute]
|
|
public string NodeType { get; set; }
|
|
|
|
[XmlElement("Child", typeof(Child))]
|
|
public List<Child> Children { get; set; }
|
|
|
|
public HashSet<Node> ChildFolders()
|
|
{
|
|
var childSet = new HashSet<Node>();
|
|
foreach (var child in this.Children)
|
|
{
|
|
var node = TreeRoot.GetNode(child.Name);
|
|
if (node != null)
|
|
{
|
|
childSet.Add(node);
|
|
}
|
|
}
|
|
return childSet;
|
|
}
|
|
|
|
public string ContainedType()
|
|
{
|
|
if (this.TreeNode != null)
|
|
{
|
|
return this.TreeNode.Replace("TreeNode", "");
|
|
}
|
|
else if (this.NodeType != null)
|
|
{
|
|
return this.NodeType;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public Node ContainedObject()
|
|
{
|
|
var containedType = this.ContainedType();
|
|
if (containedType == null)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
var containedNode = TreeRoot.GetNode(containedType);
|
|
if (containedNode == this)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
return containedNode;
|
|
}
|
|
|
|
public string Label()
|
|
{
|
|
if (this.LocLabel.StartsWith("SR."))
|
|
{
|
|
return SR.Keys.GetString(this.LocLabel.Remove(0, 3));
|
|
}
|
|
|
|
return string.Empty;
|
|
}
|
|
|
|
public HashSet<Node> ParentNodes()
|
|
{
|
|
var parentNodes = new HashSet<Node>();
|
|
foreach (var node in TreeRoot.Nodes)
|
|
{
|
|
if (this != node && (node.ContainedType() == this.Name || node.Children.Any(child => child.Name == this.Name)))
|
|
{
|
|
parentNodes.Add(node);
|
|
}
|
|
}
|
|
return parentNodes;
|
|
}
|
|
}
|
|
|
|
public class Child
|
|
{
|
|
[XmlAttribute]
|
|
public string Name { get; set; }
|
|
}
|
|
}
|
|
} |