Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add support for refactor log script files #47

Merged
merged 7 commits into from
Sep 2, 2020
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/DacpacTool/BuildOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@ public class BuildOptions
public string[] SqlCmdVar { get; set; }
public FileInfo PreDeploy { get; set; }
public FileInfo PostDeploy { get; set; }
public FileInfo RefactorLog { get; set; }
}
}
5 changes: 2 additions & 3 deletions src/DacpacTool/PackageBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,13 +102,12 @@ public bool ValidateModel()
return _modelValid.Value;
}

public void SaveToDisk(FileInfo outputFile)
public void SaveToDisk(FileInfo outputFile, PackageOptions packageOptions = null)
{
// Ensure that the model has been created and metadata has been set
EnsureModelCreated();
EnsureModelValidated();
EnsureMetadataCreated();

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Revert

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

// Check if the file already exists
if (outputFile.Exists)
{
Expand All @@ -118,7 +117,7 @@ public void SaveToDisk(FileInfo outputFile)
}

Console.WriteLine($"Writing model to {outputFile.FullName}");
DacPackageExtensions.BuildPackage(outputFile.FullName, Model, Metadata, new PackageOptions { });
DacPackageExtensions.BuildPackage(outputFile.FullName, Model, Metadata, packageOptions ?? new PackageOptions { });
}

public void SetMetadata(string name, string version)
Expand Down
9 changes: 6 additions & 3 deletions src/DacpacTool/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.CommandLine.Invocation;
using System.IO;
using System.Threading.Tasks;
using Microsoft.SqlServer.Dac;
using Microsoft.SqlServer.Dac.Model;

namespace MSBuild.Sdk.SqlProj.DacpacTool
Expand All @@ -16,11 +17,12 @@ static async Task<int> Main(string[] args)
new Option<string>(new string[] { "--name", "-n" }, "Name of the package"),
new Option<string>(new string[] { "--version", "-v" }, "Version of the package"),
new Option<FileInfo>(new string[] { "--output", "-o" }, "Filename of the output package"),
new Option<SqlServerVersion>(new string[] { "--sqlServerVersion", "-sv" }, () => SqlServerVersion.Sql150, description: "Target version of the model"),
new Option<SqlServerVersion>(new string[] { "--sqlServerVersion", "-sv" }, () => SqlServerVersion.Sql150, description: "Target version of the model"),
new Option<FileInfo[]>(new string[] { "--input", "-i" }, "Input file name(s)"),
new Option<FileInfo[]>(new string[] { "--reference", "-r" }, "Reference(s) to include"),
new Option<FileInfo>(new string[] { "--predeploy" }, "Filename of optional pre-deployment script"),
new Option<FileInfo>(new string[] { "--postdeploy" }, "Filename of optional post-deployment script"),
new Option<FileInfo>(new string[] { "--refactorlog" }, "Filename of optional refactor log script"),
new Option<string[]>(new string[] { "--property", "-p" }, "Properties to be set on the model"),
new Option<string[]>(new string[] { "--sqlcmdvar", "-sc" }, "SqlCmdVariable(s) to include"),
};
Expand Down Expand Up @@ -94,7 +96,7 @@ private static int BuildDacpac(BuildOptions options)
}

// Save the package to disk
packageBuilder.SaveToDisk(options.Output);
packageBuilder.SaveToDisk(options.Output, new PackageOptions() { RefactorLogPath = options.RefactorLog?.FullName });

// Add predeployment and postdeployment scripts (must happen after SaveToDisk)
packageBuilder.AddPreDeploymentScript(options.PreDeploy, options.Output);
Expand Down Expand Up @@ -129,7 +131,8 @@ private static int DeployDacpac(DeployOptions options)
}

deployer.UseTargetServer(options.TargetServerName);


Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Revert

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


