mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-01-13 17:23:02 -05:00
handling offline and inassisable db in oe (#369)
* handling offline and inassisable db in oe
This commit is contained in:
BIN
bin/nuget/Microsoft.SqlServer.Smo.140.17055.0.nupkg
Normal file
BIN
bin/nuget/Microsoft.SqlServer.Smo.140.17055.0.nupkg
Normal file
Binary file not shown.
@@ -2333,6 +2333,14 @@ namespace Microsoft.SqlTools.ServiceLayer
|
||||
}
|
||||
}
|
||||
|
||||
public static string DatabaseNotAccessible
|
||||
{
|
||||
get
|
||||
{
|
||||
return Keys.GetString(Keys.DatabaseNotAccessible);
|
||||
}
|
||||
}
|
||||
|
||||
public static string ScriptingParams_ConnectionString_Property_Invalid
|
||||
{
|
||||
get
|
||||
@@ -4229,6 +4237,9 @@ namespace Microsoft.SqlTools.ServiceLayer
|
||||
public const string SystemVersioned_LabelPart = "SystemVersioned_LabelPart";
|
||||
|
||||
|
||||
public const string DatabaseNotAccessible = "DatabaseNotAccessible";
|
||||
|
||||
|
||||
public const string ScriptingParams_ConnectionString_Property_Invalid = "ScriptingParams_ConnectionString_Property_Invalid";
|
||||
|
||||
|
||||
|
||||
@@ -1339,6 +1339,10 @@
|
||||
<value>System-Versioned</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="DatabaseNotAccessible" xml:space="preserve">
|
||||
<value>The database {0} is not accessible.</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="ScriptingParams_ConnectionString_Property_Invalid" xml:space="preserve">
|
||||
<value>Error parsing ScriptingParams.ConnectionString property.</value>
|
||||
<comment></comment>
|
||||
|
||||
@@ -667,6 +667,8 @@ History_LabelPart = History
|
||||
|
||||
SystemVersioned_LabelPart = System-Versioned
|
||||
|
||||
DatabaseNotAccessible = The database {0} is not accessible.
|
||||
|
||||
|
||||
############################################################################
|
||||
# Scripting Service
|
||||
|
||||
@@ -2096,6 +2096,11 @@
|
||||
<target state="new">No Applicable Filegroup</target>
|
||||
<note></note>
|
||||
</trans-unit>
|
||||
<trans-unit id="DatabaseNotAccessible">
|
||||
<source>The database {0} is not accessible.</source>
|
||||
<target state="new">The database {0} is not accessible.</target>
|
||||
<note></note>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
@@ -37,6 +37,11 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes
|
||||
/// </summary>
|
||||
public abstract IEnumerable<NodeFilter> Filters { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The list of properties to be loaded with the object
|
||||
/// </summary>
|
||||
public abstract IEnumerable<NodeSmoProperty> SmoProperties { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns the node sub type if the object can have sub types otehr wise returns empty string
|
||||
/// </summary>
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes
|
||||
{
|
||||
/// <summary>
|
||||
/// Has information for SMO object properties to be loaded with the SMO object
|
||||
/// </summary>
|
||||
public class NodeSmoProperty
|
||||
{
|
||||
/// <summary>
|
||||
/// Property name
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
/// <summary>
|
||||
/// Indicates which platforms a filter is valid for
|
||||
/// </summary>
|
||||
public ValidForFlag ValidFor { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -286,7 +286,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes
|
||||
return Parent as T;
|
||||
}
|
||||
|
||||
protected void PopulateChildren(bool refresh, string name = null)
|
||||
protected virtual void PopulateChildren(bool refresh, string name = null)
|
||||
{
|
||||
Logger.Write(LogLevel.Verbose, string.Format(CultureInfo.InvariantCulture, "Populating oe node :{0}", this.GetNodePath()));
|
||||
Debug.Assert(IsAlwaysLeaf == false);
|
||||
@@ -331,7 +331,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(Exception ex)
|
||||
catch (Exception ex)
|
||||
{
|
||||
string error = string.Format(CultureInfo.InvariantCulture, "Failed populating oe children. error:{0} inner:{1} stacktrace:{2}",
|
||||
ex.Message, ex.InnerException != null ? ex.InnerException.Message : "", ex.StackTrace);
|
||||
|
||||
@@ -332,7 +332,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer
|
||||
|
||||
}
|
||||
|
||||
internal async Task<NodeInfo[]> ExpandNode(ObjectExplorerSession session, string nodePath, bool forceRefresh = false)
|
||||
internal async Task<ExpandResponse> ExpandNode(ObjectExplorerSession session, string nodePath, bool forceRefresh = false)
|
||||
{
|
||||
return await Task.Factory.StartNew(() =>
|
||||
{
|
||||
@@ -349,7 +349,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer
|
||||
nodes = node.Expand().Select(x => x.ToNodeInfo()).ToArray();
|
||||
}
|
||||
}
|
||||
return nodes;
|
||||
return new ExpandResponse { Nodes = nodes, ErrorMessage = node.ErrorMessage, SessionId = session.Uri, NodePath = nodePath };
|
||||
});
|
||||
}
|
||||
|
||||
@@ -383,7 +383,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer
|
||||
{
|
||||
// open connection based on request details
|
||||
ConnectionCompleteParams result = await connectionService.Connect(connectParams);
|
||||
connectionErrorMessage = result != null ? result.Messages : string.Empty;
|
||||
connectionErrorMessage = result != null ? $"{result.Messages} error code:{result.ErrorNumber}" : string.Empty;
|
||||
if (result != null && !string.IsNullOrEmpty(result.ConnectionId))
|
||||
{
|
||||
return result;
|
||||
@@ -463,16 +463,14 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer
|
||||
|
||||
private async Task ExpandNodeAsync(ObjectExplorerSession session, ExpandParams expandParams, CancellationToken cancellationToken, bool forceRefresh = false)
|
||||
{
|
||||
NodeInfo[] nodes = null;
|
||||
nodes = await ExpandNode(session, expandParams.NodePath, forceRefresh);
|
||||
ExpandResponse response = null;
|
||||
response = await ExpandNode(session, expandParams.NodePath, forceRefresh);
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
Logger.Write(LogLevel.Verbose, "OE expand canceled ");
|
||||
Logger.Write(LogLevel.Verbose, "OE expand canceled");
|
||||
}
|
||||
else
|
||||
{
|
||||
ExpandResponse response = CreateExpandResponse(session, expandParams);
|
||||
response.Nodes = nodes;
|
||||
await serviceHost.SendEvent(ExpandCompleteNotification.Type, response);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,10 @@
|
||||
//
|
||||
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using Microsoft.SqlServer.Management.Smo;
|
||||
using Microsoft.SqlTools.Utility;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
|
||||
{
|
||||
@@ -34,5 +37,38 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void PopulateChildren(bool refresh, string name = null)
|
||||
{
|
||||
SmoQueryContext context = this.GetContextAs<SmoQueryContext>();
|
||||
if (IsAccessible(context))
|
||||
{
|
||||
base.PopulateChildren(refresh, name);
|
||||
}
|
||||
else
|
||||
{
|
||||
ErrorMessage = string.Format(CultureInfo.InvariantCulture, SR.DatabaseNotAccessible, context.Database.Name);
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsAccessible(SmoQueryContext context)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (context == null || context.Database == null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return context.Database.IsAccessible;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return true;
|
||||
string error = string.Format(CultureInfo.InvariantCulture, "Failed to get IsAccessible. error:{0} inner:{1} stacktrace:{2}",
|
||||
ex.Message, ex.InnerException != null ? ex.InnerException.Message : "", ex.StackTrace);
|
||||
Logger.Write(LogLevel.Error, error);
|
||||
ErrorMessage = ex.Message;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,6 +84,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
|
||||
|
||||
IEnumerable<SmoQuerier> queriers = context.ServiceProvider.GetServices<SmoQuerier>(q => IsCompatibleQuerier(q));
|
||||
var filters = this.Filters.ToList();
|
||||
var smoProperties = this.SmoProperties.Where(p => (p.ValidFor == 0 || p.ValidFor.HasFlag(validForFlag))).Select(x => x.Name);
|
||||
if (!string.IsNullOrEmpty(name))
|
||||
{
|
||||
filters.Add(new NodeFilter
|
||||
@@ -98,7 +99,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
|
||||
string propertyFilter = GetProperyFilter(filters, querier.GetType(), validForFlag);
|
||||
try
|
||||
{
|
||||
var smoObjectList = querier.Query(context, propertyFilter, refresh).ToList();
|
||||
var smoObjectList = querier.Query(context, propertyFilter, refresh, smoProperties).ToList();
|
||||
foreach (var smoObject in smoObjectList)
|
||||
{
|
||||
if (smoObject == null)
|
||||
@@ -239,6 +240,14 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
|
||||
}
|
||||
}
|
||||
|
||||
public override IEnumerable<NodeSmoProperty> SmoProperties
|
||||
{
|
||||
get
|
||||
{
|
||||
return Enumerable.Empty<NodeSmoProperty>();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if any final validation of the object to be added passes, and false
|
||||
/// if validation fails. This provides a chance to filter specific items out of a list
|
||||
|
||||
@@ -6,14 +6,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using Microsoft.Data.Tools.DataSets;
|
||||
using Microsoft.SqlServer.Management.Common;
|
||||
using Microsoft.SqlServer.Management.Sdk.Sfc;
|
||||
using Microsoft.SqlServer.Management.Smo;
|
||||
using Microsoft.SqlTools.Extensibility;
|
||||
using Microsoft.SqlTools.Utility;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
|
||||
{
|
||||
@@ -33,7 +28,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
/// <returns></returns>
|
||||
public abstract IEnumerable<SqlSmoObject> Query(SmoQueryContext context, string filter, bool refresh);
|
||||
public abstract IEnumerable<SqlSmoObject> Query(SmoQueryContext context, string filter, bool refresh, IEnumerable<string> extraProperties);
|
||||
|
||||
internal IMultiServiceProvider ServiceProvider
|
||||
{
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -33,7 +33,6 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
|
||||
{
|
||||
XmlElement nodeElement = GetNodeElement(xmlFile, nodeName);
|
||||
IList<string> parents = GetParents(nodeElement, xmlFile, nodeName);
|
||||
string properties = GetProperties(nodeElement, xmlFile, nodeName);
|
||||
string nodeType = GetNodeType(nodeElement, nodeName);
|
||||
|
||||
string queryBaseClass = "SmoQuerier";
|
||||
@@ -51,7 +50,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
|
||||
WriteLine("");
|
||||
|
||||
// Query impl
|
||||
WriteLine("public override IEnumerable<SqlSmoObject> Query(SmoQueryContext context, string filter, bool refresh)");
|
||||
WriteLine("public override IEnumerable<SqlSmoObject> Query(SmoQueryContext context, string filter, bool refresh, IEnumerable<string> extraProperties)");
|
||||
WriteLine("{");
|
||||
PushIndent(indent);
|
||||
|
||||
@@ -75,7 +74,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
|
||||
|
||||
if (IsCollection(nodeElement))
|
||||
{
|
||||
WriteLine(string.Format("retValue.InitializeCollection(filter, new string[] {{ {0} }});", properties));
|
||||
WriteLine(string.Format("retValue.ClearAndInitialize(filter, extraProperties);"));
|
||||
WriteLine(string.Format("return new SmoCollectionWrapper<{0}>(retValue).Where(c => PassesFinalFilters({1}, c));", nodeType, parentVar));
|
||||
}
|
||||
else
|
||||
@@ -214,22 +213,6 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
|
||||
return new string[] { "Database" };
|
||||
}
|
||||
|
||||
public static string GetProperties(XmlElement nodeElement, string xmlFile, string parentName)
|
||||
{
|
||||
var propertiesAttr = nodeElement.GetAttribute("Properties");
|
||||
string result = string.Empty;
|
||||
if (!string.IsNullOrEmpty(propertiesAttr))
|
||||
{
|
||||
var properties = propertiesAttr.Split(';');
|
||||
foreach (var item in properties)
|
||||
{
|
||||
result = result + (string.IsNullOrEmpty(result) ? "" : ",") + "\"" + item + "\"";
|
||||
}
|
||||
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static List<XmlElement> GetChildren(string xmlFile, string parentName, string childNode)
|
||||
{
|
||||
XmlElement nodeElement = GetNodeElement(xmlFile, parentName);
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
|
||||
<Node Name="SqlErrorMessage" Type="UserDefinedMessage" Parent="Server" />
|
||||
|
||||
<Node Name="SqlTable" Parent="Database" Properties="IsSystemVersioned" />
|
||||
<Node Name="SqlTable" Parent="Database" />
|
||||
<Node Name="SqlHistoryTable" Type="Table" Parent="Table" >
|
||||
<NavigationPath Parent="Table" Type="Table" Field="Parent.Tables" FieldForUrn="Parent" />
|
||||
</Node>
|
||||
|
||||
@@ -14,10 +14,17 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
|
||||
{
|
||||
public override string GetNodeCustomName(object smoObject, SmoQueryContext smoContext)
|
||||
{
|
||||
Table table = smoObject as Table;
|
||||
if (table != null && table.IsSystemVersioned)
|
||||
try
|
||||
{
|
||||
return $"{table.Schema}.{table.Name} ({SR.SystemVersioned_LabelPart})";
|
||||
Table table = smoObject as Table;
|
||||
if (table != null && table.IsSystemVersioned)
|
||||
{
|
||||
return $"{table.Schema}.{table.Name} ({SR.SystemVersioned_LabelPart})";
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
//Ignore the exception and just not change create custom name
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
|
||||
@@ -75,6 +75,9 @@
|
||||
<Value>TableTemporalType.SystemVersioned</Value>
|
||||
</Filter>
|
||||
</Filters>
|
||||
<Properties>
|
||||
<Property Name="IsSystemVersioned" ValidFor="Sql2016|Sql2017|AzureV12"/>
|
||||
</Properties>
|
||||
<Child Name="SystemTables" IsSystemObject="1"/>
|
||||
<!--
|
||||
<Child Name="FileTables"/>
|
||||
|
||||
@@ -764,6 +764,20 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
|
||||
}
|
||||
}
|
||||
|
||||
public override IEnumerable<NodeSmoProperty> SmoProperties
|
||||
{
|
||||
get
|
||||
{
|
||||
var properties = new List<NodeSmoProperty>();
|
||||
properties.Add(new NodeSmoProperty
|
||||
{
|
||||
Name = "IsSystemVersioned",
|
||||
ValidFor = ValidForFlag.Sql2016|ValidForFlag.AzureV12
|
||||
});
|
||||
return properties;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnExpandPopulateFolders(IList<TreeNode> currentChildren, TreeNode parent)
|
||||
{
|
||||
currentChildren.Add(new FolderNode {
|
||||
|
||||
@@ -107,9 +107,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
|
||||
|
||||
List<XmlElement> children = GetChildren(xmlFile, type);
|
||||
List<XmlElement> filters = GetNodeFilters(xmlFile, type);
|
||||
|
||||
|
||||
|
||||
List<XmlElement> smoProperties = GetNodeSmoProperties(xmlFile, type);
|
||||
|
||||
if (filters.Count > 0)
|
||||
{
|
||||
@@ -180,6 +178,43 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (smoProperties.Count > 0)
|
||||
{
|
||||
WriteLine("");
|
||||
WriteLine(" public override IEnumerable<NodeSmoProperty> SmoProperties");
|
||||
WriteLine(" {");
|
||||
WriteLine(" get");
|
||||
WriteLine(" {");
|
||||
|
||||
WriteLine(" var properties = new List<NodeSmoProperty>();");
|
||||
foreach (var smoPropertiy in smoProperties)
|
||||
{
|
||||
var propertyName = smoPropertiy.GetAttribute("Name");
|
||||
var validFor = smoPropertiy.GetAttribute("ValidFor");
|
||||
|
||||
|
||||
|
||||
|
||||
WriteLine(" properties.Add(new NodeSmoProperty");
|
||||
WriteLine(" {");
|
||||
WriteLine(string.Format(" Name = \"{0}\",", propertyName));
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(validFor))
|
||||
{
|
||||
WriteLine(string.Format(" ValidFor = {0}", GetValidForFlags(validFor)));
|
||||
}
|
||||
WriteLine(" });");
|
||||
|
||||
|
||||
}
|
||||
|
||||
WriteLine(" return properties;");
|
||||
WriteLine(" }");
|
||||
WriteLine(" }");
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (children.Count > 0)
|
||||
{
|
||||
@@ -483,6 +518,26 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
|
||||
}
|
||||
return retElements;
|
||||
}
|
||||
|
||||
|
||||
public static List<XmlElement> GetNodeSmoProperties(string xmlFile, string parentName)
|
||||
{
|
||||
XmlElement nodeElement = GetNodeElement(xmlFile, parentName);
|
||||
XmlDocument doc = new XmlDocument();
|
||||
doc.Load(xmlFile);
|
||||
|
||||
List<XmlElement> retElements = new List<XmlElement>();
|
||||
XmlNodeList nodeList = doc.SelectNodes(string.Format("/ServerExplorerTree/Node[@Name='{0}']/Properties/Property", parentName));
|
||||
foreach (var item in nodeList)
|
||||
{
|
||||
XmlElement itemAsElement = item as XmlElement;
|
||||
if (itemAsElement != null)
|
||||
{
|
||||
retElements.Add(itemAsElement);
|
||||
}
|
||||
}
|
||||
return retElements;
|
||||
}
|
||||
|
||||
public static List<XmlElement> GetNodeFilterValues(string xmlFile, string parentName, string filterProperty)
|
||||
{
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
"Newtonsoft.Json": "9.0.1",
|
||||
"System.Data.Common": "4.1.0",
|
||||
"System.Data.SqlClient": "4.4.0-sqltools-24613-04",
|
||||
"Microsoft.SqlServer.Smo": "140.17054.0",
|
||||
"Microsoft.SqlServer.Smo": "140.17055.0",
|
||||
"Microsoft.SqlServer.Management.SqlScriptPublishModel": "140.17049.0",
|
||||
"System.Security.SecureString": "4.0.0",
|
||||
"System.Collections.Specialized": "4.0.1",
|
||||
|
||||
@@ -61,11 +61,11 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.ObjectExplorer
|
||||
string databaseName = "tempdb";
|
||||
await RunTest(databaseName, query, "TepmDb", async (testDbName, session) =>
|
||||
{
|
||||
var serverChildren = await _service.ExpandNode(session, session.Root.GetNodePath());
|
||||
var serverChildren = (await _service.ExpandNode(session, session.Root.GetNodePath())).Nodes;
|
||||
var securityNode = serverChildren.FirstOrDefault(x => x.Label == SR.SchemaHierarchy_Security);
|
||||
var securityChildren = await _service.ExpandNode(session, securityNode.NodePath);
|
||||
var securityChildren = (await _service.ExpandNode(session, securityNode.NodePath)).Nodes;
|
||||
var loginsNode = securityChildren.FirstOrDefault(x => x.Label == SR.SchemaHierarchy_Logins);
|
||||
var loginsChildren = await _service.ExpandNode(session, loginsNode.NodePath);
|
||||
var loginsChildren = (await _service.ExpandNode(session, loginsNode.NodePath)).Nodes;
|
||||
var login = loginsChildren.FirstOrDefault(x => x.Label == "OEServerLogin");
|
||||
Assert.NotNull(login);
|
||||
|
||||
@@ -97,12 +97,12 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.ObjectExplorer
|
||||
string databaseName = "tempdb";
|
||||
await RunTest(databaseName, query, "TepmDb", async (testDbName, session) =>
|
||||
{
|
||||
var serverChildren = await _service.ExpandNode(session, session.Root.GetNodePath());
|
||||
var serverChildren = (await _service.ExpandNode(session, session.Root.GetNodePath())).Nodes;
|
||||
var serverObjectsNode = serverChildren.FirstOrDefault(x => x.Label == SR.SchemaHierarchy_ServerObjects);
|
||||
var serverObjectsChildren = await _service.ExpandNode(session, serverObjectsNode.NodePath);
|
||||
var serverObjectsChildren = (await _service.ExpandNode(session, serverObjectsNode.NodePath)).Nodes;
|
||||
var triggersNode = serverObjectsChildren.FirstOrDefault(x => x.Label == SR.SchemaHierarchy_Triggers);
|
||||
var triggersChildren = await _service.ExpandNode(session, triggersNode.NodePath);
|
||||
var trigger = triggersChildren.FirstOrDefault(x => x.Label == "OE_ddl_trig_database");
|
||||
var trigger = triggersChildren.Nodes.FirstOrDefault(x => x.Label == "OE_ddl_trig_database");
|
||||
Assert.NotNull(trigger);
|
||||
|
||||
Assert.True(trigger.NodeStatus == "Disabled");
|
||||
@@ -130,18 +130,36 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.ObjectExplorer
|
||||
await RunTest(databaseName, query, "TestDb", async (testDbName, session) =>
|
||||
{
|
||||
var tablesNode = await FindNodeByLabel(session.Root.ToNodeInfo(), session, SR.SchemaHierarchy_Tables);
|
||||
var tableChildren = await _service.ExpandNode(session, tablesNode.NodePath);
|
||||
var tableChildren = (await _service.ExpandNode(session, tablesNode.NodePath)).Nodes;
|
||||
string dropTableScript = "Drop Table t1";
|
||||
Assert.True(tableChildren.Any(t => t.Label == "dbo.t1"));
|
||||
await TestServiceProvider.Instance.RunQueryAsync(TestServerType.OnPrem, testDbName, dropTableScript);
|
||||
tableChildren = await _service.ExpandNode(session, tablesNode.NodePath);
|
||||
tableChildren = (await _service.ExpandNode(session, tablesNode.NodePath)).Nodes;
|
||||
Assert.True(tableChildren.Any(t => t.Label == "dbo.t1"));
|
||||
tableChildren = await _service.ExpandNode(session, tablesNode.NodePath, true);
|
||||
tableChildren = (await _service.ExpandNode(session, tablesNode.NodePath, true)).Nodes;
|
||||
Assert.False(tableChildren.Any(t => t.Label == "dbo.t1"));
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a test database with prefix (OfflineDb). Create an oe session for master db and expand the new test db.
|
||||
/// The expand should return an error that says database if offline
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public async void ExpandOfflineDatabaseShouldReturnError()
|
||||
{
|
||||
var query = "ALTER DATABASE {0} SET OFFLINE WITH ROLLBACK IMMEDIATE";
|
||||
string databaseName = "master";
|
||||
|
||||
await RunTest(databaseName, query, "OfflineDb", async (testDbName, session) =>
|
||||
{
|
||||
var databaseNode = await ExpandServerNodeAndVerifyDatabaseHierachy(testDbName, session);
|
||||
var response = await _service.ExpandNode(session, databaseNode.NodePath);
|
||||
Assert.True(response.ErrorMessage.Contains(string.Format(CultureInfo.InvariantCulture, SR.DatabaseNotAccessible, testDbName)));
|
||||
});
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async void RefreshShouldCleanTheCache()
|
||||
{
|
||||
@@ -161,7 +179,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.ObjectExplorer
|
||||
var tableChildren = await _service.ExpandNode(session, tablesNode.NodePath);
|
||||
|
||||
//Expanding the tables return t1
|
||||
Assert.True(tableChildren.Any(t => t.Label == "dbo.t1"));
|
||||
Assert.True(tableChildren.Nodes.Any(t => t.Label == "dbo.t1"));
|
||||
|
||||
//Delete the table from db
|
||||
await TestServiceProvider.Instance.RunQueryAsync(TestServerType.OnPrem, testDbName, dropTableScript1);
|
||||
@@ -170,7 +188,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.ObjectExplorer
|
||||
tableChildren = await _service.ExpandNode(session, tablesNode.NodePath);
|
||||
|
||||
//Tables still includes t1
|
||||
Assert.True(tableChildren.Any(t => t.Label == "dbo.t1"));
|
||||
Assert.True(tableChildren.Nodes.Any(t => t.Label == "dbo.t1"));
|
||||
|
||||
//Verify the tables cache has items
|
||||
|
||||
@@ -197,7 +215,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.ObjectExplorer
|
||||
Assert.False(tablesCache.Any());
|
||||
|
||||
//Expand Tables
|
||||
var tableChildren = await _service.ExpandNode(session, tablePath, true);
|
||||
var tableChildren = (await _service.ExpandNode(session, tablePath, true)).Nodes;
|
||||
|
||||
//Verify table is not returned
|
||||
Assert.Equal(tableChildren.Any(t => t.Label == tableName), !deleted);
|
||||
@@ -238,6 +256,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.ObjectExplorer
|
||||
{
|
||||
databaseName = testDb.DatabaseName;
|
||||
}
|
||||
|
||||
var session = await CreateSession(databaseName);
|
||||
uri = session.Uri;
|
||||
await test(testDb.DatabaseName, session);
|
||||
@@ -293,7 +312,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.ObjectExplorer
|
||||
}
|
||||
|
||||
var databasesRoot = children.FirstOrDefault(x => x.NodeTypeId == NodeTypes.Databases);
|
||||
var databasesChildren = await _service.ExpandNode(session, databasesRoot.GetNodePath());
|
||||
var databasesChildren = (await _service.ExpandNode(session, databasesRoot.GetNodePath())).Nodes;
|
||||
var databases = databasesChildren.Where(x => x.NodeType == NodeTypes.Database.ToString());
|
||||
|
||||
//Verify the test databases is in the list
|
||||
@@ -303,7 +322,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.ObjectExplorer
|
||||
Assert.NotNull(systemDatabasesNode);
|
||||
|
||||
var systemDatabases = await _service.ExpandNode(session, systemDatabasesNode.NodePath);
|
||||
Assert.True(systemDatabases.Any(x => x.Label == "master"));
|
||||
Assert.True(systemDatabases.Nodes.Any(x => x.Label == "master"));
|
||||
|
||||
databaseNode = databases.FirstOrDefault(d => d.Label == databaseName);
|
||||
}
|
||||
@@ -312,7 +331,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.ObjectExplorer
|
||||
Assert.Equal(nodeInfo.NodeType, NodeTypes.Database.ToString());
|
||||
databaseNode = session.Root.ToNodeInfo();
|
||||
Assert.True(databaseNode.Label.Contains(databaseName));
|
||||
var databasesChildren = await _service.ExpandNode(session, databaseNode.NodePath);
|
||||
var databasesChildren = (await _service.ExpandNode(session, databaseNode.NodePath)).Nodes;
|
||||
Assert.False(databasesChildren.Any(x => x.Label == SR.SchemaHierarchy_SystemDatabases));
|
||||
|
||||
}
|
||||
@@ -328,7 +347,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.ObjectExplorer
|
||||
Assert.Equal(nodeInfo.IsLeaf, false);
|
||||
Assert.Equal(nodeInfo.NodeType, NodeTypes.Database.ToString());
|
||||
Assert.True(nodeInfo.Label.Contains(databaseName));
|
||||
var children = await _service.ExpandNode(session, session.Root.GetNodePath());
|
||||
var children = (await _service.ExpandNode(session, session.Root.GetNodePath())).Nodes;
|
||||
|
||||
//All server children should be folder nodes
|
||||
foreach (var item in children)
|
||||
@@ -350,7 +369,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.ObjectExplorer
|
||||
{
|
||||
if (node != null && !node.IsLeaf)
|
||||
{
|
||||
var children = await _service.ExpandNode(session, node.NodePath);
|
||||
var children = (await _service.ExpandNode(session, node.NodePath)).Nodes;
|
||||
foreach (var child in children)
|
||||
{
|
||||
VerifyMetadata(child);
|
||||
@@ -384,7 +403,8 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.ObjectExplorer
|
||||
}
|
||||
else if (node != null && !node.IsLeaf)
|
||||
{
|
||||
var children = await _service.ExpandNode(session, node.NodePath);
|
||||
var response = await _service.ExpandNode(session, node.NodePath);
|
||||
var children = response.Nodes;
|
||||
Assert.NotNull(children);
|
||||
foreach (var child in children)
|
||||
{
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
"System.Runtime.Serialization.Primitives": "4.1.1",
|
||||
"System.Data.Common": "4.1.0",
|
||||
"System.Data.SqlClient": "4.4.0-sqltools-24613-04",
|
||||
"Microsoft.SqlServer.Smo": "140.17054.0",
|
||||
"Microsoft.SqlServer.Smo": "140.17055.0",
|
||||
"System.Security.SecureString": "4.0.0",
|
||||
"System.Collections.Specialized": "4.0.1",
|
||||
"System.ComponentModel.TypeConverter": "4.1.0",
|
||||
|
||||
@@ -82,6 +82,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Common
|
||||
Console.WriteLine(string.Format(CultureInfo.InvariantCulture, "Test database '{0}' is created", databaseName));
|
||||
if (!string.IsNullOrEmpty(query))
|
||||
{
|
||||
query = string.Format(CultureInfo.InvariantCulture, query, databaseName);
|
||||
await TestServiceProvider.Instance.RunQueryAsync(serverType, databaseName, query);
|
||||
Console.WriteLine(string.Format(CultureInfo.InvariantCulture, "Test database '{0}' SQL types are created", databaseName));
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
"System.Runtime.Serialization.Primitives": "4.1.1",
|
||||
"System.Data.Common": "4.1.0",
|
||||
"System.Data.SqlClient": "4.4.0-sqltools-24613-04",
|
||||
"Microsoft.SqlServer.Smo": "140.17054.0",
|
||||
"Microsoft.SqlServer.Smo": "140.17055.0",
|
||||
"System.Security.SecureString": "4.0.0",
|
||||
"System.Collections.Specialized": "4.0.1",
|
||||
"System.ComponentModel.TypeConverter": "4.1.0",
|
||||
|
||||
@@ -7,6 +7,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.SqlClient;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using Microsoft.SqlServer.Management.Common;
|
||||
using Microsoft.SqlServer.Management.Smo;
|
||||
using Microsoft.SqlTools.Extensibility;
|
||||
@@ -399,7 +400,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.ObjectExplorer
|
||||
smoObjectMock.SetupGet(s => s.Name).Returns(dbName);
|
||||
|
||||
Mock<SqlDatabaseQuerier> querierMock = new Mock<SqlDatabaseQuerier>();
|
||||
querierMock.Setup(q => q.Query(It.IsAny<SmoQueryContext>(), It.IsAny<string>(), false))
|
||||
querierMock.Setup(q => q.Query(It.IsAny<SmoQueryContext>(), It.IsAny<string>(), false, It.IsAny<IEnumerable<string>>()))
|
||||
.Returns(smoObjectMock.Object.SingleItemAsEnumerable());
|
||||
|
||||
ServiceProvider.Register<SmoQuerier>(() => new[] { querierMock.Object });
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
"System.Runtime.Serialization.Primitives": "4.1.1",
|
||||
"System.Data.Common": "4.1.0",
|
||||
"System.Data.SqlClient": "4.4.0-sqltools-24613-04",
|
||||
"Microsoft.SqlServer.Smo": "140.17054.0",
|
||||
"Microsoft.SqlServer.Smo": "140.17055.0",
|
||||
"System.Security.SecureString": "4.0.0",
|
||||
"System.Collections.Specialized": "4.0.1",
|
||||
"System.ComponentModel.TypeConverter": "4.1.0",
|
||||
|
||||
Reference in New Issue
Block a user