diff --git a/bin/nuget/Microsoft.SqlServer.Management.SqlScriptPublishModel.140.2.0.nupkg b/bin/nuget/Microsoft.SqlServer.Management.SqlScriptPublishModel.140.2.3.nupkg similarity index 97% rename from bin/nuget/Microsoft.SqlServer.Management.SqlScriptPublishModel.140.2.0.nupkg rename to bin/nuget/Microsoft.SqlServer.Management.SqlScriptPublishModel.140.2.3.nupkg index 59a51e72..6a79d110 100644 Binary files a/bin/nuget/Microsoft.SqlServer.Management.SqlScriptPublishModel.140.2.0.nupkg and b/bin/nuget/Microsoft.SqlServer.Management.SqlScriptPublishModel.140.2.3.nupkg differ diff --git a/src/Microsoft.SqlTools.ServiceLayer/Microsoft.SqlTools.ServiceLayer.csproj b/src/Microsoft.SqlTools.ServiceLayer/Microsoft.SqlTools.ServiceLayer.csproj index 918624a4..38a65768 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Microsoft.SqlTools.ServiceLayer.csproj +++ b/src/Microsoft.SqlTools.ServiceLayer/Microsoft.SqlTools.ServiceLayer.csproj @@ -20,7 +20,7 @@ - + diff --git a/src/Microsoft.SqlTools.ServiceLayer/Scripting/Contracts/ScriptingOptions.cs b/src/Microsoft.SqlTools.ServiceLayer/Scripting/Contracts/ScriptingOptions.cs index 628a1b7c..ffdedd35 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Scripting/Contracts/ScriptingOptions.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Scripting/Contracts/ScriptingOptions.cs @@ -130,6 +130,14 @@ namespace Microsoft.SqlTools.ServiceLayer.Scripting.Contracts /// public string ScriptCompatibilityOption { get; set; } = "Script140Compat"; + /// + /// Script only features compatible with the specified SQL Server database engine type. + /// Possible Values: + /// SingleInstance + /// SqlAzure + /// + public string TargetDatabaseEngineType { get; set; } = "SingleInstance"; + /// /// Script only features compatible with the specified SQL Server database engine edition. /// Possible Values: @@ -143,14 +151,6 @@ namespace Microsoft.SqlTools.ServiceLayer.Scripting.Contracts /// public string TargetDatabaseEngineEdition { get; set; } = "SqlServerEnterpriseEdition"; - /// - /// Script only features compatible with the specified SQL Server database engine type. - /// Possible Values: - /// SingleInstance - /// SqlAzure - /// - public string TargetDatabaseEngineType { get; set; } = "SingleInstance"; - /// /// Script all logins available on the server. Passwords will not be scripted. /// @@ -224,7 +224,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Scripting.Contracts /// /// Script the full-text indexes for each table or indexed view scripted. /// - public bool? ScriptFullTextIndexes { get; set; } = false; + public bool? ScriptFullTextIndexes { get; set; } = true; /// /// Script the indexes (including XML and clustered indexes) for each table or indexed view scripted. @@ -245,7 +245,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Scripting.Contracts /// /// Script the triggers for each table or view scripted /// - public bool? ScriptTriggers { get; set; } = false; + public bool? ScriptTriggers { get; set; } = true; /// /// Script the unique keys for each table or view scripted. diff --git a/src/Microsoft.SqlTools.ServiceLayer/Scripting/Contracts/ScriptingRequest.cs b/src/Microsoft.SqlTools.ServiceLayer/Scripting/Contracts/ScriptingRequest.cs index e581aac5..b7987de0 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Scripting/Contracts/ScriptingRequest.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Scripting/Contracts/ScriptingRequest.cs @@ -18,6 +18,11 @@ namespace Microsoft.SqlTools.ServiceLayer.Scripting.Contracts /// public string FilePath { get; set; } + /// + /// Gets or sets whether scripting to a single file or file per object. + /// + public string ScriptDestination { get; set; } + /// /// Gets or sets connection string of the target database the scripting operation will run against. /// @@ -38,6 +43,26 @@ namespace Microsoft.SqlTools.ServiceLayer.Scripting.Contracts /// public List ExcludeObjectCriteria { get; set; } + /// + /// Gets or sets a list of schema name of objects to script. + /// + public List IncludeSchemas { get; set; } + + /// + /// Gets or sets a list of schema name of objects to not script. + /// + public List ExcludeSchemas { get; set; } + + /// + /// Gets or sets a list of type name of objects to script. + /// + public List IncludeTypes { get; set; } + + /// + /// Gets or sets a list of type name of objects to not script + /// + public List ExcludeTypes { get; set; } + /// /// Gets or sets the scripting options. /// @@ -57,7 +82,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Scripting.Contracts /// public class ScriptingRequest { - public static readonly RequestType Type = + public static readonly RequestType Type = RequestType.Create("scripting/script"); } } diff --git a/src/Microsoft.SqlTools.ServiceLayer/Scripting/ScriptingExtensionMethods.cs b/src/Microsoft.SqlTools.ServiceLayer/Scripting/ScriptingExtensionMethods.cs index 2b324dc3..cc17761e 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Scripting/ScriptingExtensionMethods.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Scripting/ScriptingExtensionMethods.cs @@ -89,9 +89,10 @@ namespace Microsoft.SqlTools.ServiceLayer.Scripting /// The scripting object instance. /// The name of the database referenced by the Urn. /// The Urn instance. - public static Urn ToUrn(this ScriptingObject scriptingObject, string database) + public static Urn ToUrn(this ScriptingObject scriptingObject, string server, string database) { Validate.IsNotNull("scriptingObject", scriptingObject); + Validate.IsNotNullOrEmptyString("server", server); Validate.IsNotNullOrWhitespaceString("database", database); Validate.IsNotNullOrWhitespaceString("scriptingObject.Name", scriptingObject.Name); @@ -99,7 +100,8 @@ namespace Microsoft.SqlTools.ServiceLayer.Scripting // Leaving the server name blank will automatically match whatever the server SMO is running against. string urn = string.Format( - "Server/Database[@Name='{0}']/{1}[@Name='{2}' {3}]", + "Server[@Name='{0}']/Database[@Name='{1}']/{2}[@Name='{3}' {4}]", + server.ToUpper(), database, scriptingObject.Type, scriptingObject.Name, diff --git a/src/Microsoft.SqlTools.ServiceLayer/Scripting/ScriptingObjectMatcher.cs b/src/Microsoft.SqlTools.ServiceLayer/Scripting/ScriptingObjectMatcher.cs index 9932c72a..8171c362 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Scripting/ScriptingObjectMatcher.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Scripting/ScriptingObjectMatcher.cs @@ -52,16 +52,28 @@ namespace Microsoft.SqlTools.ServiceLayer.Scripting /// /// The include object criteria. /// The exclude object criteria. + /// The include schema filter. + /// The exclude schema filter. + /// The include type filter. + /// The exclude type filter. /// The candidate object to filter. /// The matching scripting objects. public static IEnumerable Match( ScriptingObject includeCriteria, ScriptingObject excludeCriteria, + string includeSchemas, + string excludeSchemas, + string includeTypes, + string excludeTypes, IEnumerable candidates) { return Match( includeCriteria == null ? new ScriptingObject[0] : new[] { includeCriteria }, excludeCriteria == null ? new ScriptingObject[0] : new[] { excludeCriteria }, + includeSchemas == null ? new List(): new List { includeSchemas }, + excludeSchemas == null ? new List(): new List { excludeSchemas }, + includeTypes == null ? new List(): new List { includeTypes }, + excludeTypes == null ? new List(): new List { excludeTypes }, candidates); } @@ -71,15 +83,23 @@ namespace Microsoft.SqlTools.ServiceLayer.Scripting /// /// The collection of include object criteria items. /// The collection of exclude object criteria items. + /// The collection of include schema items. + /// The collection of exclude schema items. + /// The collection of include type items. + /// The collection of exclude type items. /// The candidate object to filter. /// The matching scripting objects. public static IEnumerable Match( IEnumerable includeCriteria, IEnumerable excludeCriteria, + IEnumerable includeSchemas, + IEnumerable excludeSchemas, + IEnumerable includeTypes, + IEnumerable excludeTypes, IEnumerable candidates) { Validate.IsNotNull("candidates", candidates); - + IEnumerable matchedObjects = new List(); if (includeCriteria != null && includeCriteria.Any()) @@ -95,15 +115,84 @@ namespace Microsoft.SqlTools.ServiceLayer.Scripting matchedObjects = candidates; } - if (excludeCriteria != null) + if (excludeCriteria != null && excludeCriteria.Any()) { foreach (ScriptingObject scriptingObjectCriteria in excludeCriteria) { - IEnumerable matches = MatchCriteria(scriptingObjectCriteria, candidates); + IEnumerable matches = MatchCriteria(scriptingObjectCriteria, matchedObjects); matchedObjects = matchedObjects.Except(matches); } } + // Apply additional filters if included. + matchedObjects = ExcludeSchemaAndOrType(excludeSchemas, excludeTypes, matchedObjects); + matchedObjects = IncludeSchemaAndOrType(includeSchemas, includeTypes, matchedObjects); + + return matchedObjects; + } + + private static IEnumerable ExcludeSchemaAndOrType(IEnumerable excludeSchemas, IEnumerable excludeTypes, + IEnumerable candidates) + { + // Given a list of candidates, we remove any objects that match the excluded schema and/or type. + IEnumerable remainingObjects = candidates; + IEnumerable matches = null; + + if (excludeSchemas != null && excludeSchemas.Any()) + { + foreach (string exclude_schema in excludeSchemas) + { + matches = MatchCriteria(exclude_schema, (candidate) => { return candidate.Schema; }, candidates); + remainingObjects = remainingObjects.Except(matches); + } + } + + if (excludeTypes != null && excludeTypes.Any()) + { + foreach (string exclude_type in excludeTypes) + { + matches = remainingObjects.Where(o => string.Equals(exclude_type, o.Type, StringComparison.OrdinalIgnoreCase)); + remainingObjects = remainingObjects.Except(matches); + } + } + + return remainingObjects; + } + + private static IEnumerable IncludeSchemaAndOrType(IEnumerable includeSchemas, IEnumerable includeTypes, + IEnumerable candidates) + { + // Given a list of candidates, we return a new list of scripting objects that match + // the schema and/or type filter. + IEnumerable matchedSchema = new List(); + IEnumerable matchedType = new List(); + IEnumerable matchedObjects = new List(); + IEnumerable matches = null; + + if (includeSchemas != null && includeSchemas.Any()) + { + foreach (string include_schema in includeSchemas) + { + matches = MatchCriteria(include_schema, (candidate) => { return candidate.Schema; }, candidates); + matchedSchema = matchedSchema.Union(matches); + } + matchedObjects = matchedSchema; + } + else + { + matchedObjects = candidates; + } + + if (includeTypes != null && includeTypes.Any()) + { + foreach (string include_type in includeTypes) + { + matches = matchedObjects.Where(o => string.Equals(include_type, o.Type, StringComparison.OrdinalIgnoreCase)); + matchedType = matchedType.Union(matches); + } + matchedObjects = matchedType; + } + return matchedObjects; } @@ -137,9 +226,12 @@ namespace Microsoft.SqlTools.ServiceLayer.Scripting } if (property.EndsWith(Wildcard, StringComparison.OrdinalIgnoreCase)) { - matchedObjects = candidates.Where(o => propertySelector(o).StartsWith( - propertySelector(o).Substring(0, propertySelector(o).Length - 1), - StringComparison.OrdinalIgnoreCase)); + matchedObjects = candidates.Where( + o => + propertySelector(o) != null && + propertySelector(o).StartsWith( + propertySelector(o).Substring(0, propertySelector(o).Length - 1), + StringComparison.OrdinalIgnoreCase)); } else { diff --git a/src/Microsoft.SqlTools.ServiceLayer/Scripting/ScriptingScriptOperation.cs b/src/Microsoft.SqlTools.ServiceLayer/Scripting/ScriptingScriptOperation.cs index 92042b07..3908e548 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Scripting/ScriptingScriptOperation.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Scripting/ScriptingScriptOperation.cs @@ -72,11 +72,16 @@ namespace Microsoft.SqlTools.ServiceLayer.Scripting publishModel.ScriptProgress += this.OnPublishModelScriptProgress; publishModel.ScriptError += this.OnPublishModelScriptError; + ScriptDestination destination = !string.IsNullOrWhiteSpace(this.Parameters.ScriptDestination) + ? (ScriptDestination)Enum.Parse(typeof(ScriptDestination), this.Parameters.ScriptDestination) + : ScriptDestination.ToSingleFile; + + // SMO is currently hardcoded to produce UTF-8 encoding when running on dotnet core. ScriptOutputOptions outputOptions = new ScriptOutputOptions { SaveFileMode = ScriptFileMode.Overwrite, - SaveFileType = ScriptFileType.Unicode, // UTF-16 SaveFileName = this.Parameters.FilePath, + ScriptDestination = destination, }; this.CancellationToken.ThrowIfCancellationRequested(); @@ -160,57 +165,61 @@ namespace Microsoft.SqlTools.ServiceLayer.Scripting { SqlScriptPublishModel publishModel = new SqlScriptPublishModel(this.Parameters.ConnectionString); - // In the getter for SqlScriptPublishModel.AdvancedOptions, there is some strange logic which will - // cause the SqlScriptPublishModel.AdvancedOptions to get reset and lose all values based the ordering - // of when SqlScriptPublishModel.ScriptAllObjects is set. To workaround this, we initialize with - // SqlScriptPublishModel.ScriptAllObjects to true. If we need to set SqlScriptPublishModel.ScriptAllObjects - // to false, it must the last thing we do after setting all SqlScriptPublishModel.AdvancedOptions values. - // If we call the SqlScriptPublishModel.AdvancedOptions getter afterwards, all options will be reset. - // - publishModel.ScriptAllObjects = true; - - PopulateAdvancedScriptOptions(this.Parameters.ScriptOptions, publishModel.AdvancedOptions); - // See if any filtering criteria was specified. If not, we're scripting the entire database. Otherwise, the filtering // criteria should include the target objects to script. // - bool hasIncludeCriteria = this.Parameters.IncludeObjectCriteria != null && this.Parameters.IncludeObjectCriteria.Any(); - bool hasExcludeCriteria = this.Parameters.ExcludeObjectCriteria != null && this.Parameters.ExcludeObjectCriteria.Any(); bool hasObjectsSpecified = this.Parameters.ScriptingObjects != null && this.Parameters.ScriptingObjects.Any(); - bool scriptAllObjects = !(hasIncludeCriteria || hasExcludeCriteria || hasObjectsSpecified); + bool hasCriteriaSpecified = + (this.Parameters.IncludeObjectCriteria != null && this.Parameters.IncludeObjectCriteria.Any()) || + (this.Parameters.ExcludeObjectCriteria != null && this.Parameters.ExcludeObjectCriteria.Any()) || + (this.Parameters.IncludeSchemas != null && this.Parameters.IncludeSchemas.Any()) || + (this.Parameters.ExcludeSchemas != null && this.Parameters.ExcludeSchemas.Any()) || + (this.Parameters.IncludeTypes != null && this.Parameters.IncludeTypes.Any()) || + (this.Parameters.ExcludeTypes != null && this.Parameters.ExcludeTypes.Any()); + bool scriptAllObjects = !hasObjectsSpecified && !hasCriteriaSpecified; + + // In the getter for SqlScriptPublishModel.AdvancedOptions, there is some strange logic which will + // cause the SqlScriptPublishModel.AdvancedOptions to get reset and lose all values based the ordering + // of when SqlScriptPublishModel.ScriptAllObjects is set. + // + publishModel.ScriptAllObjects = scriptAllObjects; if (scriptAllObjects) { - Logger.Write(LogLevel.Verbose, "ScriptAllObjects is True"); + // Due to the getter logic within publishModel.AdvancedOptions, we explicitly populate the options + // after we determine what objects we are scripting. + // + PopulateAdvancedScriptOptions(this.Parameters.ScriptOptions, publishModel.AdvancedOptions); return publishModel; } - // After setting this property, SqlScriptPublishModel.AdvancedOptions should NOT be referenced again - // or all SqlScriptPublishModel.AdvancedOptions will be reset. - // - publishModel.ScriptAllObjects = false; - Logger.Write(LogLevel.Verbose, "ScriptAllObjects is False"); - - // An object selection criteria was specified, so now we need to resolve the SMO Urn instances to script. - // IEnumerable selectedObjects = new List(); - if (hasIncludeCriteria || hasExcludeCriteria) + + if (hasCriteriaSpecified) { // This is an expensive remote call to load all objects from the database. + // List allObjects = publishModel.GetDatabaseObjects(); - selectedObjects = ScriptingObjectMatcher.Match( this.Parameters.IncludeObjectCriteria, this.Parameters.ExcludeObjectCriteria, + this.Parameters.IncludeSchemas, + this.Parameters.ExcludeSchemas, + this.Parameters.IncludeTypes, + this.Parameters.ExcludeTypes, allObjects); } - // If specific objects are specified, include them. - // if (hasObjectsSpecified) { selectedObjects = selectedObjects.Union(this.Parameters.ScriptingObjects); } + // Populating advanced options after we select our objects in question, otherwise we lose all + // advanced options. After this call to PopulateAdvancedScriptOptions, DO NOT reference the + // publishModel.AdvancedOptions getter as it will reset the options in the model. + // + PopulateAdvancedScriptOptions(this.Parameters.ScriptOptions, publishModel.AdvancedOptions); + Logger.Write( LogLevel.Normal, string.Format( @@ -218,15 +227,49 @@ namespace Microsoft.SqlTools.ServiceLayer.Scripting selectedObjects.Count(), string.Join(", ", selectedObjects))); + string server = GetServerNameFromLiveInstance(this.Parameters.ConnectionString); string database = new SqlConnectionStringBuilder(this.Parameters.ConnectionString).InitialCatalog; + foreach (ScriptingObject scriptingObject in selectedObjects) { - publishModel.SelectedObjects.Add(scriptingObject.ToUrn(database)); + publishModel.SelectedObjects.Add(scriptingObject.ToUrn(server, database)); } return publishModel; } + private string GetServerNameFromLiveInstance(string connectionString) + { + string serverName = null; + using(SqlConnection connection = new SqlConnection(connectionString)) + using (SqlCommand cmd = connection.CreateCommand()) + { + connection.Open(); + + try + { + cmd.CommandText = "select @@servername"; + serverName = (string)cmd.ExecuteScalar(); + } + catch (SqlException e) + { + // + // Azure SQL Data Warehouse does not support @@servername, so fallback to SERVERPROPERTY. + // + + Logger.Write( + LogLevel.Verbose, + string.Format("Exception running query 'SELECT @@servername' {0}, fallback to SERVERPROPERTY query", e)); + + cmd.CommandText = "select SERVERPROPERTY('ServerName') AS ServerName"; + serverName = (string)cmd.ExecuteScalar(); + } + } + + Logger.Write(LogLevel.Verbose, string.Format("Resolved server name '{0}'", serverName)); + return serverName; + } + private static void PopulateAdvancedScriptOptions(ScriptOptions scriptOptionsParameters, SqlScriptOptions advancedOptions) { if (scriptOptionsParameters == null) diff --git a/test/Microsoft.SqlTools.ServiceLayer.TestDriver.Tests/SqlScriptPublishModelTests.cs b/test/Microsoft.SqlTools.ServiceLayer.TestDriver.Tests/SqlScriptPublishModelTests.cs index e2401ae3..9ae96baf 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.TestDriver.Tests/SqlScriptPublishModelTests.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.TestDriver.Tests/SqlScriptPublishModelTests.cs @@ -130,7 +130,7 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests ScriptingPlanNotificationParams planEvent = await testService.Driver.WaitForEvent(ScriptingPlanNotificationEvent.Type, TimeSpan.FromSeconds(30)); ScriptingCompleteParams parameters = await testService.Driver.WaitForEvent(ScriptingCompleteEvent.Type, TimeSpan.FromSeconds(30)); Assert.True(parameters.Success); - Assert.Equal(2, planEvent.Count); + Assert.Equal(1, planEvent.Count); Assert.True(File.Exists(tempFile.FilePath)); Assert.True(new FileInfo(tempFile.FilePath).Length > 0); } @@ -165,7 +165,7 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests ScriptingPlanNotificationParams planEvent = await testService.Driver.WaitForEvent(ScriptingPlanNotificationEvent.Type, TimeSpan.FromSeconds(30)); ScriptingCompleteParams parameters = await testService.Driver.WaitForEvent(ScriptingCompleteEvent.Type, TimeSpan.FromSeconds(30)); Assert.True(parameters.Success); - Assert.Equal(2, planEvent.Count); + Assert.Equal(1, planEvent.Count); Assert.True(File.Exists(tempFile.FilePath)); Assert.True(new FileInfo(tempFile.FilePath).Length > 0); } @@ -200,7 +200,7 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests ScriptingPlanNotificationParams planEvent = await testService.Driver.WaitForEvent(ScriptingPlanNotificationEvent.Type, TimeSpan.FromSeconds(30)); ScriptingCompleteParams parameters = await testService.Driver.WaitForEvent(ScriptingCompleteEvent.Type, TimeSpan.FromSeconds(30)); Assert.True(parameters.Success); - Assert.Equal(2, planEvent.Count); + Assert.Equal(1, planEvent.Count); Assert.True(File.Exists(tempFile.FilePath)); Assert.True(new FileInfo(tempFile.FilePath).Length > 0); } diff --git a/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Driver/ServiceTestDriver.cs b/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Driver/ServiceTestDriver.cs index 6c67c9ae..440cd6c0 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Driver/ServiceTestDriver.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Driver/ServiceTestDriver.cs @@ -51,9 +51,10 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Driver { // Include a fallback value to for running tests within visual studio serviceHostExecutable = - @"..\..\src\Microsoft.SqlTools.ServiceLayer\bin\Debug\netcoreapp2.0\win7-x64\Microsoft.SqlTools.ServiceLayer.exe"; + @"..\..\..\..\..\src\Microsoft.SqlTools.ServiceLayer\bin\Debug\netcoreapp2.0\win7-x64\MicrosoftSqlToolsServiceLayer.exe"; } + serviceHostExecutable = Path.GetFullPath(serviceHostExecutable); // Make sure it exists before continuing if (!File.Exists(serviceHostExecutable)) { diff --git a/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Microsoft.SqlTools.ServiceLayer.TestDriver.csproj b/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Microsoft.SqlTools.ServiceLayer.TestDriver.csproj index 7964389f..daa473c7 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Microsoft.SqlTools.ServiceLayer.TestDriver.csproj +++ b/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Microsoft.SqlTools.ServiceLayer.TestDriver.csproj @@ -13,7 +13,7 @@ - + diff --git a/test/Microsoft.SqlTools.ServiceLayer.UnitTests/Scripting/ScriptingObjectMatcherTests.cs b/test/Microsoft.SqlTools.ServiceLayer.UnitTests/Scripting/ScriptingObjectMatcherTests.cs index 47921574..35d40978 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.UnitTests/Scripting/ScriptingObjectMatcherTests.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.UnitTests/Scripting/ScriptingObjectMatcherTests.cs @@ -72,6 +72,10 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Scripting IEnumerable results = ScriptingObjectMatcher.Match( includeCriteria: new ScriptingObject[0], excludeCriteria: new ScriptingObject[0], + includeSchemas: null, + excludeSchemas: null, + includeTypes: null, + excludeTypes: null, candidates: TestData); Assert.Equal(6, results.Count()); @@ -83,6 +87,10 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Scripting IEnumerable results = ScriptingObjectMatcher.Match( includeCriteria: new ScriptingObject(), excludeCriteria: new ScriptingObject(), + includeSchemas: null, + excludeSchemas: null, + includeTypes: null, + excludeTypes: null, candidates: TestData); Assert.Equal(0, results.Count()); @@ -92,8 +100,12 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Scripting public void ScriptingMatchIncludeName() { IEnumerable results = ScriptingObjectMatcher.Match( - includeCriteria: new ScriptingObject { Name = "Table1"}, + includeCriteria: new ScriptingObject { Name = "Table1" }, excludeCriteria: null, + includeSchemas: null, + excludeSchemas: null, + includeTypes: null, + excludeTypes: null, candidates: TestData); Assert.Equal(2, results.Count()); @@ -105,6 +117,10 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Scripting IEnumerable results = ScriptingObjectMatcher.Match( includeCriteria: new ScriptingObject { Name = "*" }, excludeCriteria: null, + includeSchemas: null, + excludeSchemas: null, + includeTypes: null, + excludeTypes: null, candidates: TestData); Assert.Equal(6, results.Count()); @@ -115,6 +131,10 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Scripting IEnumerable results = ScriptingObjectMatcher.Match( includeCriteria: new ScriptingObject { Name = "Tab*" }, excludeCriteria: null, + includeSchemas: null, + excludeSchemas: null, + includeTypes: null, + excludeTypes: null, candidates: TestData); Assert.Equal(4, results.Count()); @@ -126,6 +146,10 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Scripting IEnumerable results = ScriptingObjectMatcher.Match( includeCriteria: new ScriptingObject { Schema = "S2" }, excludeCriteria: null, + includeSchemas: null, + excludeSchemas: null, + includeTypes: null, + excludeTypes: null, candidates: TestData); Assert.Equal(2, results.Count()); @@ -137,6 +161,25 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Scripting IEnumerable results = ScriptingObjectMatcher.Match( includeCriteria: new ScriptingObject { Schema = "*" }, excludeCriteria: null, + includeSchemas: null, + excludeSchemas: null, + includeTypes: null, + excludeTypes: null, + candidates: TestData); + + Assert.Equal(6, results.Count()); + } + + [Fact] + public void ScriptingMatchIncludeSchemaWildcardPostfixCriteria() + { + IEnumerable results = ScriptingObjectMatcher.Match( + includeCriteria: new ScriptingObject { Schema = "S*" }, + excludeCriteria: null, + includeSchemas: null, + excludeSchemas: null, + includeTypes: null, + excludeTypes: null, candidates: TestData); Assert.Equal(6, results.Count()); @@ -148,17 +191,25 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Scripting IEnumerable results = ScriptingObjectMatcher.Match( includeCriteria: new ScriptingObject { Schema = "S*" }, excludeCriteria: null, + includeSchemas: null, + excludeSchemas: null, + includeTypes: "Table", + excludeTypes: "View", candidates: TestData); - Assert.Equal(6, results.Count()); + Assert.Equal(4, results.Count()); } [Fact] public void ScriptingMatchIncludeType() { IEnumerable results = ScriptingObjectMatcher.Match( - includeCriteria: new ScriptingObject { Type="Table" }, + includeCriteria: new ScriptingObject { Type = "Table" }, excludeCriteria: null, + includeSchemas: null, + excludeSchemas: null, + includeTypes: null, + excludeTypes: null, candidates: TestData); Assert.Equal(4, results.Count()); @@ -170,6 +221,10 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Scripting IEnumerable results = ScriptingObjectMatcher.Match( includeCriteria: new ScriptingObject { Schema = "S1", Name = "Table1" }, excludeCriteria: null, + includeSchemas: null, + excludeSchemas: null, + includeTypes: null, + excludeTypes: null, candidates: TestData); Assert.Equal(1, results.Count()); @@ -179,8 +234,12 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Scripting public void ScriptingMatchIncludeSchemaAndType() { IEnumerable results = ScriptingObjectMatcher.Match( - includeCriteria: new ScriptingObject { Type="View", Schema = "S1" }, + includeCriteria: new ScriptingObject { Type = "View", Schema = "S1" }, excludeCriteria: null, + includeSchemas: null, + excludeSchemas: null, + includeTypes: null, + excludeTypes: null, candidates: TestData); Assert.Equal(2, results.Count()); @@ -192,6 +251,10 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Scripting IEnumerable results = ScriptingObjectMatcher.Match( includeCriteria: null, excludeCriteria: new ScriptingObject { Name = "Table1" }, + includeSchemas: null, + excludeSchemas: null, + includeTypes: null, + excludeTypes: null, candidates: TestData); Assert.Equal(4, results.Count()); @@ -203,6 +266,10 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Scripting IEnumerable results = ScriptingObjectMatcher.Match( includeCriteria: null, excludeCriteria: new ScriptingObject { Name = "*" }, + includeSchemas: null, + excludeSchemas: null, + includeTypes: null, + excludeTypes: null, candidates: TestData); Assert.Equal(0, results.Count()); @@ -213,6 +280,10 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Scripting IEnumerable results = ScriptingObjectMatcher.Match( includeCriteria: null, excludeCriteria: new ScriptingObject { Name = "Tab*" }, + includeSchemas: null, + excludeSchemas: null, + includeTypes: null, + excludeTypes: null, candidates: TestData); Assert.Equal(4, results.Count()); @@ -224,6 +295,10 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Scripting IEnumerable results = ScriptingObjectMatcher.Match( includeCriteria: null, excludeCriteria: new ScriptingObject { Schema = "S2" }, + includeSchemas: null, + excludeSchemas: null, + includeTypes: null, + excludeTypes: null, candidates: TestData); Assert.Equal(4, results.Count()); @@ -235,6 +310,10 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Scripting IEnumerable results = ScriptingObjectMatcher.Match( includeCriteria: null, excludeCriteria: new ScriptingObject { Schema = "*" }, + includeSchemas: null, + excludeSchemas: null, + includeTypes: null, + excludeTypes: null, candidates: TestData); Assert.Equal(0, results.Count()); @@ -246,6 +325,10 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Scripting IEnumerable results = ScriptingObjectMatcher.Match( includeCriteria: null, excludeCriteria: new ScriptingObject { Schema = "S*" }, + includeSchemas: null, + excludeSchemas: null, + includeTypes: null, + excludeTypes: null, candidates: TestData); Assert.Equal(0, results.Count()); @@ -257,20 +340,58 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Scripting IEnumerable results = ScriptingObjectMatcher.Match( includeCriteria: null, excludeCriteria: new ScriptingObject { Type = "Table" }, + includeSchemas: null, + excludeSchemas: null, + includeTypes: null, + excludeTypes: null, candidates: TestData); Assert.Equal(2, results.Count()); } + [Fact] + public void ScriptingMatchExcludeNameAndSchemaCriteria() + { + IEnumerable results = ScriptingObjectMatcher.Match( + includeCriteria: null, + excludeCriteria: new ScriptingObject { Schema = "S1", Name = "Table1" }, + includeSchemas: null, + excludeSchemas: null, + includeTypes: null, + excludeTypes: null, + candidates: TestData); + + Assert.Equal(5, results.Count()); + } + [Fact] public void ScriptingMatchExcludeNameAndSchema() { IEnumerable results = ScriptingObjectMatcher.Match( includeCriteria: null, - excludeCriteria: new ScriptingObject { Schema = "S1", Name = "Table1" }, + excludeCriteria: new ScriptingObject { Name = "Table1" }, + includeSchemas: null, + excludeSchemas: "S1", + includeTypes: null, + excludeTypes: null, candidates: TestData); - Assert.Equal(5, results.Count()); + Assert.Equal(1, results.Count()); + } + + [Fact] + public void ScriptingMatchExcludeSchemaAndTypeCriteria() + { + IEnumerable results = ScriptingObjectMatcher.Match( + includeCriteria: null, + excludeCriteria: new ScriptingObject { Type = "View", Schema = "S1" }, + includeSchemas: null, + excludeSchemas: null, + includeTypes: null, + excludeTypes: null, + candidates: TestData); + + Assert.Equal(4, results.Count()); } [Fact] @@ -278,10 +399,14 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Scripting { IEnumerable results = ScriptingObjectMatcher.Match( includeCriteria: null, - excludeCriteria: new ScriptingObject { Type = "View", Schema = "S1" }, + excludeCriteria: null, + includeSchemas: null, + excludeSchemas: "S1", + includeTypes: null, + excludeTypes: "View", candidates: TestData); - Assert.Equal(4, results.Count()); + Assert.Equal(2, results.Count()); } } }