if (!string.IsNullOrWhiteSpace(options.TargetUser))
{
deployer.UseSqlAuthentication(options.TargetUser, options.TargetPassword);
Expand Down
8 changes: 2 additions & 6 deletions src/MSBuild.Sdk.SqlProj/Sdk/Sdk.targets
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
<!--
Set LanguageTargets to Microsoft.Common.targets for any project that the SDK won't (.proj, .noproj, etc)
https://github.com/dotnet/sdk/blob/50ddfbb91be94d068514e8f4b0ce1052156364a0/src/Tasks/Microsoft.NET.Build.Tasks/sdk/Sdk.targets#L28

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Revert removed line breaks (?)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, could not see it was whitespace removals...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

We can't default LanguageTargets it is set in the SDK and immediately imported. So we can only default
it if we know the SDK won't. Projects probably won't load in Visual Studio but will build from the
command-line just fine.
Expand All @@ -21,7 +20,6 @@
<Import Project="$(CustomBeforeNoTargets)" Condition="'$(CustomBeforeNoTargets)' != '' and Exists('$(CustomBeforeNoTargets)')" />

<Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" Condition=" '$(CommonTargetsPath)' == '' " />

<ItemGroup>
<!-- Override primary output path to be a .dacpac -->
<_IntermediateAssembly Include="@(IntermediateAssembly)" />
Expand Down Expand Up @@ -76,7 +74,6 @@
<Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\Managed\Microsoft.Managed.DesignTime.targets"
Condition="'$(DebuggerFlavor)' == '' And Exists('$(MSBuildExtensionsPath)\Microsoft\VisualStudio\Managed\Microsoft.Managed.DesignTime.targets')" />


<!--
The GetTargetPathWithTargetPlatformMoniker target uses a BeforeTargets so the only way to disable it is to override it with an empty target.
-->
Expand Down Expand Up @@ -125,7 +122,6 @@

<DacpacFile>%(_ResolvedPackageReference.PhysicalLocation)/tools/%(Identity).dacpac</DacpacFile>
</_ResolvedPackageReference>

<!-- Build a list of package references that include a dacpac file matching the package identity in their tools folder -->
<DacpacReference Include="@(_ResolvedPackageReference)" Condition="Exists(%(DacpacFile))" />
</ItemGroup>
Expand Down Expand Up @@ -156,7 +152,8 @@
<SqlCmdVariableArguments>@(SqlCmdVariable->'-sc %(Identity)', ' ')</SqlCmdVariableArguments>
<PreDeploymentScriptArgument>@(PreDeploy->'--predeploy %(Identity)', ' ')</PreDeploymentScriptArgument>
<PostDeploymentScriptArgument>@(PostDeploy->'--postdeploy %(Identity)', ' ')</PostDeploymentScriptArgument>
<DacpacToolCommand>dotnet $(DacpacToolExe) build $(OutputPathArgument) $(MetadataArguments) $(SqlServerVersionArgument) $(InputFileArguments) $(ReferenceArguments) $(SqlCmdVariableArguments) $(PropertyArguments) $(PreDeploymentScriptArgument) $(PostDeploymentScriptArgument)</DacpacToolCommand>
<RefactorLogScriptArgument>@(RefactorLog->'--refactorlog %(Identity)', ' ')</RefactorLogScriptArgument>
<DacpacToolCommand>dotnet $(DacpacToolExe) build $(OutputPathArgument) $(MetadataArguments) $(SqlServerVersionArgument) $(InputFileArguments) $(ReferenceArguments) $(SqlCmdVariableArguments) $(PropertyArguments) $(PreDeploymentScriptArgument) $(PostDeploymentScriptArgument) $(RefactorLogScriptArgument)</DacpacToolCommand>
</PropertyGroup>
<!-- Run it, except during design-time builds -->
<Message Importance="Low" Text="Running command: $(DacpacToolCommand)" />
Expand Down Expand Up @@ -188,5 +185,4 @@
<Message Importance="Low" Text="Running command: $(DacpacToolCommand)" />
<Exec Command="$(DacpacToolCommand)" />
</Target>

</Project>
61 changes: 53 additions & 8 deletions test/DacpacTool.Tests/PackageBuilderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Linq;
using System.Reflection;
using Microsoft.Data.Tools.Schema.Sql.Packaging;
using Microsoft.SqlServer.Dac;
using Microsoft.SqlServer.Dac.Model;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Shouldly;
Expand Down Expand Up @@ -77,7 +78,6 @@ public void AddReference_FileExists()

// Assert
packageBuilder.Model.GetObject(Procedure.TypeClass, new ObjectIdentifier("dbo", "MyStoredProcedure"), DacQueryScopes.All).ShouldNotBeNull();

// Cleanup
reference.Delete();
}
Expand All @@ -100,7 +100,6 @@ public void AddSqlCmdvariable()
packageBuilder.ValidateModel();
packageBuilder.SaveToDisk(tempFile);
var headerParser = new DacpacHeaderParser.HeaderParser(tempFile.FullName);

