Welcome to EMC Consulting Blogs Sign in | Join | Help

SSIS Junkie

VSTS4DBP: Database name does not get included in TFS builds

I found a bug in datadude yesterday and, with a little help, I was able to come up with a workaround so figured I'd post here in case anyone else comes up against it.

In the RTM version of Datadude it is possible to specify the name of the database when it is deployed. As you can see here:

Note the specified name of the database and the name of the Datadude project that are circled.

If you do a build of your datadude project from within Visual Studio then the resultant .sql file will contain something like the following at the top of it:

    1 :setvar databasename "MyExampleDatabase"

    2 USE [master]

    3 GO

    4 

    5 :on error exit

    6 

    7 IF (   DB_ID(N'$(databasename)') IS NOT NULL

    8     AND DATABASEPROPERTYEX(N'$(databasename)','Status') <> N'ONLINE')

    9 BEGIN

   10     RAISERROR(N'The state of the target database, %s, is not set to ONLINE. To deploy to this database, its state must be set to ONLINE.', 16, 127,N'$(databasename)') WITH NOWAIT

   11     RETURN

   12 END

   13 GO

   14 

   15 :on error resume

   16 

   17 CREATE DATABASE [$(databasename)] COLLATE SQL_Latin1_General_CP1_CS_AS

   18 GO

 

However, there's a problem. If you have your database builds integrated into TFS Team Build the name of the database will not appear in the script, instead you will get the default database name which is the name of your project. So it'll look something like this:

    1 :setvar databasename "datadudetmp"

    2 USE [master]

    3 GO

    4 

    5 :on error exit

    6 ...

    7 ...

    8 <snip>

Note how the name of the database is different - its the same as the name of the project as you can see in the screenshot.

 

I spoke to Jamie Laflen about the problem. Jamie is one of the developers of Datadude and he confirmed that this is a bug. He also told me WHY it is a bug. If you check out the .user file that is in the project root folder you will see something like the following:

    1 <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

    2   <PropertyGroup Condition=" '$(Configuration)' == 'Default' ">

    3     <TargetDatabase>MyExampleDatabase</TargetDatabase>

    4   </PropertyGroup>

    5   <PropertyGroup>

    6     <DesignDBName>datadudetmp_DB_43fe3dd4-1ffa-4d51-9192-881f8660573d</DesignDBName>

    7   </PropertyGroup>

    8 </Project>

 You can see that on line 3 that the name of the database is defined in this file. It is NOT defined in the .dbproj file. If you look inside there you'll see the following for the <TargetDatabase> element

    <TargetDatabase>

    </TargetDatabase>

Its not defined! The bug, in a nutshell, is that the Datadude targets file overwrites the setting in the .dbproj file. It creates a problem because the build process checks the following places for the <TargetDatabase> setting:

  1. Project File (i.e. .dbproj file)
  2. Datadude targets file
  3. Common targets
  4. .user file

And that is the order in which it checks them so essentially the last one wins. When you build from the Visual Studio IDE it works but when you build from TFSBuild it doesn't because the .user file is not used during TFS builds.

 

Happily there is an easy fix - it just requires a manual edit of the .dbproj file. There are two steps though:

  1. Fill in the name of the database in the <TargetDatabase> element
  2. Move that element to a property group after the import of the Datadude targets file

In other words, you need to modify your .dbproj file to make it look like this:

  <Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v8.0\TeamData\Microsoft.VisualStudio.TeamSystem.Data.Tasks.targets" />

  <PropertyGroup Condition=" '$(Configuration)' == 'Default' ">

    <TargetDatabase>MyExampleDatabase</TargetDatabase>

  </PropertyGroup>

  <ItemGroup>

 

That's it! That's all you need to do. Hope this helps.

 

Thank you to Jamie Laflen for taking the time to help me out with this. He tells me that this bug will be fixed in an upcoming version of Datadude. The fix is that the targets file only overwrites the <TargetDatabase> setting if it is not defined in the .dbproj file. This means that you will not have to move <TargetDatabase>MyExampleDatabase</TargetDatabase> to after the import directive.

 

However, you will still have to define the database name manually inthe .dbproj file - it is not set according to the value entered in the Build properties (as per the screenshot above). That didn't seem right to me to and I asked Jamie (there's too many Jamie's in this blog post :) what the rationale for that was. Here is his answer:

The idea was that there are a set of build properties that are relevant to a user’s sandbox environment and not to the team as a whole; for example, the target connection string and designdb name.  You could argue that the target database does not fall into this sandbox category, and this argument does make sense for TFS. 

This is an area where we could certainly use feedback from our customers.  Is the sandboxing mechanism completely unknown and everyone just standardizes on a deployment target, or are customers checking in the .user file (oy – I hope not!).  Do customers actually use different solution configurations, or, does everyone just stick with “Default.”

So, the datadude team are looking for feedback on this behaviour. Feel free to submit your feedback as a comment on this blog and I shall collate them and feedback to Jamie. Otherwise, contact the datadude team through the usual channels:

-Jamie

 

 

Comments

 

Grant Fritchey said:

Well, based on our conversations over at SQL Server Central, you already know my feedback, but just in case, put me down as (oi!) checking the .user file into the server because, yes, we are using configurations and the sandbox methods would be killing us otherwise.

January 24, 2008 14:49
New Comments to this post are disabled

This Blog

Syndication

Powered by Community Server (Personal Edition), by Telligent Systems