mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-01-14 09:59:48 -05:00
Merging mssql-scripter changes (#430)
* Manual port of latest 'feature/mssq-scripter' branch * Bumpnuget package SqlScriptPublishModel.140.2.0 to Microsoft.SqlServer.Management.SqlScriptPublishModel.140.2.3 * In TestDriver, fix the path to Microsoft.SqlTools.ServiceLayer.exe after move to .NET Core 2.0
This commit is contained in:
@@ -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<ScriptingObject> selectedObjects = new List<ScriptingObject>();
|
||||
if (hasIncludeCriteria || hasExcludeCriteria)
|
||||
|
||||
if (hasCriteriaSpecified)
|
||||
{
|
||||
// This is an expensive remote call to load all objects from the database.
|
||||
//
|
||||
List<ScriptingObject> 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)
|
||||
|
||||
Reference in New Issue
Block a user