headerParser.GetCustomData()
.Where(d => d.Category == "SqlCmdVariables"
&& d.Type == "SqlCmdVariable")
Expand Down Expand Up @@ -130,10 +129,12 @@ public void AddPreDeployment_FilesExist()
packageBuilder.SetMetadata("MyPackage", "1.0.0.0");
packageBuilder.UsingVersion(SqlServerVersion.Sql150);
packageBuilder.ValidateModel();
packageBuilder.SaveToDisk(tempFile);
var packageOptions = new PackageOptions() { RefactorLogPath = "../../../../TestProjectWithPrePost/RefactorLog/TestProjectWithPrePost.refactorlog" };

// Act
packageBuilder.AddPreDeploymentScript(
packageBuilder.SaveToDisk(tempFile, packageOptions);

packageBuilder.AddPreDeploymentScript(
new FileInfo("../../../../TestProjectWithPrePost/Pre-Deployment/Script.PreDeployment.sql"),
tempFile);

Expand All @@ -143,8 +144,9 @@ public void AddPreDeployment_FilesExist()

// Assert
var package = Package.Open(tempFile.FullName);
var prePart = package.GetPart(new Uri("/predeploy.sql", UriKind.Relative));
var prePart = package.GetPart(new Uri("/predeploy.sql", UriKind.Relative));
var postPart = package.GetPart(new Uri("/postdeploy.sql", UriKind.Relative));
var refactorPart = package.GetPart(new Uri("/refactor.xml", UriKind.Relative));

prePart.ShouldNotBeNull();
prePart.ContentType.ShouldBe("text/plain");
Expand All @@ -154,6 +156,10 @@ public void AddPreDeployment_FilesExist()
postPart.ContentType.ShouldBe("text/plain");
postPart.GetStream().ShouldNotBeNull();

refactorPart.ShouldNotBeNull();
refactorPart.ContentType.ShouldBe("text/xml");
refactorPart.GetStream().ShouldNotBeNull();

// Cleanup
package.Close();
tempFile.Delete();
Expand All @@ -177,7 +183,6 @@ public void AddPreDeployment_NoFilePresent()

// Assert
var package = Package.Open(tempFile.FullName);

package.GetParts()
.Where(p => p.Uri == new Uri("/predeploy.sql", UriKind.Relative))
.FirstOrDefault()
Expand Down Expand Up @@ -222,6 +227,31 @@ public void AddPostDeployment_NoFilePresent()
tempFile.Delete();
}

