Thursday, January 24, 2008

I want it and don't want it


"There is something in the air" Probably, most of you out there were going crazy on trying to speculate what possibly could it be. Later, it turned out to be a very special something "Macbook Air". It's so far the thinnest and coolest looking laptop ever. No doubts on it. The moment, I saw it I said to myself "I am buying one" like I did it with the iPhone. But now, I am contemplating.. why? BTW, I love my iPhone and I feel it is the best purchase I have done in the past year (My PS3 takes the second place). So, here are my thoughts as to why I am contemplating?

It is definitely not the price (it's little high I agree), missing optical drive, or less hard drive memory but, Simple usability issues:
  • I read today I can't use the Magsafe adapter from other Macbooks or Macbook Pros. Are you kidding me? It's so common to people to share their power adapters all the time especially when you are at meetings, conferences or even at home. I love the Nokia cellphones for this one reason, one power adapter can work with several Nokia handsets (at least, it used to be this way)
  • Remote Disc: It doesn't let you install Windows (not very important), watch DVDs (important) or import Music MP3's or Audio CD's (very important). So, is this utility any worth to general people?
  • Oh, so why don't I buy the Super drive and not bother with Remote disc. There is a catch. I can't use the Super drive with any other laptops or PCs, not even with a Macbook Pro. Apparently, the regular USB ports can't deliver the power required by the Optical Super drive.
My thoughts mentioned here are not a big hassle. But, they are definitely something that everyone would miss at least once in few months. Apple, if you really intended the Macbook Air to be not the only computer in a household, then make sure you when you market it add a line "Not for a Single Computer household".

And BTW, I am a Apple Fanboy.

Wednesday, January 23, 2008

Unit Testing Stored Procedures

Testing Stored Procedures at times can get very difficult. I am sure there are several frameworks and tools available out there. But, I wanted to use NUnit and came across this excellent article by Alex Kuznetsov and Alex Styler. Their framework lets you compare results sets and even entire database modification changes. And as expected, rolls back after the tests, so the db is maintained in a clean state.

But, I wanted some initial test data to be populated in the database and at times the initial data need to be different for different tests. To solve that issue, I used NDbUnit, which helped me to put my database in a known state and thereby increasing repeatability in my unit tests.

Using NDbUnit and Alex's Database Testing framework, I was able to build stable and consistent unit tests to test the database table, stored procedures.

If someone would, like to see an example, please let me know and I could send it to you.

Tuesday, January 22, 2008

Postable content

I am new to blogging and I found the following link useful which makes the contents postaable. This comes in handy when trying to post code block or xml markup tags.

http://www.elliotswan.com/postable/

Include SVN Revision number in the Assembly Info using Nant

Recently, I decided to include the revision number from the SVN repository into the assembly major/minor build information (e.g., 1.0.1234.0, where 1234 is the SVN revision number). The reason I had to do this, our applications gets installed locally at multiple user's computers primarily for testing/demo purposes and over time, it was getting hard to track the problems/bugs resported as it was too hard to figure which version was installed on their machine. And, nant is used as the primary build tool.

First, let's create a target to retrieve the latest SVN revision number.

<target name="RetriveSVNRevisionNumber" description="Retreiving the latest revision number of the working copy">
<echo message="Retrieving Subversion revision number"/>
<exec program="${tortoisesvn.dir}/SubWCRev.exe" >
<arg value="." />
<arg value="revision.include.default" />
<arg value="revision.include" />
</exec>
</target>

The above section retrieves the version number into the local project. For more details, refer this link.

In our case, the contents of revision.include.default file looks like:

<project name="RevisionSpecificProperties">
<property name="revision.value" overwrite="true" value="$WCREV$" />
</project>

Ok, now after retrieving the version number, we need to update our global SolutionInfo.cs file that will hold the assembly information.

<target name="UpdateAssemblyInfo" depends="GenerateBuildNumber" description="Updating the Assembly Information by overwriting the SolutionInfo.cs file with a new one." >
<asminfo output="SolutionInfo.cs" language="CSharp">
<imports>
<import namespace="System.Reflection" />
<import namespace="System.Runtime.InteropServices" />
</imports>
<attributes>
<attribute type="AssemblyCompanyAttribute" value="Company Name" />
<attribute type="AssemblyVersionAttribute" value="${build.version}" />
<attribute type="AssemblyFileVersionAttribute" value="${build.version}" />
</attributes>
</asminfo>
</target>

<target name="GenerateBuildNumber">
<script language="C#">
<imports>
<import name="System.Globalization" />
<import name="System.Threading" />
</imports>
<code>
<![CDATA[
public static void ScriptMain(Project project) {
Version version = new Version(project.Properties["build.version"]);
int major = version.Major;
int minor = version.Minor;
int build = version.Build;
int revision = version.Revision;

build = Convert.ToInt32(project.Properties["revision.value"]);

version = new Version(major, minor, build, revision);
project.Properties["build.version"] = version.ToString();

}

]]>
</code>
</script>
<delete file="revision.include" />
</target>


The above targets, creates/updates an existing SolutionInfo.cs file which can be linked to all the projects in the solution so, all assemblies gets updated with the latest revision number in their build info.

Visual Studio 2005 Customizing build process

Visual Studio 2005 provides a great set of features to customize the build process. Recently, I had an requirement to customize the build process for an in house web application to conditionally include files and project references. In my case, I had an web application projects and multiple library projects which were being references by the webapp. For one particular installation, I had to exclude one library project (say Project One ) and several aspx pages in the web app that were using Project One. MSDN had a nice article on a new feature called web deployment project which allows to customize the build process. But, I didn't want to add an additional project to existing solution, so I tried to solve my problem in a different way.

1. I created a seperate build configuration named "ExcludeProjectOne". Right click on Solution->Choose Configuration Manager->Select New from Active Configuration.
2. Uncheck the project you don't want to build in that configuration (Here, it is ProjectOne)

Now, when you choose the active configuration as ExcludeProjectOne, the library project "Project One" is excluded from the build process. But, it still didn't solve the problem in my web app project which references the ProjectOne and some aspx files which uses it. So, I manually edited the Web.csproj file to achieve the desired action.

I created a new itemgroup element with a condition attribute and placed all the necessary files and the project reference inside the itemgroup element.

The above changes allowed to me have a build configuration for the web application where I can exclude the library and the related aspx pages being built.