mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-02-16 10:58:30 -05:00
@@ -0,0 +1,215 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.SqlTools.ServiceLayer.Connection;
|
||||
using Microsoft.SqlTools.ServiceLayer.Connection.Contracts;
|
||||
using Microsoft.SqlTools.ServiceLayer.IntegrationTests.Utility;
|
||||
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer;
|
||||
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Contracts;
|
||||
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes;
|
||||
using Microsoft.SqlTools.ServiceLayer.Test.Common;
|
||||
using Xunit;
|
||||
using static Microsoft.SqlTools.ServiceLayer.ObjectExplorer.ObjectExplorerService;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.ObjectExplorer
|
||||
{
|
||||
public class ObjectExplorerServiceTests
|
||||
{
|
||||
private ObjectExplorerService _service = TestServiceProvider.Instance.ObjectExplorerService;
|
||||
|
||||
[Fact]
|
||||
public async void CreateSessionAndExpandOnTheServerShouldReturnTheDatabases()
|
||||
{
|
||||
var query = "";
|
||||
string uri = "CreateSessionAndExpand";
|
||||
string databaseName = null;
|
||||
using (SqlTestDb testDb = SqlTestDb.CreateNew(TestServerType.OnPrem, false, databaseName, query, uri))
|
||||
{
|
||||
var session = await CreateSession(testDb.DatabaseName, uri);
|
||||
await CreateSessionAndDatabaseNode(testDb.DatabaseName, session);
|
||||
CancelConnection(uri);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<ObjectExplorerSession> CreateSession(string databaseName, string uri)
|
||||
{
|
||||
ConnectParams connectParams = TestServiceProvider.Instance.ConnectionProfileService.GetConnectionParameters(TestServerType.OnPrem, databaseName);
|
||||
ConnectionDetails details = connectParams.Connection;
|
||||
|
||||
return await _service.DoCreateSession(details, uri);
|
||||
}
|
||||
|
||||
private async Task<NodeInfo> CreateSessionAndDatabaseNode(string databaseName, ObjectExplorerSession session)
|
||||
{
|
||||
Assert.NotNull(session);
|
||||
Assert.NotNull(session.Root);
|
||||
NodeInfo nodeInfo = session.Root.ToNodeInfo();
|
||||
Assert.Equal(nodeInfo.IsLeaf, false);
|
||||
Assert.Equal(nodeInfo.NodeType, NodeTypes.ServerInstance.ToString());
|
||||
var children = session.Root.Expand();
|
||||
|
||||
//All server children should be folder nodes
|
||||
foreach (var item in children)
|
||||
{
|
||||
Assert.Equal(item.NodeType, "Folder");
|
||||
}
|
||||
|
||||
var databasesRoot = children.FirstOrDefault(x => x.NodeTypeId == NodeTypes.Databases);
|
||||
var databasesChildren = await _service.ExpandNode(session, databasesRoot.GetNodePath());
|
||||
var databases = databasesChildren.Where(x => x.NodeType == NodeTypes.DatabaseInstance.ToString());
|
||||
|
||||
//Verify the test databases is in the list
|
||||
Assert.NotNull(databases);
|
||||
var databaseNode = databases.FirstOrDefault(d => d.Label == databaseName);
|
||||
Assert.NotNull(databaseNode);
|
||||
return databaseNode;
|
||||
}
|
||||
|
||||
private void CancelConnection(string uri)
|
||||
{
|
||||
//ConnectionService.Instance.CancelConnect(new CancelConnectParams
|
||||
//{
|
||||
// OwnerUri = uri,
|
||||
// Type = ConnectionType.Default
|
||||
//});
|
||||
}
|
||||
|
||||
private async Task ExpandTree(NodeInfo node, ObjectExplorerSession session)
|
||||
{
|
||||
if(node != null && !node.IsLeaf)
|
||||
{
|
||||
var children = await _service.ExpandNode(session, node.NodePath);
|
||||
Assert.NotNull(children);
|
||||
if(children.Count() == 0 && !node.NodePath.Contains("System") &&
|
||||
!node.NodePath.Contains("FileTables") && !node.NodePath.Contains("External Tables"))
|
||||
{
|
||||
var labaleToUpper = node.Label.ToUpper();
|
||||
if (labaleToUpper.Contains("TABLE") || labaleToUpper.Contains("StoredProcedure")
|
||||
|| labaleToUpper.Contains("VIEW"))
|
||||
{
|
||||
//TOOD: Add a better validation. For now at least check tables not to be empty
|
||||
//Assert.True(false, "The list of tables, procedure and views cannot be empty");
|
||||
}
|
||||
}
|
||||
foreach (var child in children)
|
||||
{
|
||||
//Console.WriteLine(child.Label);
|
||||
await ExpandTree(child, session);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async void VerifyAdventureWorksDatabaseObjects()
|
||||
{
|
||||
var query = Scripts.AdventureWorksScript;
|
||||
string uri = "VerifyAdventureWorksDatabaseObjects";
|
||||
string databaseName = null;
|
||||
|
||||
using (SqlTestDb testDb = SqlTestDb.CreateNew(TestServerType.OnPrem, false, databaseName, query, uri))
|
||||
{
|
||||
var session = await CreateSession(testDb.DatabaseName, uri);
|
||||
var databaseNodeInfo = await CreateSessionAndDatabaseNode(testDb.DatabaseName, session);
|
||||
await ExpandTree(databaseNodeInfo, session);
|
||||
CancelConnection(uri);
|
||||
}
|
||||
}
|
||||
|
||||
// [Fact]
|
||||
public async void VerifySql2016Objects()
|
||||
{
|
||||
var query = LoadScript("Sql_2016_Additions.sql");
|
||||
string uri = "VerifySql2016Objects";
|
||||
string databaseName = null;
|
||||
|
||||
using (SqlTestDb testDb = SqlTestDb.CreateNew(TestServerType.OnPrem, false, databaseName, query, uri))
|
||||
{
|
||||
var session = await CreateSession(testDb.DatabaseName, uri);
|
||||
var databaseNodeInfo = await CreateSessionAndDatabaseNode(testDb.DatabaseName, session);
|
||||
await ExpandTree(databaseNodeInfo, session);
|
||||
CancelConnection(uri);
|
||||
}
|
||||
}
|
||||
|
||||
// [Fact]
|
||||
public async void VerifySqlObjects()
|
||||
{
|
||||
var query = LoadScript("Sql_Additions.sql");
|
||||
string uri = "VerifySqlObjects";
|
||||
string databaseName = null;
|
||||
|
||||
using (SqlTestDb testDb = SqlTestDb.CreateNew(TestServerType.OnPrem, false, databaseName, query, uri))
|
||||
{
|
||||
var session = await CreateSession(testDb.DatabaseName, uri);
|
||||
var databaseNodeInfo = await CreateSessionAndDatabaseNode(testDb.DatabaseName, session);
|
||||
await ExpandTree(databaseNodeInfo, session);
|
||||
CancelConnection(uri);
|
||||
}
|
||||
}
|
||||
|
||||
// [Fact]
|
||||
public async void VerifyFileTableTest()
|
||||
{
|
||||
var query = LoadScript("FileTableTest.sql");
|
||||
string uri = "VerifyFileTableTest";
|
||||
string databaseName = null;
|
||||
|
||||
using (SqlTestDb testDb = SqlTestDb.CreateNew(TestServerType.OnPrem, false, databaseName, query, uri))
|
||||
{
|
||||
var session = await CreateSession(testDb.DatabaseName, uri);
|
||||
var databaseNodeInfo = await CreateSessionAndDatabaseNode(testDb.DatabaseName, session);
|
||||
await ExpandTree(databaseNodeInfo, session);
|
||||
CancelConnection(uri);
|
||||
}
|
||||
}
|
||||
|
||||
//[Fact]
|
||||
public async void VerifyColumnstoreindexSql16()
|
||||
{
|
||||
var query = LoadScript("ColumnstoreindexSql16.sql");
|
||||
string uri = "VerifyColumnstoreindexSql16";
|
||||
string databaseName = null;
|
||||
|
||||
using (SqlTestDb testDb = SqlTestDb.CreateNew(TestServerType.OnPrem, false, databaseName, query, uri))
|
||||
{
|
||||
var session = await CreateSession(testDb.DatabaseName, uri);
|
||||
var databaseNodeInfo = await CreateSessionAndDatabaseNode(testDb.DatabaseName, session);
|
||||
await ExpandTree(databaseNodeInfo, session);
|
||||
CancelConnection(uri);
|
||||
}
|
||||
}
|
||||
|
||||
private static string TestLocationDirectory
|
||||
{
|
||||
get
|
||||
{
|
||||
return Path.Combine(RunEnvironmentInfo.GetTestDataLocation(), "ObjectExplorer");
|
||||
}
|
||||
}
|
||||
|
||||
public DirectoryInfo InputFileDirectory
|
||||
{
|
||||
get
|
||||
{
|
||||
string d = Path.Combine(TestLocationDirectory, "TestScripts");
|
||||
return new DirectoryInfo(d);
|
||||
}
|
||||
}
|
||||
|
||||
public FileInfo GetInputFile(string fileName)
|
||||
{
|
||||
return new FileInfo(Path.Combine(InputFileDirectory.FullName, fileName));
|
||||
}
|
||||
|
||||
private string LoadScript(string fileName)
|
||||
{
|
||||
FileInfo inputFile = GetInputFile(fileName);
|
||||
return TestUtilities.ReadTextAndNormalizeLineEndings(inputFile.FullName);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,10 @@
|
||||
using System.Data.SqlClient;
|
||||
using System;
|
||||
using System.Data.SqlClient;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.SqlServer.Management.Common;
|
||||
using Microsoft.SqlTools.ServiceLayer.Connection;
|
||||
using Microsoft.SqlTools.ServiceLayer.Connection.Contracts;
|
||||
@@ -27,11 +30,11 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Utility
|
||||
|
||||
}
|
||||
|
||||
public static TestConnectionResult InitLiveConnectionInfo()
|
||||
public static TestConnectionResult InitLiveConnectionInfo(string databaseName = null)
|
||||
{
|
||||
string sqlFilePath = GetTestSqlFile();
|
||||
ScriptFile scriptFile = TestServiceProvider.Instance.WorkspaceService.Workspace.GetFile(sqlFilePath);
|
||||
ConnectParams connectParams = TestServiceProvider.Instance.ConnectionProfileService.GetConnectionParameters(TestServerType.OnPrem);
|
||||
ConnectParams connectParams = TestServiceProvider.Instance.ConnectionProfileService.GetConnectionParameters(TestServerType.OnPrem, databaseName);
|
||||
|
||||
string ownerUri = scriptFile.ClientFilePath;
|
||||
var connectionService = GetLiveTestConnectionService();
|
||||
@@ -50,6 +53,35 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Utility
|
||||
return new TestConnectionResult() { ConnectionInfo = connInfo, ScriptFile = scriptFile };
|
||||
}
|
||||
|
||||
public static async Task<TestConnectionResult> InitLiveConnectionInfoAsync(string databaseName = null, string ownerUri = null)
|
||||
{
|
||||
ScriptFile scriptFile = null;
|
||||
if (string.IsNullOrEmpty(ownerUri))
|
||||
{
|
||||
string sqlFilePath = GetTestSqlFile();
|
||||
scriptFile = TestServiceProvider.Instance.WorkspaceService.Workspace.GetFile(sqlFilePath);
|
||||
ownerUri = scriptFile.ClientFilePath;
|
||||
}
|
||||
ConnectParams connectParams = TestServiceProvider.Instance.ConnectionProfileService.GetConnectionParameters(TestServerType.OnPrem, databaseName);
|
||||
|
||||
var connectionService = GetLiveTestConnectionService();
|
||||
var connectionResult =
|
||||
await connectionService
|
||||
.Connect(new ConnectParams
|
||||
{
|
||||
OwnerUri = ownerUri,
|
||||
Connection = connectParams.Connection
|
||||
});
|
||||
if (!string.IsNullOrEmpty(connectionResult.ErrorMessage))
|
||||
{
|
||||
Console.WriteLine(connectionResult.ErrorMessage);
|
||||
}
|
||||
|
||||
ConnectionInfo connInfo = null;
|
||||
connectionService.TryFindConnection(ownerUri, out connInfo);
|
||||
return new TestConnectionResult() { ConnectionInfo = connInfo, ScriptFile = scriptFile };
|
||||
}
|
||||
|
||||
public static ConnectionInfo InitLiveConnectionInfoForDefinition(string databaseName = null)
|
||||
{
|
||||
ConnectParams connectParams = TestServiceProvider.Instance.ConnectionProfileService.GetConnectionParameters(TestServerType.OnPrem, databaseName);
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -43,7 +43,9 @@ END
|
||||
|
||||
public static string CreateDatabaseQuery { get { return CreateDatabaseQueryInstance.Value; } }
|
||||
|
||||
public static string TestDbComplexSelectQueries { get { return TestDbSelectQueriesInstance.Value; } }
|
||||
public static string TestDbComplexSelectQueries { get { return TestDbSelectQueriesInstance.Value; } }
|
||||
|
||||
public static string AdventureWorksScript { get { return AdventureWorksScriptInstance.Value; } }
|
||||
|
||||
private static readonly Lazy<string> CreateDatabaseObjectsQueryInstance = new Lazy<string>(() =>
|
||||
{
|
||||
@@ -58,6 +60,11 @@ END
|
||||
private static readonly Lazy<string> TestDbSelectQueriesInstance = new Lazy<string>(() =>
|
||||
{
|
||||
return GetScriptFileContent(ResourceNameRefix + "TestDbTableQueries.sql");
|
||||
});
|
||||
|
||||
private static readonly Lazy<string> AdventureWorksScriptInstance = new Lazy<string>(() =>
|
||||
{
|
||||
return GetScriptFileContent(ResourceNameRefix + "AdventureWorks.sql");
|
||||
});
|
||||
|
||||
private static string GetScriptFileContent(string fileName)
|
||||
|
||||
@@ -27,13 +27,18 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Common
|
||||
/// <summary>
|
||||
/// Create the test db if not already exists
|
||||
/// </summary>
|
||||
public static SqlTestDb CreateNew(TestServerType serverType, bool doNotCleanupDb = false, string databaseName = null, string query = null)
|
||||
public static SqlTestDb CreateNew(
|
||||
TestServerType serverType,
|
||||
bool doNotCleanupDb = false,
|
||||
string databaseName = null,
|
||||
string query = null,
|
||||
string dbNamePrefix = null)
|
||||
{
|
||||
SqlTestDb testDb = new SqlTestDb();
|
||||
|
||||
using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile())
|
||||
{
|
||||
databaseName = databaseName ?? GetUniqueDBName("");
|
||||
databaseName = databaseName ?? GetUniqueDBName(dbNamePrefix);
|
||||
string createDatabaseQuery = Scripts.CreateDatabaseQuery.Replace("#DatabaseName#", databaseName);
|
||||
TestServiceProvider.Instance.RunQuery(serverType, MasterDatabaseName, createDatabaseQuery);
|
||||
Console.WriteLine(string.Format(CultureInfo.InvariantCulture, "Test database '{0}' is created", databaseName));
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
CREATE TABLE CS_Delay_Table1
|
||||
(ProductKey [int] NOT NULL,
|
||||
OrderDateKey [int] NOT NULL,
|
||||
DueDateKey [int] NOT NULL,
|
||||
ShipDateKey [int] NOT NULL);
|
||||
GO
|
||||
|
||||
CREATE CLUSTERED COLUMNSTORE INDEX CSI_1 ON CS_Delay_Table1
|
||||
WITH (COMPRESSION_DELAY = 100 minutes);
|
||||
GO
|
||||
|
||||
CREATE TABLE CS_Delay_Table2
|
||||
(ProductKey [int] NOT NULL,
|
||||
OrderDateKey [int] NOT NULL,
|
||||
DueDateKey [int] NOT NULL,
|
||||
ShipDateKey [int] NOT NULL);
|
||||
GO
|
||||
|
||||
CREATE CLUSTERED INDEX CI_Table2 ON CS_Delay_Table2 (ProductKey);
|
||||
GO
|
||||
|
||||
CREATE NONCLUSTERED COLUMNSTORE INDEX CSI_2
|
||||
ON CS_Delay_Table2
|
||||
(OrderDateKey, DueDateKey, ShipDateKey)
|
||||
WITH (COMPRESSION_DELAY = 200);
|
||||
GO
|
||||
|
||||
CREATE TABLE CS_Delay_Table3
|
||||
(ProductKey [int] NOT NULL,
|
||||
OrderDateKey [int] NOT NULL,
|
||||
DueDateKey [int] NOT NULL,
|
||||
ShipDateKey [int] NOT NULL,
|
||||
INDEX CSI_3 CLUSTERED COLUMNSTORE WITH(COMPRESSION_DELAY = 50 minute));
|
||||
GO
|
||||
@@ -0,0 +1,103 @@
|
||||
|
||||
CREATE DATABASE [$(DatabaseName)]
|
||||
|
||||
GO
|
||||
ALTER DATABASE [$(DatabaseName)] SET TARGET_RECOVERY_TIME = 1 MINUTES
|
||||
GO
|
||||
USE [$(DatabaseName)]
|
||||
|
||||
GO
|
||||
ALTER DATABASE [$(DatabaseName)]
|
||||
SET FILESTREAM(
|
||||
NON_TRANSACTED_ACCESS = FULL,
|
||||
DIRECTORY_NAME = N'$(DatabaseName)'
|
||||
) WITH NO_WAIT
|
||||
|
||||
GO
|
||||
|
||||
ALTER DATABASE $(DatabaseName)
|
||||
ADD FILEGROUP [FileGroup1]
|
||||
CONTAINS FILESTREAM
|
||||
|
||||
GO
|
||||
|
||||
ALTER DATABASE $(DatabaseName)
|
||||
ADD FILE
|
||||
(NAME = 'FileTableFile'
|
||||
, FILENAME = '$(DefaultDataPath)$(DatabaseName)_FT'
|
||||
)
|
||||
TO FILEGROUP [FileGroup1]
|
||||
|
||||
GO
|
||||
|
||||
|
||||
|
||||
CREATE TABLE [dbo].[FileTablePass] AS FILETABLE WITH(
|
||||
FileTable_Directory = 'docs',
|
||||
FILETABLE_PRIMARY_KEY_CONSTRAINT_NAME=MyPk,
|
||||
FILETABLE_STREAMID_UNIQUE_CONSTRAINT_NAME=MyStreamUQ,
|
||||
FILETABLE_FULLPATH_UNIQUE_CONSTRAINT_NAME=MyPathUQ)
|
||||
|
||||
GO
|
||||
ALTER TABLE [dbo].[FileTablePass] WITH CHECK ADD CONSTRAINT [MyCheck] CHECK ((stream_id IS NOT NULL))
|
||||
GO
|
||||
ALTER TABLE [dbo].[FileTablePass] ADD CONSTRAINT [MyDefault] DEFAULT ((NULL)) FOR [name]
|
||||
GO
|
||||
ALTER TABLE [dbo].[FileTablePass] ADD CONSTRAINT [MyQU] UNIQUE NONCLUSTERED ([name] ASC)
|
||||
GO
|
||||
ALTER TABLE [dbo].[FileTablePass] WITH CHECK ADD CONSTRAINT [MyFk] FOREIGN KEY([parent_path_locator])
|
||||
REFERENCES [dbo].[FileTablePass] ([path_locator])
|
||||
GO
|
||||
CREATE TABLE [dbo].[t2] (
|
||||
[c1] INT NOT NULL,
|
||||
[c2] INT DEFAULT ((1)) NULL,
|
||||
[c3] INT DEFAULT ((1)) NOT NULL,
|
||||
[path_locator] hierarchyid,
|
||||
PRIMARY KEY CLUSTERED ([c1] ASC),
|
||||
UNIQUE NONCLUSTERED ([c2] ASC),
|
||||
CHECK ([c2] > (0))
|
||||
);
|
||||
|
||||
GO
|
||||
CREATE STATISTICS stat1
|
||||
ON dbo.[FileTablePass](stream_id)
|
||||
WITH SAMPLE 50 PERCENT;
|
||||
GO
|
||||
CREATE INDEX IX_FileTablePass_Stream_id
|
||||
ON dbo.FileTablePass(stream_id);
|
||||
GO
|
||||
|
||||
CREATE TRIGGER FileTableTrigger
|
||||
ON dbo.FileTablePass
|
||||
AFTER INSERT
|
||||
AS RAISERROR ('Block insert', 16, 10);
|
||||
GO
|
||||
CREATE INDEX IX_T2_C3
|
||||
ON [dbo].[t2](c3);
|
||||
|
||||
GO
|
||||
|
||||
CREATE TRIGGER reminder2
|
||||
ON dbo.t2
|
||||
AFTER INSERT, UPDATE, DELETE
|
||||
AS
|
||||
PRINT 'reminder trigger';
|
||||
|
||||
GO
|
||||
|
||||
ALTER TABLE dbo.t2
|
||||
ADD CONSTRAINT FK_TO_FILETABLE FOREIGN KEY (path_locator)
|
||||
REFERENCES FileTablePass (path_locator) ;
|
||||
GO
|
||||
exec sp_addextendedproperty 'prop_ex', 'FileTable', 'SCHEMA', 'dbo', 'TABLE', 'FileTablePass'
|
||||
exec sp_addextendedproperty 'prop_ex', 'MyPk', 'SCHEMA', 'dbo', 'TABLE', 'FileTablePass', 'CONSTRAINT', 'MyPk'
|
||||
exec sp_addextendedproperty 'prop_ex', 'MyStreamUQ', 'SCHEMA', 'dbo', 'TABLE', 'FileTablePass', 'CONSTRAINT', 'MyStreamUQ'
|
||||
exec sp_addextendedproperty 'prop_ex', 'MyPathUQ', 'SCHEMA', 'dbo', 'TABLE', 'FileTablePass', 'CONSTRAINT', 'MyPathUQ'
|
||||
|
||||
GO
|
||||
|
||||
CREATE USER test_user WITHOUT LOGIN
|
||||
GO
|
||||
|
||||
GRANT SELECT ON dbo.FileTablePass TO test_user
|
||||
GO
|
||||
@@ -0,0 +1,62 @@
|
||||
CREATE PROCEDURE [dbo].[Encrypted_Additional_Numbered_Procedure]
|
||||
( @param1 int)
|
||||
WITH ENCRYPTION
|
||||
AS
|
||||
SELECT 1 AS Col1
|
||||
|
||||
GO
|
||||
|
||||
|
||||
CREATE PROCEDURE [dbo].[Encrypted_Additional_Numbered_Procedure];2
|
||||
( @param1 int)
|
||||
WITH ENCRYPTION
|
||||
AS
|
||||
SELECT 2 AS Col1
|
||||
|
||||
|
||||
GO
|
||||
|
||||
CREATE PROCEDURE [dbo].[Encrypted_Additional_Numbered_Procedure];3
|
||||
( @param1 int)
|
||||
WITH ENCRYPTION
|
||||
AS
|
||||
SELECT 3 AS Col1
|
||||
|
||||
|
||||
GO
|
||||
|
||||
CREATE PROCEDURE [dbo].[Encrypted_Additional_Numbered_Procedure];4
|
||||
( @param1 int)
|
||||
WITH ENCRYPTION
|
||||
AS
|
||||
SELECT 4 AS Col1
|
||||
|
||||
GO
|
||||
|
||||
CREATE PROCEDURE [dbo].[Additional_Numbered_Procedure]
|
||||
(@param1 int)
|
||||
AS
|
||||
SELECT 1 AS Col1
|
||||
|
||||
GO
|
||||
|
||||
CREATE PROCEDURE [dbo].[Additional_Numbered_Procedure];2
|
||||
(@param1 int)
|
||||
AS
|
||||
SELECT 2 AS Col1
|
||||
|
||||
GO
|
||||
|
||||
CREATE PROCEDURE [dbo].[Additional_Numbered_Procedure];3
|
||||
(@param1 int)
|
||||
AS
|
||||
SELECT 3 AS Col1
|
||||
|
||||
GO
|
||||
|
||||
CREATE PROCEDURE [dbo].[Additional_Numbered_Procedure];4
|
||||
(@param1 int)
|
||||
AS
|
||||
SELECT 4 AS Col1
|
||||
|
||||
|
||||
@@ -0,0 +1,275 @@
|
||||
ALTER DATABASE current SET COMPATIBILITY_LEVEL=130
|
||||
GO
|
||||
|
||||
/* Dropping previous master key in master db that could have been created from other runs */
|
||||
IF ( EXISTS(SELECT name FROM sys.symmetric_keys WHERE name = '##MS_DatabaseMasterKey##')) DROP MASTER KEY
|
||||
|
||||
CREATE MASTER KEY ENCRYPTION BY PASSWORD= 'Password01!';
|
||||
|
||||
OPEN MASTER KEY DECRYPTION BY PASSWORD = 'Password01!';
|
||||
|
||||
|
||||
CREATE DATABASE SCOPED CREDENTIAL AlterEgo WITH IDENTITY = 'RettigB',
|
||||
SECRET = 'sdrlk8$40-dksli87nNN8';
|
||||
|
||||
GO
|
||||
|
||||
-- Row-Level Security
|
||||
CREATE TABLE [dbo].[Sales1]
|
||||
(
|
||||
OrderID INT,
|
||||
SalesRep SYSNAME NOT NULL,
|
||||
Product VARCHAR(10),
|
||||
Qty INT
|
||||
);
|
||||
|
||||
GO
|
||||
|
||||
CREATE TABLE [dbo].[Sales2]
|
||||
(
|
||||
OrderID INT,
|
||||
SalesRep SYSNAME NOT NULL,
|
||||
Product VARCHAR(10),
|
||||
Qty INT
|
||||
);
|
||||
|
||||
GO
|
||||
|
||||
CREATE FUNCTION [dbo].[fn_securitypredicate](@SalesRep AS SYSNAME)
|
||||
RETURNS TABLE
|
||||
WITH SCHEMABINDING
|
||||
AS
|
||||
RETURN SELECT 1 AS fn_securitypredicate_result
|
||||
WHERE @SalesRep = USER_NAME() OR USER_NAME() = 'Manager';
|
||||
|
||||
|
||||
GO
|
||||
|
||||
CREATE SECURITY POLICY [dbo].[SalesFilter]
|
||||
ADD FILTER PREDICATE [dbo].[fn_securitypredicate]([SalesRep]) ON [dbo].[Sales1],
|
||||
ADD FILTER PREDICATE [dbo].[fn_securitypredicate]([SalesRep]) ON [dbo].[Sales2],
|
||||
ADD BLOCK PREDICATE [dbo].[fn_securitypredicate]([SalesRep]) ON [dbo].[Sales1],
|
||||
ADD BLOCK PREDICATE [dbo].[fn_securitypredicate]([SalesRep]) ON [dbo].[Sales2] AFTER UPDATE
|
||||
WITH (STATE = OFF)
|
||||
NOT FOR REPLICATION
|
||||
|
||||
GO
|
||||
|
||||
CREATE COLUMN MASTER KEY CMK1
|
||||
WITH (
|
||||
KEY_STORE_PROVIDER_NAME = 'MSSQL_CERTIFICATE_STORE',
|
||||
KEY_PATH = 'Current User/Personal/f2260f28d909d21c642a3d8e0b45a830e79a1420'
|
||||
);
|
||||
|
||||
GO
|
||||
|
||||
CREATE COLUMN MASTER KEY CMK2
|
||||
WITH (
|
||||
KEY_STORE_PROVIDER_NAME = 'MSSQL_CERTIFICATE_STORE',
|
||||
KEY_PATH = 'Current User/Personal/f2260f28d909d21c642a3d8e0b45a830e79a1420'
|
||||
);
|
||||
|
||||
GO
|
||||
|
||||
CREATE COLUMN ENCRYPTION KEY TwoValueCEK
|
||||
WITH VALUES
|
||||
(
|
||||
COLUMN_MASTER_KEY = CMK1,
|
||||
ALGORITHM = 'RSA_OAEP',
|
||||
ENCRYPTED_VALUE = 0x016E000001630075007200720065006E00740075007300650072002F006D0079002F0037006300380061003100310033003400320037003800620037003000630038003100390062003900630039003400360061006600340039006500610030003200650038006200650038003400340065006C33A82ECF04A7185824B4545457AC5244CD9C219E64067B9520C0081B8399B58C2863F7494ABE3694BD87D55FFD7576FFDC47C28F94ECC99577DF4FB8FA19AA95764FEF889CDE0F176DA5897B74382FBB22756CE2921050A09201A0EB6AF3D6091014C30146EA62635EE8CBF0A8074DEDFF125CEA80D1C0F5E8C58750A07D270E2A8BF824EE4C0C156366BF26D38CCE49EBDD5639A2DF029A7DBAE5A5D111F2F2FA3246DF8C2FA83C1E542C10570FADA98F6B29478DC58CE5CBDD407CCEFCDB97814525F6F32BECA266014AC346AC39C4F185C6C0F0A24FEC4DFA015649624692DE7865B9827BA22C3B574C9FD169F822B609F902288C5880EB25F14BD990D871B1BC4BA3A5B237AF76D26354773FA2A25CF4511AF58C911E601CFCB1905128C997844EED056C2AE7F0B48700AB41307E470FF9520997D0EB0D887DE11AFE574FFE845B7DC6C03FEEE8D467236368FC0CB2FDBD54DADC65B10B3DE6C80DF8B7B3F8F3CE5BE914713EE7B1FA5B7A578359592B8A5FDFDDE5FF9F392BC87C3CD02FBA94582AC063BBB9FFAC803FD489E16BEB28C4E3374A8478C737236A0B232F5A9DDE4D119573F1AEAE94B2192B81575AD6F57E670C1B2AB91045124DFDAEC2898F3F0112026DFC93BF9391D667D1AD7ED7D4E6BB119BBCEF1D1ADA589DD3E1082C3DAD13223BE438EB9574DA04E9D8A06320CAC6D3EC21D5D1C2A0AA484C7C
|
||||
),
|
||||
(
|
||||
COLUMN_MASTER_KEY = CMK2,
|
||||
ALGORITHM = 'RSA_OAEP',
|
||||
ENCRYPTED_VALUE = 0x016E000001630075007200720065006E00740075007300650072002F006D0079002F0064006500650063006200660034006100340031003000380034006200350033003200360066003200630062006200350030003600380065003900620061003000320030003600610037003800310066001DDA6134C3B73A90D349C8905782DD819B428162CF5B051639BA46EC69A7C8C8F81591A92C395711493B25DCBCCC57836E5B9F17A0713E840721D098F3F8E023ABCDFE2F6D8CC4339FC8F88630ED9EBADA5CA8EEAFA84164C1095B12AE161EABC1DF778C07F07D413AF1ED900F578FC00894BEE705EAC60F4A5090BBE09885D2EFE1C915F7B4C581D9CE3FDAB78ACF4829F85752E9FC985DEB8773889EE4A1945BD554724803A6F5DC0A2CD5EFE001ABED8D61E8449E4FAA9E4DD392DA8D292ECC6EB149E843E395CDE0F98D04940A28C4B05F747149B34A0BAEC04FFF3E304C84AF1FF81225E615B5F94E334378A0A888EF88F4E79F66CB377E3C21964AACB5049C08435FE84EEEF39D20A665C17E04898914A85B3DE23D56575EBC682D154F4F15C37723E04974DB370180A9A579BC84F6BC9B5E7C223E5CBEE721E57EE07EFDCC0A3257BBEBF9ADFFB00DBF7EF682EC1C4C47451438F90B4CF8DA709940F72CFDC91C6EB4E37B4ED7E2385B1FF71B28A1D2669FBEB18EA89F9D391D2FDDEA0ED362E6A591AC64EF4AE31CA8766C259ECB77D01A7F5C36B8418F91C1BEADDD4491C80F0016B66421B4B788C55127135DA2FA625FB7FD195FB40D90A6C67328602ECAF3EC4F5894BFD84A99EB4753BE0D22E0D4DE6A0ADFEDC80EB1B556749B4A8AD00E73B329C95827AB91C0256347E85E3C5FD6726D0E1FE82C925D3DF4A9
|
||||
);
|
||||
|
||||
GO
|
||||
|
||||
CREATE TABLE Customers (
|
||||
CustName nvarchar(60),
|
||||
SSN varchar(11)
|
||||
COLLATE Latin1_General_BIN2 ENCRYPTED WITH (COLUMN_ENCRYPTION_KEY = TwoValueCEK,
|
||||
ENCRYPTION_TYPE = DETERMINISTIC ,
|
||||
ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256'),
|
||||
Age int NULL,
|
||||
ACTNO varchar(11)
|
||||
ENCRYPTED WITH (COLUMN_ENCRYPTION_KEY = TwoValueCEK,
|
||||
ENCRYPTION_TYPE = RANDOMIZED,
|
||||
ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256')
|
||||
);
|
||||
|
||||
GO
|
||||
|
||||
USE [$(DatabaseName)]
|
||||
|
||||
GO
|
||||
|
||||
DBCC TRACEON(4631,-1)
|
||||
|
||||
GO
|
||||
|
||||
OPEN MASTER KEY DECRYPTION BY PASSWORD = 'Password01!';
|
||||
|
||||
CREATE DATABASE SCOPED CREDENTIAL cred1 WITH IDENTITY = 'test_user', SECRET = '$(Secret)';
|
||||
|
||||
CREATE EXTERNAL DATA SOURCE eds1
|
||||
WITH (
|
||||
TYPE = HADOOP,
|
||||
LOCATION = '$(DataSourceLocation)',
|
||||
CREDENTIAL = cred1
|
||||
);
|
||||
|
||||
CREATE EXTERNAL DATA SOURCE eds2
|
||||
WITH (
|
||||
TYPE = HADOOP,
|
||||
LOCATION = '$(DataSourceLocation)'
|
||||
);
|
||||
|
||||
CREATE EXTERNAL FILE FORMAT eff1
|
||||
WITH (
|
||||
FORMAT_TYPE = DELIMITEDTEXT
|
||||
);
|
||||
|
||||
CREATE EXTERNAL FILE FORMAT eff2
|
||||
WITH (
|
||||
FORMAT_TYPE = ORC
|
||||
);
|
||||
|
||||
CREATE EXTERNAL FILE FORMAT eff3
|
||||
WITH (
|
||||
FORMAT_TYPE = PARQUET
|
||||
);
|
||||
|
||||
CREATE EXTERNAL FILE FORMAT eff4
|
||||
WITH (
|
||||
FORMAT_TYPE = RCFILE,
|
||||
SERDE_METHOD = 'org.apache.hadoop.hive.serde2.columnar.ColumnarSerDe'
|
||||
);
|
||||
|
||||
CREATE EXTERNAL FILE FORMAT eff5
|
||||
WITH (
|
||||
FORMAT_TYPE = DELIMITEDTEXT,
|
||||
FORMAT_OPTIONS (FIELD_TERMINATOR = '|', STRING_DELIMITER = ';', DATE_FORMAT = 'MM-dd-yyyy', USE_TYPE_DEFAULT = FALSE)
|
||||
);
|
||||
|
||||
CREATE EXTERNAL FILE FORMAT eff6
|
||||
WITH (
|
||||
FORMAT_TYPE = DELIMITEDTEXT,
|
||||
FORMAT_OPTIONS (FIELD_TERMINATOR = '|')
|
||||
);
|
||||
|
||||
CREATE EXTERNAL FILE FORMAT eff7
|
||||
WITH (
|
||||
FORMAT_TYPE = DELIMITEDTEXT,
|
||||
FORMAT_OPTIONS (DATE_FORMAT = 'MM-dd-yyyy', FIELD_TERMINATOR = '|')
|
||||
);
|
||||
|
||||
CREATE EXTERNAL FILE FORMAT eff8
|
||||
WITH (
|
||||
FORMAT_TYPE = DELIMITEDTEXT,
|
||||
FORMAT_OPTIONS (DATE_FORMAT = 'MM-dd-yyyy', FIELD_TERMINATOR = '|', STRING_DELIMITER = ';')
|
||||
);
|
||||
|
||||
CREATE EXTERNAL FILE FORMAT eff9
|
||||
WITH (
|
||||
FORMAT_TYPE = DELIMITEDTEXT,
|
||||
FORMAT_OPTIONS (DATE_FORMAT = 'MM-dd-yyyy', FIELD_TERMINATOR = '|', STRING_DELIMITER = ';'),
|
||||
DATA_COMPRESSION = 'org.apache.hadoop.io.compress.GzipCodec'
|
||||
);
|
||||
|
||||
CREATE EXTERNAL FILE FORMAT eff10
|
||||
WITH (
|
||||
FORMAT_TYPE = RCFILE,
|
||||
SERDE_METHOD = 'org.apache.hadoop.hive.serde2.columnar.ColumnarSerDe',
|
||||
DATA_COMPRESSION = 'org.apache.hadoop.io.compress.DefaultCodec'
|
||||
);
|
||||
|
||||
CREATE EXTERNAL FILE FORMAT eff11
|
||||
WITH (
|
||||
FORMAT_TYPE = ORC,
|
||||
DATA_COMPRESSION = 'org.apache.hadoop.io.compress.SnappyCodec'
|
||||
);
|
||||
|
||||
CREATE EXTERNAL FILE FORMAT eff12
|
||||
WITH (
|
||||
FORMAT_TYPE = PARQUET,
|
||||
DATA_COMPRESSION = 'org.apache.hadoop.io.compress.SnappyCodec'
|
||||
);
|
||||
|
||||
CREATE EXTERNAL TABLE bands1
|
||||
(
|
||||
id INTEGER NOT NULL,
|
||||
name VARCHAR(50) NOT NULL,
|
||||
origin CHAR(3),
|
||||
rate FLOAT,
|
||||
experience SMALLINT
|
||||
)
|
||||
WITH (
|
||||
LOCATION = '/bands.dat',
|
||||
DATA_SOURCE = eds1,
|
||||
FILE_FORMAT = eff1
|
||||
);
|
||||
|
||||
CREATE EXTERNAL TABLE bands2
|
||||
(
|
||||
id INTEGER NOT NULL,
|
||||
name VARCHAR(50) NOT NULL,
|
||||
origin CHAR(3),
|
||||
rate FLOAT,
|
||||
experience SMALLINT
|
||||
)
|
||||
WITH (
|
||||
LOCATION = '/bands.dat',
|
||||
DATA_SOURCE = eds2,
|
||||
FILE_FORMAT = eff1
|
||||
);
|
||||
|
||||
CREATE EXTERNAL TABLE bands3
|
||||
(
|
||||
id INTEGER NOT NULL,
|
||||
name VARCHAR(50) NOT NULL,
|
||||
origin CHAR(3),
|
||||
rate FLOAT,
|
||||
experience SMALLINT
|
||||
)
|
||||
WITH (
|
||||
LOCATION = '/bands.dat',
|
||||
DATA_SOURCE = eds2,
|
||||
FILE_FORMAT = eff1,
|
||||
REJECT_TYPE = VALUE,
|
||||
REJECT_VALUE = 0
|
||||
);
|
||||
|
||||
CREATE EXTERNAL TABLE bands4
|
||||
(
|
||||
id INTEGER NOT NULL,
|
||||
name VARCHAR(50) NOT NULL,
|
||||
origin CHAR(3),
|
||||
rate FLOAT,
|
||||
experience SMALLINT
|
||||
)
|
||||
WITH (
|
||||
LOCATION = '/bands.dat',
|
||||
DATA_SOURCE = eds1,
|
||||
FILE_FORMAT = eff1,
|
||||
REJECT_TYPE = PERCENTAGE,
|
||||
REJECT_VALUE = 30.5,
|
||||
REJECT_SAMPLE_VALUE = 10
|
||||
);
|
||||
|
||||
CREATE EXTERNAL TABLE bands5
|
||||
(
|
||||
id INTEGER NOT NULL,
|
||||
name VARCHAR(50) NOT NULL,
|
||||
origin CHAR(3),
|
||||
rate FLOAT,
|
||||
experience SMALLINT
|
||||
)
|
||||
WITH (
|
||||
LOCATION = '/bands.dat',
|
||||
DATA_SOURCE = eds1,
|
||||
FILE_FORMAT = eff1,
|
||||
REJECT_TYPE = VALUE,
|
||||
REJECT_VALUE = 30
|
||||
);
|
||||
@@ -0,0 +1,298 @@
|
||||
-- create signature
|
||||
ADD SIGNATURE TO [Procedure1]
|
||||
BY CERTIFICATE [Certificate1]
|
||||
WITH PASSWORD = 'pGFD4bb925DGvbd2439587y' ;
|
||||
GO
|
||||
--Create a queue to receive messages.
|
||||
CREATE QUEUE NotifyQueue ;
|
||||
GO
|
||||
--Create a service on the queue that references
|
||||
--the event notifications contract.
|
||||
CREATE SERVICE NotifyService
|
||||
ON QUEUE NotifyQueue
|
||||
([http://schemas.microsoft.com/SQL/Notifications/PostEventNotification]);
|
||||
GO
|
||||
--Create the event notification on queue.
|
||||
CREATE EVENT NOTIFICATION Notify_ALTER_T1
|
||||
ON QUEUE notifyqueue
|
||||
FOR QUEUE_ACTIVATION
|
||||
TO SERVICE 'NotifyService',
|
||||
'8140a771-3c4b-4479-8ac0-81008ab17984';
|
||||
GO
|
||||
--Create the event notification on database
|
||||
CREATE EVENT NOTIFICATION Notify_ALTER_T1
|
||||
ON DATABASE
|
||||
FOR ALTER_TABLE
|
||||
TO SERVICE 'NotifyService',
|
||||
'8140a771-3c4b-4479-8ac0-81008ab17984';
|
||||
GO
|
||||
|
||||
CREATE FUNCTION [dbo].[TableFunctionWithComputedColumns]
|
||||
(
|
||||
-- Add the parameters for the function here
|
||||
@p1 int = 2,
|
||||
@p2 nchar(10) = NUll
|
||||
)
|
||||
RETURNS
|
||||
@Table_Var TABLE
|
||||
(
|
||||
-- Add the column definitions for the TABLE variable here
|
||||
c1 int,
|
||||
c2 nchar(10),
|
||||
c3 AS 1 * 3
|
||||
)
|
||||
AS
|
||||
BEGIN
|
||||
-- Fill the table variable with the rows for your result set
|
||||
INSERT INTO @Table_Var
|
||||
SELECT a.column_1, a.column_2
|
||||
FROM Table_1 a
|
||||
WHERE a.column_1 > 5
|
||||
|
||||
INSERT INTO @Table_Var
|
||||
SELECT column_1, 'From 2'
|
||||
FROM Table_2
|
||||
WHERE @p1 > column_1
|
||||
|
||||
RETURN
|
||||
END
|
||||
GO
|
||||
|
||||
CREATE FUNCTION [dbo].[TableFunctionWithComputedColumnsEncrypted]
|
||||
(
|
||||
-- Add the parameters for the function here
|
||||
@p1 int = 2,
|
||||
@p2 nchar(10)
|
||||
)
|
||||
RETURNS
|
||||
@Table_Var TABLE
|
||||
(
|
||||
-- Add the column definitions for the TABLE variable here
|
||||
c1 int,
|
||||
c2 nchar(10),
|
||||
c3 AS 1 * 3
|
||||
)
|
||||
WITH ENCRYPTION
|
||||
AS
|
||||
BEGIN
|
||||
-- Fill the table variable with the rows for your result set
|
||||
INSERT INTO @Table_Var
|
||||
SELECT a.column_1, a.column_2
|
||||
FROM Table_1 a
|
||||
WHERE a.column_1 > 5
|
||||
|
||||
INSERT INTO @Table_Var
|
||||
SELECT column_1, 'From 2'
|
||||
FROM Table_2
|
||||
WHERE @p1 > column_1
|
||||
|
||||
RETURN
|
||||
END
|
||||
GO
|
||||
|
||||
Create table [dbo].[referenced_table] (C1 int, C2 int);
|
||||
|
||||
GO
|
||||
|
||||
CREATE PROCEDURE GetReferenedTable
|
||||
AS
|
||||
BEGIN
|
||||
SELECT * from [dbo].[referenced_table];
|
||||
END
|
||||
GO
|
||||
exec sp_addextendedproperty N'microsoft_database_tools_support', 'GetReferenedTable', N'SCHEMA', 'dbo', N'PROCEDURE' ,'GetReferenedTable'
|
||||
GO
|
||||
DISABLE TRIGGER [Trigger_1]
|
||||
ON DATABASE;
|
||||
GO
|
||||
|
||||
CREATE VIEW [dbo].[View_2] (c1)
|
||||
AS
|
||||
SELECT column_1 as c1
|
||||
FROM dbo.Table_1
|
||||
|
||||
GO
|
||||
|
||||
exec sp_addextendedproperty 'prop_ex', 'Table_1', 'SCHEMA', 'dbo', 'TABLE', 'Table_1'
|
||||
|
||||
GO
|
||||
|
||||
exec sp_addextendedproperty 'prop_ex', 'column_1', 'SCHEMA', 'dbo', 'TABLE', 'Table_1', 'COLUMN', 'column_1'
|
||||
GO
|
||||
|
||||
CREATE TABLE dbo.MultipleIndexTable
|
||||
( [c1] INT NOT NULL CHECK (c1 > 0),
|
||||
[c2] int default 10 null,
|
||||
PRIMARY KEY NONCLUSTERED (c1 ASC),
|
||||
UNIQUE CLUSTERED (c1 ASC, c2 DESC)
|
||||
)
|
||||
|
||||
GO
|
||||
|
||||
CREATE TRIGGER [Trigger_2]
|
||||
ON DATABASE
|
||||
FOR DROP_TABLE
|
||||
AS
|
||||
SELECT COUNT(column_1) from dbo.Table_1
|
||||
RAISERROR ('You must disable Trigger "Trigger_1" to drop synonyms!',10, 1)
|
||||
ROLLBACK
|
||||
|
||||
GO
|
||||
|
||||
SET ANSI_NULLS OFF
|
||||
GO
|
||||
|
||||
SET QUOTED_IDENTIFIER OFF
|
||||
GO
|
||||
|
||||
DISABLE TRIGGER [Trigger_1] ON DATABASE
|
||||
GO
|
||||
|
||||
GO
|
||||
|
||||
CREATE TABLE dbo.Table_3
|
||||
(
|
||||
c1 int,
|
||||
c2 int,
|
||||
) ON PartitionScheme(c1)
|
||||
|
||||
GO
|
||||
CREATE TABLE [dbo].[Different_WithAppend_Table](
|
||||
[Id] [int] IDENTITY(1,1) NOT NULL,
|
||||
[Col] [char](1) NULL
|
||||
) ON [PRIMARY]
|
||||
|
||||
GO
|
||||
|
||||
CREATE FUNCTION [dbo].[EncryptedFunctionWithConstraints]
|
||||
(@p1 INT)
|
||||
RETURNS
|
||||
@GeneratedTableName TABLE (
|
||||
[c0] INT NOT NULL PRIMARY KEY,
|
||||
[c1] INT DEFAULT ((1)) NULL,
|
||||
[c2] NCHAR (10) NULL,
|
||||
[c3] INT UNIQUE ,
|
||||
CHECK ([c1]>(0)))
|
||||
WITH ENCRYPTION
|
||||
AS
|
||||
BEGIN
|
||||
insert into @GeneratedTableName values (1,1, 'abc',1);
|
||||
RETURN
|
||||
END
|
||||
GO
|
||||
CREATE TABLE [[] (c1 int)
|
||||
GO
|
||||
CREATE TABLE []]] (c1 int)
|
||||
GO
|
||||
CREATE TABLE [asdf'[] (c1 int)
|
||||
GO
|
||||
CREATE TABLE [噂構申表5] (c1 int)
|
||||
GO
|
||||
-- Casing of NULL is explicit 'NUll'
|
||||
CREATE PROC CasingOnDefaultValue @param1 int = NUll, @param2 nvarchar(123) = N'abc'
|
||||
AS
|
||||
BEGIN
|
||||
select 1 as a
|
||||
END
|
||||
-- permissions
|
||||
GO
|
||||
CREATE USER nologon4 without login
|
||||
GO
|
||||
GRANT VIEW DEFINITION ON CasingOnDefaultValue to nologon4
|
||||
GO
|
||||
CREATE USER granter without login
|
||||
GO
|
||||
GRANT CONNECT TO granter WITH GRANT OPTION;
|
||||
GO
|
||||
DENY CONNECT TO nologon4 CASCADE AS granter;
|
||||
GO
|
||||
GRANT VIEW DEFINITION ON [噂構申表5] to nologon4
|
||||
GO
|
||||
GRANT VIEW DEFINITION ON [[] TO nologon4
|
||||
GO
|
||||
GRANT VIEW DEFINITION ON []]] TO nologon4
|
||||
GO
|
||||
GRANT VIEW DEFINITION ON [asdf'[] TO nologon4
|
||||
GO
|
||||
GRANT SELECT ON dbo.Table_1 to nologon4
|
||||
GO
|
||||
GRANT SELECT ON dbo.Table_2 to nologon4
|
||||
GO
|
||||
REVOKE SELECT ON dbo.Table_2(column_2) TO nologon4
|
||||
GO
|
||||
GRANT SELECT ON dbo.View_1 to nologon4
|
||||
GO
|
||||
GRANT SELECT ON dbo.EncryptedView(A) to nologon4
|
||||
GO
|
||||
GRANT EXECUTE ON dbo.Procedure1 TO nologon4
|
||||
GO
|
||||
GRANT EXECUTE ON dbo.CLR_SimpleResultsetProcedure TO nologon4
|
||||
GO
|
||||
GRANT EXECUTE ON dbo.EncryptedProcedure TO nologon4
|
||||
GO
|
||||
GRANT VIEW DEFINITION ON CERTIFICATE :: Certificate1 TO nologon4
|
||||
GO
|
||||
GRANT EXECUTE ON dbo.ScalarFunction1 TO nologon4
|
||||
GO
|
||||
GRANT EXECUTE ON dbo.EncryptedFunction TO nologon4
|
||||
GO
|
||||
GRANT SELECT ON dbo.InlineFunction_1 TO nologon4
|
||||
GO
|
||||
GRANT SELECT ON dbo.TableFunction1 TO nologon4
|
||||
GO
|
||||
GRANT SELECT ON dbo.CLRTableValueFunction TO nologon4
|
||||
GO
|
||||
GRANT VIEW DEFINITION ON TYPE::dbo.dataType To nologon4
|
||||
GO
|
||||
GRANT VIEW DEFINITION ON FULLTEXT CATALOG ::FullTextCatalog1 To nologon4
|
||||
GO
|
||||
GRANT VIEW DEFINITION ON XML SCHEMA COLLECTION :: dbo.XmlSchemaCollection To nologon4
|
||||
GO
|
||||
GRANT VIEW DEFINITION ON ASSEMBLY :: [Geometry] To nologon4
|
||||
GO
|
||||
GRANT VIEW DEFINITION ON TYPE:: dbo.Angle To nologon4
|
||||
GO
|
||||
GRANT VIEW DEFINITION ON dbo.[Concat] To nologon4
|
||||
GO
|
||||
GRANT VIEW DEFINITION ON dbo.Synonym_1 To nologon4
|
||||
GO
|
||||
GRANT VIEW DEFINITION ON SCHEMA :: Schema1 To nologon4
|
||||
GO
|
||||
GRANT VIEW DEFINITION ON SYMMETRIC KEY :: SymKey1 To nologon4
|
||||
GO
|
||||
GRANT VIEW DEFINITION ON ASYMMETRIC KEY :: AsmKey1 To nologon4
|
||||
GO
|
||||
GRANT VIEW DEFINITION ON dbo.Queue1 To nologon4
|
||||
GO
|
||||
GRANT VIEW DEFINITION ON dbo.NotifyQueue To nologon4
|
||||
GO
|
||||
GRANT VIEW DEFINITION ON SERVICE :: Service1 To nologon4
|
||||
GO
|
||||
GRANT VIEW DEFINITION ON SERVICE :: NotifyService To nologon4
|
||||
GO
|
||||
GRANT VIEW DEFINITION ON CONTRACT :: Contract1 To nologon4
|
||||
GO
|
||||
GRANT VIEW DEFINITION ON MESSAGE TYPE :: MessageType1 To nologon4
|
||||
GO
|
||||
GRANT VIEW DEFINITION ON ROUTE :: AutoCreatedLocal To nologon4
|
||||
GO
|
||||
GRANT VIEW DEFINITION ON ROUTE :: Route1 To nologon4
|
||||
GO
|
||||
GRANT VIEW DEFINITION ON REMOTE SERVICE BINDING :: ServiceBinding1 To nologon4
|
||||
GO
|
||||
GRANT SELECT ON dbo.referenced_table To nologon4
|
||||
GO
|
||||
GRANT SELECT ON dbo.TableFunctionWithComputedColumns To nologon4
|
||||
GO
|
||||
GRANT SELECT ON dbo.TableFunctionWithComputedColumnsEncrypted To nologon4
|
||||
GO
|
||||
GRANT SELECT ON dbo.View_2 TO nologon4
|
||||
GO
|
||||
GRANT SELECT ON dbo.MultipleIndexTable TO nologon4
|
||||
GO
|
||||
GRANT SELECT ON dbo.Table_3 TO nologon4
|
||||
GO
|
||||
GRANT SELECT ON dbo.Different_WithAppend_Table TO nologon4
|
||||
GO
|
||||
GRANT SELECT ON dbo.[EncryptedFunctionWithConstraints] TO nologon4
|
||||
GO
|
||||
@@ -8,6 +8,7 @@ using Microsoft.SqlTools.Credentials;
|
||||
using Microsoft.SqlTools.ServiceLayer.Connection;
|
||||
using Microsoft.SqlTools.ServiceLayer.Connection.Contracts;
|
||||
using Microsoft.SqlTools.ServiceLayer.Hosting;
|
||||
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer;
|
||||
using Microsoft.SqlTools.ServiceLayer.QueryExecution;
|
||||
using Microsoft.SqlTools.ServiceLayer.SqlContext;
|
||||
using Microsoft.SqlTools.ServiceLayer.Workspace;
|
||||
@@ -43,6 +44,15 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Common
|
||||
{
|
||||
return CredentialService.Instance;
|
||||
}
|
||||
}
|
||||
|
||||
public ObjectExplorerService ObjectExplorerService
|
||||
{
|
||||
get
|
||||
{
|
||||
var serviceProvider = ServiceHost.Instance.ServiceProvider;
|
||||
return serviceProvider.GetService<ObjectExplorerService>();
|
||||
}
|
||||
}
|
||||
|
||||
public TestConnectionProfileService ConnectionProfileService
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
"includeFiles": [
|
||||
"Scripts/CreateTestDatabaseObjects.sql",
|
||||
"Scripts/CreateTestDatabase.sql",
|
||||
"Scripts/TestDbTableQueries.sql"
|
||||
"Scripts/TestDbTableQueries.sql",
|
||||
"Scripts/AdventureWorks.sql"
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
@@ -0,0 +1,369 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.SqlClient;
|
||||
using System.Globalization;
|
||||
using Microsoft.SqlServer.Management.Common;
|
||||
using Microsoft.SqlServer.Management.Smo;
|
||||
using Microsoft.SqlTools.Extensibility;
|
||||
using Microsoft.SqlTools.ServiceLayer.Connection;
|
||||
using Microsoft.SqlTools.ServiceLayer.Connection.Contracts;
|
||||
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer;
|
||||
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Contracts;
|
||||
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes;
|
||||
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel;
|
||||
using Microsoft.SqlTools.ServiceLayer.UnitTests.Utility;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.UnitTests.ObjectExplorer
|
||||
{
|
||||
/// <summary>
|
||||
/// Tests covering basic operation of Node based classes
|
||||
/// </summary>
|
||||
public class NodeTests : ObjectExplorerTestBase
|
||||
{
|
||||
private string defaultOwnerUri = "objectexplorer://myserver";
|
||||
private ServerInfo defaultServerInfo;
|
||||
private ConnectionDetails defaultConnectionDetails;
|
||||
private ConnectionCompleteParams defaultConnParams;
|
||||
private string fakeConnectionString = "Data Source=server;Initial Catalog=database;Integrated Security=False;User Id=user";
|
||||
|
||||
public NodeTests()
|
||||
{
|
||||
defaultServerInfo = TestObjects.GetTestServerInfo();
|
||||
|
||||
defaultConnectionDetails = new ConnectionDetails()
|
||||
{
|
||||
DatabaseName = "master",
|
||||
ServerName = "localhost",
|
||||
UserName = "serverAdmin",
|
||||
Password = "..."
|
||||
};
|
||||
defaultConnParams = new ConnectionCompleteParams()
|
||||
{
|
||||
ServerInfo = defaultServerInfo,
|
||||
ConnectionSummary = defaultConnectionDetails,
|
||||
OwnerUri = defaultOwnerUri
|
||||
};
|
||||
|
||||
// TODO can all tests use the standard service provider?
|
||||
ServiceProvider = ExtensionServiceProvider.CreateDefaultServiceProvider();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ServerNodeConstructorValidatesFields()
|
||||
{
|
||||
Assert.Throws<ArgumentNullException>(() => new ServerNode(null, ServiceProvider));
|
||||
Assert.Throws<ArgumentNullException>(() => new ServerNode(defaultConnParams, null));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ServerNodeConstructorShouldSetValuesCorrectly()
|
||||
{
|
||||
// Given a server node with valid inputs
|
||||
ServerNode node = new ServerNode(defaultConnParams, ServiceProvider);
|
||||
// Then expect all fields set correctly
|
||||
Assert.False(node.IsAlwaysLeaf, "Server node should never be a leaf");
|
||||
Assert.Equal(defaultConnectionDetails.ServerName, node.NodeValue);
|
||||
|
||||
string expectedLabel = defaultConnectionDetails.ServerName + " (SQL Server " + defaultServerInfo.ServerVersion + " - "
|
||||
+ defaultConnectionDetails.UserName + ")";
|
||||
Assert.Equal(expectedLabel, node.Label);
|
||||
|
||||
Assert.Equal(NodeTypes.ServerInstance.ToString(), node.NodeType);
|
||||
string[] nodePath = node.GetNodePath().Split(TreeNode.PathPartSeperator);
|
||||
Assert.Equal(1, nodePath.Length);
|
||||
Assert.Equal(defaultConnectionDetails.ServerName, nodePath[0]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ServerNodeLabelShouldIgnoreUserNameIfEmptyOrNull()
|
||||
{
|
||||
// Given no username set
|
||||
ConnectionSummary integratedAuthSummary = new ConnectionSummary()
|
||||
{
|
||||
DatabaseName = defaultConnectionDetails.DatabaseName,
|
||||
ServerName = defaultConnectionDetails.ServerName,
|
||||
UserName = null
|
||||
};
|
||||
ConnectionCompleteParams connParams = new ConnectionCompleteParams()
|
||||
{
|
||||
ConnectionSummary = integratedAuthSummary,
|
||||
ServerInfo = defaultServerInfo,
|
||||
OwnerUri = defaultOwnerUri
|
||||
};
|
||||
// When querying label
|
||||
string label = new ServerNode(connParams, ServiceProvider).Label;
|
||||
// Then only server name and version shown
|
||||
string expectedLabel = defaultConnectionDetails.ServerName + " (SQL Server " + defaultServerInfo.ServerVersion + ")";
|
||||
Assert.Equal(expectedLabel, label);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ServerNodeConstructorShouldShowDbNameForCloud()
|
||||
{
|
||||
defaultServerInfo.IsCloud = true;
|
||||
|
||||
// Given a server node for a cloud DB, with master name
|
||||
ServerNode node = new ServerNode(defaultConnParams, ServiceProvider);
|
||||
// Then expect label to not include db name
|
||||
string expectedLabel = defaultConnectionDetails.ServerName + " (SQL Server " + defaultServerInfo.ServerVersion + " - "
|
||||
+ defaultConnectionDetails.UserName + ")";
|
||||
Assert.Equal(expectedLabel, node.Label);
|
||||
|
||||
// But given a server node for a cloud DB that's not master
|
||||
defaultConnectionDetails.DatabaseName = "NotMaster";
|
||||
node = new ServerNode(defaultConnParams, ServiceProvider);
|
||||
|
||||
// Then expect label to include db name
|
||||
expectedLabel = defaultConnectionDetails.ServerName + " (SQL Server " + defaultServerInfo.ServerVersion + " - "
|
||||
+ defaultConnectionDetails.UserName + ", " + defaultConnectionDetails.DatabaseName + ")";
|
||||
Assert.Equal(expectedLabel, node.Label);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ToNodeInfoIncludeAllFields()
|
||||
{
|
||||
// Given a server connection
|
||||
ServerNode node = new ServerNode(defaultConnParams, ServiceProvider);
|
||||
// When converting to NodeInfo
|
||||
NodeInfo info = node.ToNodeInfo();
|
||||
// Then all fields should match
|
||||
Assert.Equal(node.IsAlwaysLeaf, info.IsLeaf);
|
||||
Assert.Equal(node.Label, info.Label);
|
||||
Assert.Equal(node.NodeType, info.NodeType);
|
||||
string[] nodePath = node.GetNodePath().Split(TreeNode.PathPartSeperator);
|
||||
string[] nodeInfoPathParts = info.NodePath.Split(TreeNode.PathPartSeperator);
|
||||
Assert.Equal(nodePath.Length, nodeInfoPathParts.Length);
|
||||
for (int i = 0; i < nodePath.Length; i++)
|
||||
{
|
||||
Assert.Equal(nodePath[i], nodeInfoPathParts[i]);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AddChildShouldSetParent()
|
||||
{
|
||||
TreeNode parent = new TreeNode("parent");
|
||||
TreeNode child = new TreeNode("child");
|
||||
Assert.Null(child.Parent);
|
||||
parent.AddChild(child);
|
||||
Assert.Equal(parent, child.Parent);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetChildrenShouldReturnReadonlyList()
|
||||
{
|
||||
TreeNode node = new TreeNode("parent");
|
||||
IList<TreeNode> children = node.GetChildren();
|
||||
Assert.Throws<NotSupportedException>(() => children.Add(new TreeNode("child")));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetChildrenShouldReturnAddedNodesInOrder()
|
||||
{
|
||||
TreeNode parent = new TreeNode("parent");
|
||||
TreeNode[] expectedKids = new TreeNode[] { new TreeNode("1"), new TreeNode("2") };
|
||||
foreach (TreeNode child in expectedKids)
|
||||
{
|
||||
parent.AddChild(child);
|
||||
}
|
||||
IList<TreeNode> children = parent.GetChildren();
|
||||
Assert.Equal(expectedKids.Length, children.Count);
|
||||
for (int i = 0; i < expectedKids.Length; i++)
|
||||
{
|
||||
Assert.Equal(expectedKids[i], children[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public void MultiLevelTreeShouldFormatPath()
|
||||
{
|
||||
TreeNode root = new TreeNode("root");
|
||||
Assert.Equal("/root" , root.GetNodePath());
|
||||
|
||||
TreeNode level1Child1 = new TreeNode("L1C1");
|
||||
TreeNode level1Child2 = new TreeNode("L1C2");
|
||||
root.AddChild(level1Child1);
|
||||
root.AddChild(level1Child2);
|
||||
Assert.Equal("/root/L1C1" , level1Child1.GetNodePath());
|
||||
Assert.Equal("/root/L1C2", level1Child2.GetNodePath());
|
||||
|
||||
TreeNode level2Child1 = new TreeNode("L2C2");
|
||||
level1Child1.AddChild(level2Child1);
|
||||
Assert.Equal("/root/L1C1/L2C2", level2Child1.GetNodePath());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ServerNodeContextShouldIncludeServer()
|
||||
{
|
||||
// given a successful Server creation
|
||||
SetupAndRegisterTestConnectionService();
|
||||
Server smoServer = new Server(new ServerConnection(new SqlConnection(fakeConnectionString)));
|
||||
ServerNode node = SetupServerNodeWithServer(smoServer);
|
||||
|
||||
// When I get the context for a ServerNode
|
||||
var context = node.GetContextAs<SmoQueryContext>();
|
||||
|
||||
// Then I expect it to contain the server I created
|
||||
Assert.NotNull(context);
|
||||
Assert.Equal(smoServer, context.Server);
|
||||
// And the server should be the parent
|
||||
Assert.Equal(smoServer, context.Parent);
|
||||
Assert.Null(context.Database);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ServerNodeContextShouldSetErrorMessageIfSqlConnectionIsNull()
|
||||
{
|
||||
// given a connectionInfo with no SqlConnection to use for queries
|
||||
ConnectionService connService = SetupAndRegisterTestConnectionService();
|
||||
connService.OwnerToConnectionMap.Remove(defaultOwnerUri);
|
||||
|
||||
Server smoServer = new Server(new ServerConnection(new SqlConnection(fakeConnectionString)));
|
||||
ServerNode node = SetupServerNodeWithServer(smoServer);
|
||||
|
||||
// When I get the context for a ServerNode
|
||||
var context = node.GetContextAs<SmoQueryContext>();
|
||||
|
||||
// Then I expect it to be in an error state
|
||||
Assert.Null(context);
|
||||
Assert.Equal(
|
||||
string.Format(CultureInfo.CurrentCulture, SR.ServerNodeConnectionError, defaultConnectionDetails.ServerName),
|
||||
node.ErrorStateMessage);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ServerNodeContextShouldSetErrorMessageIfConnFailureExceptionThrown()
|
||||
{
|
||||
// given a connectionInfo with no SqlConnection to use for queries
|
||||
SetupAndRegisterTestConnectionService();
|
||||
|
||||
Server smoServer = new Server(new ServerConnection(new SqlConnection(fakeConnectionString)));
|
||||
string expectedMsg = "ConnFailed!";
|
||||
ServerNode node = SetupServerNodeWithExceptionCreator(new ConnectionFailureException(expectedMsg));
|
||||
|
||||
// When I get the context for a ServerNode
|
||||
var context = node.GetContextAs<SmoQueryContext>();
|
||||
|
||||
// Then I expect it to be in an error state
|
||||
Assert.Null(context);
|
||||
Assert.Equal(
|
||||
string.Format(CultureInfo.CurrentCulture, SR.TreeNodeError, expectedMsg),
|
||||
node.ErrorStateMessage);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ServerNodeContextShouldSetErrorMessageIfExceptionThrown()
|
||||
{
|
||||
// given a connectionInfo with no SqlConnection to use for queries
|
||||
SetupAndRegisterTestConnectionService();
|
||||
|
||||
Server smoServer = new Server(new ServerConnection(new SqlConnection(fakeConnectionString)));
|
||||
string expectedMsg = "Failed!";
|
||||
ServerNode node = SetupServerNodeWithExceptionCreator(new Exception(expectedMsg));
|
||||
|
||||
// When I get the context for a ServerNode
|
||||
var context = node.GetContextAs<SmoQueryContext>();
|
||||
|
||||
// Then I expect it to be in an error state
|
||||
Assert.Null(context);
|
||||
Assert.Equal(
|
||||
string.Format(CultureInfo.CurrentCulture, SR.TreeNodeError, expectedMsg),
|
||||
node.ErrorStateMessage);
|
||||
}
|
||||
|
||||
private ConnectionService SetupAndRegisterTestConnectionService()
|
||||
{
|
||||
ConnectionService connService = TestObjects.GetTestConnectionService();
|
||||
ConnectionInfo connectionInfo = new ConnectionInfo(TestObjects.GetTestSqlConnectionFactory(),
|
||||
defaultOwnerUri, defaultConnectionDetails);
|
||||
connectionInfo.AddConnection("Default", new SqlConnection());
|
||||
|
||||
connService.OwnerToConnectionMap.Add(defaultOwnerUri, connectionInfo);
|
||||
ServiceProvider.RegisterSingleService(connService);
|
||||
return connService;
|
||||
}
|
||||
|
||||
private ServerNode SetupServerNodeWithServer(Server smoServer)
|
||||
{
|
||||
Mock<SmoServerCreator> creator = new Mock<SmoServerCreator>();
|
||||
creator.Setup(c => c.Create(It.IsAny<SqlConnection>()))
|
||||
.Returns(() => smoServer);
|
||||
ServerNode node = SetupServerNodeWithCreator(creator.Object);
|
||||
return node;
|
||||
}
|
||||
|
||||
private ServerNode SetupServerNodeWithExceptionCreator(Exception ex)
|
||||
{
|
||||
Mock<SmoServerCreator> creator = new Mock<SmoServerCreator>();
|
||||
creator.Setup(c => c.Create(It.IsAny<SqlConnection>()))
|
||||
.Throws(ex);
|
||||
|
||||
ServerNode node = SetupServerNodeWithCreator(creator.Object);
|
||||
return node;
|
||||
}
|
||||
|
||||
private ServerNode SetupServerNodeWithCreator(SmoServerCreator creator)
|
||||
{
|
||||
ServerNode node = new ServerNode(defaultConnParams, ServiceProvider);
|
||||
node.ServerCreator = creator;
|
||||
return node;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ServerNodeChildrenShouldIncludeFoldersAndDatabases()
|
||||
{
|
||||
// Given a server with 1 database
|
||||
SetupAndRegisterTestConnectionService();
|
||||
ServiceProvider.RegisterSingleService(new ObjectExplorerService());
|
||||
|
||||
string dbName = "DB1";
|
||||
Mock<NamedSmoObject> smoObjectMock = new Mock<NamedSmoObject>();
|
||||
smoObjectMock.SetupGet(s => s.Name).Returns(dbName);
|
||||
|
||||
Mock<SqlDatabaseQuerier> querierMock = new Mock<SqlDatabaseQuerier>();
|
||||
querierMock.Setup(q => q.Query(It.IsAny<SmoQueryContext>()))
|
||||
.Returns(smoObjectMock.Object.SingleItemAsEnumerable());
|
||||
|
||||
ServiceProvider.Register<SmoQuerier>(() => new[] { querierMock.Object });
|
||||
|
||||
Server smoServer = new Server(new ServerConnection(new SqlConnection(fakeConnectionString)));
|
||||
ServerNode node = SetupServerNodeWithServer(smoServer);
|
||||
|
||||
// When I populate its children
|
||||
IList<TreeNode> children = node.Expand();
|
||||
|
||||
// Then I expect it to contain server-level folders
|
||||
Assert.Equal(3, children.Count);
|
||||
VerifyTreeNode<FolderNode>(children[0], "Folder", SR.SchemaHierarchy_Databases);
|
||||
VerifyTreeNode<FolderNode>(children[1], "Folder", SR.SchemaHierarchy_Security);
|
||||
VerifyTreeNode<FolderNode>(children[2], "Folder", SR.SchemaHierarchy_ServerObjects);
|
||||
// And the database is contained under it
|
||||
TreeNode databases = children[0];
|
||||
IList<TreeNode> dbChildren = databases.Expand();
|
||||
Assert.Equal(2, dbChildren.Count);
|
||||
Assert.Equal("System Databases", dbChildren[0].NodeValue);
|
||||
|
||||
TreeNode dbNode = dbChildren[1];
|
||||
Assert.Equal(dbName, dbNode.NodeValue);
|
||||
Assert.Equal(dbName, dbNode.Label);
|
||||
Assert.False(dbNode.IsAlwaysLeaf);
|
||||
|
||||
// Note: would like to verify Database in the context, but cannot since it's a Sealed class and isn't easily mockable
|
||||
}
|
||||
|
||||
private void VerifyTreeNode<T>(TreeNode node, string nodeType, string folderValue)
|
||||
where T : TreeNode
|
||||
{
|
||||
T nodeAsT = node as T;
|
||||
Assert.NotNull(nodeAsT);
|
||||
Assert.Equal(nodeType, nodeAsT.NodeType);
|
||||
Assert.Equal(folderValue, nodeAsT.NodeValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.SqlTools.Hosting.Protocol;
|
||||
using Microsoft.SqlTools.ServiceLayer.Connection;
|
||||
using Microsoft.SqlTools.ServiceLayer.Connection.Contracts;
|
||||
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer;
|
||||
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Contracts;
|
||||
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes;
|
||||
using Microsoft.SqlTools.ServiceLayer.Test.Common;
|
||||
using Microsoft.SqlTools.ServiceLayer.UnitTests.Utility;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.UnitTests.ObjectExplorer
|
||||
{
|
||||
|
||||
public class ObjectExplorerServiceTests : ObjectExplorerTestBase
|
||||
{
|
||||
private ObjectExplorerService service;
|
||||
private Mock<ConnectionService> connectionServiceMock;
|
||||
private Mock<IProtocolEndpoint> serviceHostMock;
|
||||
public ObjectExplorerServiceTests()
|
||||
{
|
||||
connectionServiceMock = new Mock<ConnectionService>();
|
||||
serviceHostMock = new Mock<IProtocolEndpoint>();
|
||||
service = CreateOEService(connectionServiceMock.Object);
|
||||
service.InitializeService(serviceHostMock.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CreateSessionRequestErrorsIfConnectionDetailsIsNull()
|
||||
{
|
||||
object errorResponse = null;
|
||||
var contextMock = RequestContextMocks.Create<CreateSessionResponse>(null)
|
||||
.AddErrorHandling((errorMessage, errorCode, obj) => errorResponse = errorMessage);
|
||||
|
||||
await service.HandleCreateSessionRequest(null, contextMock.Object);
|
||||
VerifyErrorSent(contextMock);
|
||||
Assert.True(((string)errorResponse).Contains("ArgumentNullException"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CreateSessionRequestReturnsFalseOnConnectionFailure()
|
||||
{
|
||||
// Given the connection service fails to connect
|
||||
ConnectionDetails details = TestObjects.GetTestConnectionDetails();
|
||||
ConnectionCompleteParams completeParams = null;
|
||||
serviceHostMock.AddEventHandling(ConnectionCompleteNotification.Type, (et, p) => completeParams = p);
|
||||
|
||||
string expectedExceptionText = "Error!!!";
|
||||
connectionServiceMock.Setup(c => c.Connect(It.IsAny<ConnectParams>()))
|
||||
.Throws(new Exception(expectedExceptionText));
|
||||
|
||||
// when creating a new session
|
||||
// then expect the create session request to return false
|
||||
await RunAndVerify<CreateSessionResponse>(
|
||||
test: (requestContext) => service.HandleCreateSessionRequest(details, requestContext),
|
||||
verify: (actual =>
|
||||
{
|
||||
Assert.False(actual.Success);
|
||||
Assert.Null(actual.SessionId);
|
||||
Assert.Null(actual.RootNode);
|
||||
}));
|
||||
|
||||
// And expect error notification to be sent
|
||||
serviceHostMock.Verify(x => x.SendEvent(ConnectionCompleteNotification.Type, It.IsAny<ConnectionCompleteParams>()), Times.Once());
|
||||
Assert.NotNull(completeParams);
|
||||
Assert.True(completeParams.Messages.Contains(expectedExceptionText));
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public async Task CreateSessionRequestReturnsSuccessAndNodeInfo()
|
||||
{
|
||||
// Given the connection service fails to connect
|
||||
ConnectionDetails details = TestObjects.GetTestConnectionDetails();
|
||||
serviceHostMock.AddEventHandling(ConnectionCompleteNotification.Type, null);
|
||||
|
||||
connectionServiceMock.Setup(c => c.Connect(It.IsAny<ConnectParams>()))
|
||||
.Returns((ConnectParams connectParams) => Task.FromResult(GetCompleteParamsForConnection(connectParams.OwnerUri, details)));
|
||||
|
||||
// when creating a new session
|
||||
// then expect the create session request to return false
|
||||
await RunAndVerify<CreateSessionResponse>(
|
||||
test: (requestContext) => service.HandleCreateSessionRequest(details, requestContext),
|
||||
verify: (actual =>
|
||||
{
|
||||
Assert.True(actual.Success);
|
||||
Assert.NotNull(actual.SessionId);
|
||||
VerifyServerNode(actual.RootNode, details);
|
||||
}));
|
||||
|
||||
// And expect no error notification to be sent
|
||||
serviceHostMock.Verify(x => x.SendEvent(ConnectionCompleteNotification.Type,
|
||||
It.IsAny<ConnectionCompleteParams>()), Times.Never());
|
||||
}
|
||||
|
||||
private void VerifyServerNode(NodeInfo serverNode, ConnectionDetails details)
|
||||
{
|
||||
Assert.NotNull(serverNode);
|
||||
Assert.Equal(NodeTypes.ServerInstance.ToString(), serverNode.NodeType);
|
||||
string[] pathParts = serverNode.NodePath.Split(TreeNode.PathPartSeperator);
|
||||
Assert.Equal(1, pathParts.Length);
|
||||
Assert.Equal(details.ServerName, pathParts[0]);
|
||||
Assert.True(serverNode.Label.Contains(details.ServerName));
|
||||
Assert.False(serverNode.IsLeaf);
|
||||
}
|
||||
|
||||
private static ConnectionCompleteParams GetCompleteParamsForConnection(string uri, ConnectionDetails details)
|
||||
{
|
||||
return new ConnectionCompleteParams()
|
||||
{
|
||||
OwnerUri = uri,
|
||||
ConnectionSummary = new ConnectionSummary()
|
||||
{
|
||||
ServerName = details.ServerName,
|
||||
DatabaseName = details.DatabaseName,
|
||||
UserName = details.UserName
|
||||
},
|
||||
ServerInfo = TestObjects.GetTestServerInfo()
|
||||
};
|
||||
}
|
||||
|
||||
private async Task RunAndVerify<T>(Func<RequestContext<T>, Task> test, Action<T> verify)
|
||||
{
|
||||
T result = default(T);
|
||||
var contextMock = RequestContextMocks.Create<T>(r => result = r).AddErrorHandling(null);
|
||||
await test(contextMock.Object);
|
||||
VerifyResult(contextMock, verify, result);
|
||||
}
|
||||
|
||||
private void VerifyResult<T>(Mock<RequestContext<T>> contextMock, Action<T> verify, T actual)
|
||||
{
|
||||
contextMock.Verify(c => c.SendResult(It.IsAny<T>()), Times.Once);
|
||||
contextMock.Verify(c => c.SendError(It.IsAny<string>(), It.IsAny<int>(), It.IsAny<object>()), Times.Never);
|
||||
verify(actual);
|
||||
}
|
||||
|
||||
private void VerifyErrorSent<T>(Mock<RequestContext<T>> contextMock)
|
||||
{
|
||||
contextMock.Verify(c => c.SendResult(It.IsAny<T>()), Times.Never);
|
||||
contextMock.Verify(c => c.SendError(It.IsAny<string>(), It.IsAny<int>(), It.IsAny<object>()), Times.Once);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
using Microsoft.SqlTools.Extensibility;
|
||||
using Microsoft.SqlTools.ServiceLayer.Connection;
|
||||
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.UnitTests.ObjectExplorer
|
||||
{
|
||||
// Base class providing common test functionality for OE tests
|
||||
public abstract class ObjectExplorerTestBase
|
||||
{
|
||||
protected RegisteredServiceProvider ServiceProvider
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
protected RegisteredServiceProvider CreateServiceProviderWithMinServices()
|
||||
{
|
||||
return CreateProvider()
|
||||
.RegisterSingleService(new ConnectionService())
|
||||
.RegisterSingleService(new ObjectExplorerService());
|
||||
}
|
||||
|
||||
protected RegisteredServiceProvider CreateProvider()
|
||||
{
|
||||
ServiceProvider = new RegisteredServiceProvider();
|
||||
return ServiceProvider;
|
||||
}
|
||||
|
||||
protected ObjectExplorerService CreateOEService(ConnectionService connService)
|
||||
{
|
||||
CreateProvider()
|
||||
.RegisterSingleService(connService)
|
||||
.RegisterSingleService(new ObjectExplorerService());
|
||||
|
||||
// Create the service using the service provider, which will initialize dependencies
|
||||
return ServiceProvider.GetService<ObjectExplorerService>();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Microsoft.SqlServer.Management.Smo;
|
||||
using Microsoft.SqlTools.Extensibility;
|
||||
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.UnitTests.ObjectExplorer
|
||||
{
|
||||
public class SmoQueryModelTests
|
||||
{
|
||||
|
||||
[Fact]
|
||||
public void ShouldFindDatabaseQuerierFromRealPath()
|
||||
{
|
||||
// Given the extension type loader is set to find SmoCollectionQuerier objects
|
||||
IMultiServiceProvider serviceProvider = ExtensionServiceProvider.CreateDefaultServiceProvider();
|
||||
// When I request a database compatible querier
|
||||
SmoQuerier querier = serviceProvider.GetService<SmoQuerier>(q => q.SupportedObjectTypes.Contains(typeof(Database)));
|
||||
// Then I expect to get back the SqlDatabaseQuerier
|
||||
Assert.NotNull(querier);
|
||||
Assert.Equal(typeof(SqlDatabaseQuerier), querier.GetType());
|
||||
|
||||
// And I expect the service provider to have been set by the extension code
|
||||
Assert.NotNull(querier.ServiceProvider);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ShouldFindQuerierIfInExtensionList()
|
||||
{
|
||||
VerifyQuerierLookup(typeof(Table), typeof(SqlTableQuerier), expectExists: true);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ShouldNotFindQuerierIfNotInExtensionList()
|
||||
{
|
||||
VerifyQuerierLookup(typeof(Database), null, expectExists: false);
|
||||
}
|
||||
|
||||
private static void VerifyQuerierLookup(Type smoType, Type querierType, bool expectExists)
|
||||
{
|
||||
ExtensionServiceProvider serviceProvider = ExtensionServiceProvider.Create(new Type[] {
|
||||
typeof(SqlTableQuerier),
|
||||
typeof(SqlLinkedServerQuerier)
|
||||
});
|
||||
SmoQuerier querier = serviceProvider.GetService<SmoQuerier>(q => q.SupportedObjectTypes.Contains(smoType));
|
||||
if (expectExists)
|
||||
{
|
||||
Assert.NotNull(querier);
|
||||
Assert.Equal(querierType, querier.GetType());
|
||||
Assert.NotNull(querier.ServiceProvider);
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.Null(querier);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -43,6 +43,169 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.ServiceHost
|
||||
var queryServiceErrorFormat = SR.QueryServiceErrorFormat(1, 1, 1, 1, "\n", "..");
|
||||
var queryServiceQueryFailed = SR.QueryServiceQueryFailed("..");
|
||||
var workspaceServiceBufferPositionOutOfOrder = SR.WorkspaceServiceBufferPositionOutOfOrder(1, 2, 3, 4);
|
||||
var treeNodeError = SR.TreeNodeError;
|
||||
var serverNodeConnectionError = SR.ServerNodeConnectionError;
|
||||
var schemaHierarchyAggregates = SR.SchemaHierarchy_Aggregates;
|
||||
var SchemaHierarchy_ServerRoles = SR.SchemaHierarchy_ServerRoles;
|
||||
var SchemaHierarchy_ApplicationRoles = SR.SchemaHierarchy_ApplicationRoles;
|
||||
var SchemaHierarchy_Assemblies = SR.SchemaHierarchy_Assemblies;
|
||||
var SchemaHierarchy_AssemblyFiles = SR.SchemaHierarchy_AssemblyFiles;
|
||||
var SchemaHierarchy_AsymmetricKeys = SR.SchemaHierarchy_AsymmetricKeys;
|
||||
var SchemaHierarchy_DatabaseAsymmetricKeys = SR.SchemaHierarchy_DatabaseAsymmetricKeys;
|
||||
var SchemaHierarchy_DataCompressionOptions = SR.SchemaHierarchy_DataCompressionOptions;
|
||||
var SchemaHierarchy_Certificates = SR.SchemaHierarchy_Certificates;
|
||||
var SchemaHierarchy_FileTables = SR.SchemaHierarchy_FileTables;
|
||||
var SchemaHierarchy_DatabaseCertificates = SR.SchemaHierarchy_DatabaseCertificates;
|
||||
var SchemaHierarchy_CheckConstraints = SR.SchemaHierarchy_CheckConstraints;
|
||||
var SchemaHierarchy_Columns = SR.SchemaHierarchy_Columns;
|
||||
var SchemaHierarchy_Constraints = SR.SchemaHierarchy_Constraints;
|
||||
var SchemaHierarchy_Contracts = SR.SchemaHierarchy_Contracts;
|
||||
var SchemaHierarchy_Credentials = SR.SchemaHierarchy_Credentials;
|
||||
var SchemaHierarchy_ErrorMessages = SR.SchemaHierarchy_ErrorMessages;
|
||||
var SchemaHierarchy_ServerRoleMembership = SR.SchemaHierarchy_ServerRoleMembership;
|
||||
var SchemaHierarchy_DatabaseOptions = SR.SchemaHierarchy_DatabaseOptions;
|
||||
var SchemaHierarchy_DatabaseRoles = SR.SchemaHierarchy_DatabaseRoles;
|
||||
var SchemaHierarchy_RoleMemberships = SR.SchemaHierarchy_RoleMemberships;
|
||||
var SchemaHierarchy_DatabaseTriggers = SR.SchemaHierarchy_DatabaseTriggers;
|
||||
var SchemaHierarchy_DefaultConstraints = SR.SchemaHierarchy_DefaultConstraints;
|
||||
var SchemaHierarchy_Defaults = SR.SchemaHierarchy_Defaults;
|
||||
var SchemaHierarchy_Sequences = SR.SchemaHierarchy_Sequences;
|
||||
var SchemaHierarchy_Endpoints = SR.SchemaHierarchy_Endpoints;
|
||||
var SchemaHierarchy_EventNotifications = SR.SchemaHierarchy_EventNotifications;
|
||||
var SchemaHierarchy_ServerEventNotifications = SR.SchemaHierarchy_ServerEventNotifications;
|
||||
var SchemaHierarchy_ExtendedProperties = SR.SchemaHierarchy_ExtendedProperties;
|
||||
var SchemaHierarchy_FileGroups = SR.SchemaHierarchy_FileGroups;
|
||||
var SchemaHierarchy_ForeignKeys = SR.SchemaHierarchy_ForeignKeys;
|
||||
var SchemaHierarchy_FullTextCatalogs = SR.SchemaHierarchy_FullTextCatalogs;
|
||||
var SchemaHierarchy_FullTextIndexes = SR.SchemaHierarchy_FullTextIndexes;
|
||||
var SchemaHierarchy_Functions = SR.SchemaHierarchy_Functions;
|
||||
var SchemaHierarchy_Indexes = SR.SchemaHierarchy_Indexes;
|
||||
var SchemaHierarchy_InlineFunctions = SR.SchemaHierarchy_InlineFunctions;
|
||||
var SchemaHierarchy_Keys = SR.SchemaHierarchy_Keys;
|
||||
var SchemaHierarchy_LinkedServers = SR.SchemaHierarchy_LinkedServers;
|
||||
var SchemaHierarchy_LinkedServerLogins = SR.SchemaHierarchy_LinkedServerLogins;
|
||||
var SchemaHierarchy_Logins = SR.SchemaHierarchy_Logins;
|
||||
var SchemaHierarchy_MasterKey = SR.SchemaHierarchy_MasterKey;
|
||||
var SchemaHierarchy_MasterKeys = SR.SchemaHierarchy_MasterKeys;
|
||||
var SchemaHierarchy_MessageTypes = SR.SchemaHierarchy_MessageTypes;
|
||||
var SchemaHierarchy_MultiSelectFunctions = SR.SchemaHierarchy_MultiSelectFunctions;
|
||||
var SchemaHierarchy_Parameters = SR.SchemaHierarchy_Parameters;
|
||||
var SchemaHierarchy_PartitionFunctions = SR.SchemaHierarchy_PartitionFunctions;
|
||||
var SchemaHierarchy_PartitionSchemes = SR.SchemaHierarchy_PartitionSchemes;
|
||||
var SchemaHierarchy_Permissions = SR.SchemaHierarchy_Permissions;
|
||||
var SchemaHierarchy_PrimaryKeys = SR.SchemaHierarchy_PrimaryKeys;
|
||||
var schemaHierarchyPrimaryKeys = SR.SchemaHierarchy_PrimaryKeys;
|
||||
var schemaHierarchyProgrammability = SR.SchemaHierarchy_Programmability;
|
||||
var schemaHierarchyQueues = SR.SchemaHierarchy_Queues;
|
||||
var schemaHierarchyRemoteServiceBindings = SR.SchemaHierarchy_RemoteServiceBindings;
|
||||
var schemaHierarchyReturnedColumns = SR.SchemaHierarchy_ReturnedColumns;
|
||||
var schemaHierarchyRoles = SR.SchemaHierarchy_Roles;
|
||||
var schemaHierarchyRoutes = SR.SchemaHierarchy_Routes;
|
||||
var schemaHierarchyRules = SR.SchemaHierarchy_Rules;
|
||||
var schemaHierarchySchemas = SR.SchemaHierarchy_Schemas;
|
||||
var schemaHierarchySecurity = SR.SchemaHierarchy_Security;
|
||||
var schemaHierarchyServerObjects = SR.SchemaHierarchy_ServerObjects;
|
||||
var schemaHierarchyManagement = SR.SchemaHierarchy_Management;
|
||||
var schemaHierarchyServerTriggers = SR.SchemaHierarchy_ServerTriggers;
|
||||
var schemaHierarchyServiceBroker = SR.SchemaHierarchy_ServiceBroker;
|
||||
var schemaHierarchyServices = SR.SchemaHierarchy_Services;
|
||||
var schemaHierarchySignatures = SR.SchemaHierarchy_LogFiles;
|
||||
var schemaHierarchyStatistics = SR.SchemaHierarchy_Statistics;
|
||||
var schemaHierarchyStorage = SR.SchemaHierarchy_Storage;
|
||||
var schemaHierarchyStoredProcedures = SR.SchemaHierarchy_StoredProcedures;
|
||||
var schemaHierarchySymmetricKeys = SR.SchemaHierarchy_SymmetricKeys;
|
||||
var schemaHierarchySynonyms = SR.SchemaHierarchy_Synonyms;
|
||||
var schemaHierarchyTables = SR.SchemaHierarchy_Tables;
|
||||
var schemaHierarchyTriggers = SR.SchemaHierarchy_Triggers;
|
||||
var schemaHierarchyTypes = SR.SchemaHierarchy_Types;
|
||||
var schemaHierarchyUniqueKeys = SR.SchemaHierarchy_UniqueKeys;
|
||||
var schemaHierarchyUserDefinedDataTypes = SR.SchemaHierarchy_UserDefinedDataTypes;
|
||||
var schemaHierarchyUserDefinedTypes = SR.SchemaHierarchy_UserDefinedTypes;
|
||||
var schemaHierarchyUsers = SR.SchemaHierarchy_Users;
|
||||
var schemaHierarchyViews = SR.SchemaHierarchy_Views;
|
||||
var schemaHierarchyXmlIndexes = SR.SchemaHierarchy_XmlIndexes;
|
||||
var schemaHierarchyXMLSchemaCollections = SR.SchemaHierarchy_XMLSchemaCollections;
|
||||
var schemaHierarchyUserDefinedTableTypes = SR.SchemaHierarchy_UserDefinedTableTypes;
|
||||
var schemaHierarchyFilegroupFiles = SR.SchemaHierarchy_FilegroupFiles;
|
||||
var missingCaption = SR.MissingCaption;
|
||||
var schemaHierarchyBrokerPriorities = SR.SchemaHierarchy_BrokerPriorities;
|
||||
var schemaHierarchyCryptographicProviders = SR.SchemaHierarchy_CryptographicProviders;
|
||||
var schemaHierarchyDatabaseAuditSpecifications = SR.SchemaHierarchy_DatabaseAuditSpecifications;
|
||||
var schemaHierarchyDatabaseEncryptionKeys = SR.SchemaHierarchy_DatabaseEncryptionKeys;
|
||||
var schemaHierarchyEventSessions = SR.SchemaHierarchy_EventSessions;
|
||||
var schemaHierarchyFullTextStopLists = SR.SchemaHierarchy_FullTextStopLists;
|
||||
var schemaHierarchyResourcePools = SR.SchemaHierarchy_ResourcePools;
|
||||
var schemaHierarchyServerAudits = SR.SchemaHierarchy_ServerAudits;
|
||||
var schemaHierarchyServerAuditSpecifications = SR.SchemaHierarchy_ServerAuditSpecifications;
|
||||
var schemaHierarchySpatialIndexes = SR.SchemaHierarchy_SpatialIndexes;
|
||||
var schemaHierarchyWorkloadGroups = SR.SchemaHierarchy_WorkloadGroups;
|
||||
var schemaHierarchySqlFiles = SR.SchemaHierarchy_SqlFiles;
|
||||
var schemaHierarchyServerFunctions = SR.SchemaHierarchy_ServerFunctions;
|
||||
var schemaHierarchySqlType = SR.SchemaHierarchy_SqlType;
|
||||
var schemaHierarchyServerOptions = SR.SchemaHierarchy_ServerOptions;
|
||||
var schemaHierarchyDatabaseDiagrams = SR.SchemaHierarchy_DatabaseDiagrams;
|
||||
var schemaHierarchySystemTables = SR.SchemaHierarchy_SystemTables;
|
||||
var schemaHierarchyDatabases = SR.SchemaHierarchy_Databases;
|
||||
var schemaHierarchySystemContracts = SR.SchemaHierarchy_SystemContracts;
|
||||
var schemaHierarchySystemDatabases = SR.SchemaHierarchy_SystemDatabases;
|
||||
var schemaHierarchySystemMessageTypes = SR.SchemaHierarchy_SystemMessageTypes;
|
||||
var schemaHierarchySystemQueues = SR.SchemaHierarchy_SystemQueues;
|
||||
var schemaHierarchySystemServices = SR.SchemaHierarchy_SystemServices;
|
||||
var schemaHierarchySystemStoredProcedures = SR.SchemaHierarchy_SystemStoredProcedures;
|
||||
var schemaHierarchySystemViews = SR.SchemaHierarchy_SystemViews;
|
||||
var schemaHierarchyDataTierApplications = SR.SchemaHierarchy_DataTierApplications;
|
||||
var schemaHierarchyExtendedStoredProcedures = SR.SchemaHierarchy_ExtendedStoredProcedures;
|
||||
var schemaHierarchySystemAggregateFunctions = SR.SchemaHierarchy_SystemAggregateFunctions;
|
||||
var schemaHierarchySystemApproximateNumerics = SR.SchemaHierarchy_SystemApproximateNumerics;
|
||||
var schemaHierarchySystemBinaryStrings = SR.SchemaHierarchy_SystemBinaryStrings;
|
||||
var schemaHierarchySystemCharacterStrings = SR.SchemaHierarchy_SystemCharacterStrings;
|
||||
var schemaHierarchySystemCLRDataTypes = SR.SchemaHierarchy_SystemCLRDataTypes;
|
||||
var schemaHierarchySystemConfigurationFunctions = SR.SchemaHierarchy_SystemConfigurationFunctions;
|
||||
var schemaHierarchySystemCursorFunctions = SR.SchemaHierarchy_SystemCursorFunctions;
|
||||
var schemaHierarchySystemDataTypes = SR.SchemaHierarchy_SystemDataTypes;
|
||||
var schemaHierarchySystemDateAndTime = SR.SchemaHierarchy_SystemDateAndTime;
|
||||
var schemaHierarchySystemDateAndTimeFunctions = SR.SchemaHierarchy_SystemDateAndTimeFunctions;
|
||||
var schemaHierarchySystemExactNumerics = SR.SchemaHierarchy_SystemExactNumerics;
|
||||
var schemaHierarchySystemFunctions = SR.SchemaHierarchy_SystemFunctions;
|
||||
var schemaHierarchySystemHierarchyIdFunctions = SR.SchemaHierarchy_SystemHierarchyIdFunctions;
|
||||
var schemaHierarchySystemMathematicalFunctions = SR.SchemaHierarchy_SystemMathematicalFunctions;
|
||||
var schemaHierarchySystemMetadataFunctionions = SR.SchemaHierarchy_SystemMetadataFunctions;
|
||||
var schemaHierarchySystemOtherDataTypes = SR.SchemaHierarchy_SystemOtherDataTypes;
|
||||
var schemaHierarchySystemOtherFunctions = SR.SchemaHierarchy_SystemOtherFunctions;
|
||||
var schemaHierarchySystemRowsetFunctions = SR.SchemaHierarchy_SystemRowsetFunctions;
|
||||
var schemaHierarchySystemSecurityFunctions = SR.SchemaHierarchy_SystemSecurityFunctions;
|
||||
var schemaHierarchySystemSpatialDataTypes = SR.SchemaHierarchy_SystemSpatialDataTypes;
|
||||
var schemaHierarchySystemStringFunctions = SR.SchemaHierarchy_SystemStringFunctions;
|
||||
var schemaHierarchySystemSystemStatisticalFunctions = SR.SchemaHierarchy_SystemSystemStatisticalFunctions;
|
||||
var schemaHierarchySystemTextAndImageFunctions = SR.SchemaHierarchy_SystemTextAndImageFunctions;
|
||||
var schemaHierarchySystemUnicodeCharacterStrings = SR.SchemaHierarchy_SystemUnicodeCharacterStrings;
|
||||
var schemaHierarchyAggregateFunctions = SR.SchemaHierarchy_AggregateFunctions;
|
||||
var schemaHierarchyScalarValuedFunctions = SR.SchemaHierarchy_ScalarValuedFunctions;
|
||||
var schemaHierarchyTableValuedFunctions = SR.SchemaHierarchy_TableValuedFunctions;
|
||||
var schemaHierarchySystemExtendedStoredProcedures = SR.SchemaHierarchy_SystemExtendedStoredProcedures;
|
||||
var schemaHierarchyBuiltInType = SR.SchemaHierarchy_BuiltInType;
|
||||
var schemaHierarchyBuiltInServerRole = SR.SchemaHierarchy_BuiltInServerRole;
|
||||
var schemaHierarchyUserWithPassword = SR.SchemaHierarchy_UserWithPassword;
|
||||
var schemaHierarchySearchPropertyList = SR.SchemaHierarchy_SearchPropertyList;
|
||||
var schemaHierarchySecurityPolicies = SR.SchemaHierarchy_SecurityPolicies;
|
||||
var schemaHierarchySecurityPredicates = SR.SchemaHierarchy_SecurityPredicates;
|
||||
var schemaHierarchyServerRole = SR.SchemaHierarchy_ServerRole;
|
||||
var schemaHierarchySearchPropertyLists = SR.SchemaHierarchy_SearchPropertyLists;
|
||||
var schemaHierarchyColumnStoreIndexes = SR.SchemaHierarchy_ColumnStoreIndexes;
|
||||
var schemaHierarchyTableTypeIndexes = SR.SchemaHierarchy_TableTypeIndexes;
|
||||
var schemaHierarchyServerInstance = SR.SchemaHierarchy_ServerInstance;
|
||||
var schemaHierarchySelectiveXmlIndexes = SR.SchemaHierarchy_SelectiveXmlIndexes;
|
||||
var schemaHierarchyXmlNamespaces = SR.SchemaHierarchy_XmlNamespaces;
|
||||
var schemaHierarchyXmlTypedPromotedPaths = SR.SchemaHierarchy_XmlTypedPromotedPaths;
|
||||
var schemaHierarchySqlTypedPromotedPaths = SR.SchemaHierarchy_SqlTypedPromotedPaths;
|
||||
var schemaHierarchyDatabaseScopedCredentials = SR.SchemaHierarchy_DatabaseScopedCredentials;
|
||||
var schemaHierarchyExternalDataSources = SR.SchemaHierarchy_ExternalDataSources;
|
||||
var schemaHierarchyExternalFileFormats = SR.SchemaHierarchy_ExternalFileFormats;
|
||||
var schemaHierarchyExternalResources = SR.SchemaHierarchy_ExternalResources;
|
||||
var schemaHierarchyExternalTables = SR.SchemaHierarchy_ExternalTables;
|
||||
var schemaHierarchyAlwaysEncryptedKeys = SR.SchemaHierarchy_AlwaysEncryptedKeys;
|
||||
var schemaHierarchyColumnMasterKeys = SR.SchemaHierarchy_ColumnMasterKeys;
|
||||
var schemaHierarchyColumnEncryptionKeys = SR.SchemaHierarchy_ColumnEncryptionKeys;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.SqlTools.Hosting.Protocol;
|
||||
using Microsoft.SqlTools.Hosting.Protocol.Contracts;
|
||||
using Moq;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Utility
|
||||
{
|
||||
public static class ProtocolEndpointMocks
|
||||
{
|
||||
public static Mock<IProtocolEndpoint> AddEventHandling<TParams>(
|
||||
this Mock<IProtocolEndpoint> mock,
|
||||
EventType<TParams> expectedEvent,
|
||||
Action<EventType<TParams>, TParams> eventCallback)
|
||||
{
|
||||
var flow = mock.Setup(h => h.SendEvent(
|
||||
It.Is<EventType<TParams>>(m => m == expectedEvent),
|
||||
It.IsAny<TParams>()))
|
||||
.Returns(Task.FromResult(0));
|
||||
if (eventCallback != null)
|
||||
{
|
||||
flow.Callback(eventCallback);
|
||||
}
|
||||
|
||||
return mock;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -53,6 +53,30 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Utility
|
||||
};
|
||||
}
|
||||
|
||||
public static ServerInfo GetTestServerInfo()
|
||||
{
|
||||
return new ServerInfo()
|
||||
{
|
||||
ServerVersion = "14.0.1.0",
|
||||
ServerMajorVersion = 14,
|
||||
ServerMinorVersion = 0,
|
||||
EngineEditionId = 3,
|
||||
OsVersion = "Linux (Ubuntu 15.10)",
|
||||
IsCloud = false,
|
||||
ServerEdition = "Developer Edition",
|
||||
ServerLevel = ""
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a test sql connection factory instance
|
||||
/// </summary>
|
||||
public static ISqlConnectionFactory GetTestSqlConnectionFactory()
|
||||
{
|
||||
// use mock database connection
|
||||
return new TestSqlConnectionFactory();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a test connection details object
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user