[TestMethod]
public void AddRefactorLog_NoFilePresent()
{
// Arrange
var tempFile = new FileInfo(Path.GetTempFileName());
var packageBuilder = new PackageBuilder();
packageBuilder.SetMetadata("MyPackage", "1.0.0.0");
packageBuilder.UsingVersion(SqlServerVersion.Sql150);
packageBuilder.ValidateModel();

// Act
packageBuilder.SaveToDisk(tempFile, new PackageOptions() { RefactorLogPath = null });

// Assert
var package = Package.Open(tempFile.FullName);

package.GetParts()
.Where(p => p.Uri == new Uri("/refactor.log", UriKind.Relative))
.FirstOrDefault()
.ShouldBeNull();

// Cleanup
package.Close();
tempFile.Delete();
}

[TestMethod]
public void AddPreDeployment_WrongOrder()
Expand All @@ -232,7 +262,6 @@ public void AddPreDeployment_WrongOrder()
packageBuilder.SetMetadata("MyPackage", "1.0.0.0");
packageBuilder.UsingVersion(SqlServerVersion.Sql150);


// Act & Assert
Should.Throw<InvalidOperationException>(() => packageBuilder.AddPreDeploymentScript(null, tempFile));
}
Expand All @@ -246,7 +275,6 @@ public void AddPostDeployment_WrongOrder()
packageBuilder.SetMetadata("MyPackage", "1.0.0.0");
packageBuilder.UsingVersion(SqlServerVersion.Sql150);


// Act & Assert
Should.Throw<InvalidOperationException>(() => packageBuilder.AddPostDeploymentScript(null, tempFile));
}
Expand Down Expand Up @@ -291,6 +319,23 @@ public void AddPostDeployment_PostNotExists()
tempFile.Delete();
}

[TestMethod]
public void AddRefactorLog_RefactorNotExists()
{
// Arrange
var tempFile = new FileInfo(Path.GetTempFileName());
var packageBuilder = new PackageBuilder();
packageBuilder.SetMetadata("MyPackage", "1.0.0.0");
packageBuilder.UsingVersion(SqlServerVersion.Sql150);
packageBuilder.ValidateModel();

// Act & Assert
Should.Throw<DacServicesException>(() => packageBuilder.SaveToDisk(tempFile, new PackageOptions() { RefactorLogPath = "NonExistingProject.refactorlog" }));

// Cleanup
tempFile.Delete();
}

[TestMethod]
[ValidPropertiesTestData]
public void SetProperty_Valid(PropertyInfo property, string value, object expected)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
jmezach marked this conversation as resolved.
Show resolved Hide resolved
<Operations Version="1.0" xmlns="http://schemas.microsoft.com/sqlserver/dac/Serialization/2012/02">
<Operation Name="Rename Refactor" Key="28824ed4-6ce7-42ae-9814-c7409c6e1a8a" ChangeDateTime="09/01/2020 18:56:35">
<Property Name="ElementName" Value="[dbo].[Product].[price]" />
<Property Name="ElementType" Value="SqlSimpleColumn" />
<Property Name="ParentElementName" Value="[dbo].[Product]" />
<Property Name="ParentElementType" Value="SqlTable" />
<Property Name="NewName" Value="Price" />
</Operation>
<Operation Name="Rename Refactor" Key="04c343fa-e6d3-4923-ab01-28a60ddd553f" ChangeDateTime="09/01/2020 18:56:38">
<Property Name="ElementName" Value="[dbo].[Product].[description]" />
<Property Name="ElementType" Value="SqlSimpleColumn" />
<Property Name="ParentElementName" Value="[dbo].[Product]" />
<Property Name="ParentElementType" Value="SqlTable" />
<Property Name="NewName" Value="Description" />
</Operation>
<Operation Name="Rename Refactor" Key="119b3933-c2e4-476c-877b-40c376bf2bde" ChangeDateTime="09/01/2020 18:56:42">
<Property Name="ElementName" Value="[dbo].[Product].[name]" />
<Property Name="ElementType" Value="SqlSimpleColumn" />
<Property Name="ParentElementName" Value="[dbo].[Product]" />
<Property Name="ParentElementType" Value="SqlTable" />
<Property Name="NewName" Value="Name" />
</Operation>
</Operations>