<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-4003504748921453462</id><updated>2011-11-27T23:16:10.155Z</updated><category term='NUnit'/><category term='Acceptance Testing'/><category term='SqLite'/><category term='Architecture'/><category term='XP'/><category term='SQL Server 2008 - Katmai'/><category term='SQL Server 2000'/><category term='.Net'/><category term='SQL Server'/><category term='SQL Server 2005'/><category term='SoapUI'/><category term='ASP'/><category term='ScrewTurn'/><category term='Threads'/><category term='COM'/><category term='Build'/><category term='MSBuild'/><category term='Oracle'/><category term='IIS'/><category term='Watin'/><category term='Web'/><category term='Open Source'/><category term='C#'/><category term='Business'/><category term='Browser'/><category term='TDD'/><category term='WCF'/><category term='Agile'/><category term='Ruby'/><category term='Cucumber'/><category term='BDD'/><category term='Database'/><category term='Nant'/><category term='Scrum'/><category term='Cruise Control.Net'/><category term='Astoria'/><category term='Software'/><category term='Katmai'/><category term='Watir'/><category term='T-SQL'/><category term='ASP.Net'/><category term='Wiki'/><category term='Specflow'/><category term='Teamcity'/><category term='Practices'/><title type='text'>Agile Driven Development</title><subtitle type='html'>Log4Agile Development Practices</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://www.agiledrivendevelopment.net/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://www.agiledrivendevelopment.net/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Log4Agile</name><uri>http://www.blogger.com/profile/04640347817726894882</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>50</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-4003504748921453462.post-5360001322321692751</id><published>2011-09-20T21:59:00.001+01:00</published><updated>2011-09-20T21:59:44.579+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Practices'/><category scheme='http://www.blogger.com/atom/ns#' term='BDD'/><category scheme='http://www.blogger.com/atom/ns#' term='Agile'/><title type='text'>Effect Mapping to manage products</title><content type='html'>&lt;p&gt;Just been to this talk by Gojko on Product Management using Effect Mapping. It is a technique which is useful for high level project visualisation. It is very similar to mind mapping technique where stakeholders, users and teams colloborate on project scope. &lt;/p&gt; &lt;p&gt;It helps reduce scope of wish lists and helps teams focus on business goals by asking the questions Why?, Who?, How? and What? in this orders&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Why&lt;/strong&gt;? Allows you to narrow down to the business goal. This is the centre piece of your effect map from where all other discussions should start and reason upon&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Who&lt;/strong&gt;? It is not the user but it is who can cause the desired effect to achieve the business goal. In most cases these are project/ product stakeholders. &lt;/p&gt; &lt;p&gt;&lt;strong&gt;How&lt;/strong&gt;? For each stakeholder , identify how the target group can achieve or obstruct the desired effect in real life and not in terms of software, these should effectively be stakeholder needs&lt;/p&gt; &lt;p&gt;&lt;strong&gt;What&lt;/strong&gt;? For each stakeholder identify what business activities or software capabilities would support the needs of the stakeholder. These become your epics in the product backlog&lt;/p&gt; &lt;p&gt;At the end of the effect map both the stakeholders and team should be able to see the synergy of the business goals and what needs to be achieved. &lt;/p&gt; &lt;p&gt;For more see, Gojko’s white paper on this see &lt;a title="http://gojko.net/effect-map" href="http://gojko.net/effect-map"&gt;http://gojko.net/effect-map&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Some advice from people who have used this are..&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Getting the right number of people can be a challenge  &lt;li&gt;Staying focussed and at the right level of detail is important  &lt;li&gt;Ensuring enough focus on the how is important  &lt;li&gt;Keeping everyone away from solutionising is a real big challenge when technical people are involved  &lt;li&gt;Ideal group size of 5-8 when working for a time box of 2-3 hours  &lt;li&gt;Will be of immense value to the business&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;This technique is not necessarily something for agile projects you could use it even for waterfall projects&lt;/p&gt; &lt;p&gt;A useful tool I have found which you can use for this is at &lt;a href="http://www.mindmeister.com"&gt;www.mindmeister.com&lt;/a&gt;. Check it out its pretty handy. Even if you are a developer striving to do something on your own , if you put your ideas on a mind map it will help you visualize the idea. &lt;img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://lh6.ggpht.com/-YevAtMUv_Uc/Tnj-uhn_4OI/AAAAAAAAAHw/frBW7apvA8E/wlEmoticon-smile2.png?imgmax=800"&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4003504748921453462-5360001322321692751?l=www.agiledrivendevelopment.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.agiledrivendevelopment.net/feeds/5360001322321692751/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4003504748921453462&amp;postID=5360001322321692751' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/5360001322321692751'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/5360001322321692751'/><link rel='alternate' type='text/html' href='http://www.agiledrivendevelopment.net/2011/09/effect-mapping-to-manage-products.html' title='Effect Mapping to manage products'/><author><name>Log4Agile</name><uri>http://www.blogger.com/profile/04640347817726894882</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/-YevAtMUv_Uc/Tnj-uhn_4OI/AAAAAAAAAHw/frBW7apvA8E/s72-c/wlEmoticon-smile2.png?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4003504748921453462.post-5193791646076955068</id><published>2011-09-16T09:41:00.001+01:00</published><updated>2011-09-17T20:15:10.790+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SoapUI'/><category scheme='http://www.blogger.com/atom/ns#' term='Acceptance Testing'/><category scheme='http://www.blogger.com/atom/ns#' term='Teamcity'/><category scheme='http://www.blogger.com/atom/ns#' term='MSBuild'/><title type='text'>Running SOAP UI Tests in Teamcity using MSBuild</title><content type='html'>&lt;p&gt;One of the web services we have has a bunch of SOAP UI Tests. I wanted to make sure when this was run on the build server we have good feedback for each test case rather than a whole build running a pack of tests and telling you if it failed or passed. Kind of a reason i was moving this build away to Teamcity from cruise control&lt;/p&gt; &lt;p&gt;The MSBuild script is as below. I had to define the variables I need and the Directory where all project files for Soap UI can be found. &lt;/p&gt; &lt;div id="codeSnippetWrapper"&gt; &lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Import&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Project&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum2"&gt;   2:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;PropertyGroup&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum3"&gt;   3:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;SoapUIDir&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;$(MSBuildProjectDirectory)\SoapUI&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;SoapUIDir&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum4"&gt;   4:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;SoapTestTool&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;C:\Program Files\eviware\soapUI-4.0.0\bin\testrunner.bat&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;SoapTestTool&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum5"&gt;   5:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;PropertyGroup&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The next thing I had to do was run each project file using the SOAP Ui testrunner.bat file. &lt;/p&gt;
&lt;p&gt;The options I have used –j will ensure JUnit style reports are pushed out of the Soap UI test runner, for local builds you could just make it push out Html reports&lt;/p&gt;
&lt;p&gt;-h allows you to specify the host header to use for your Urls, The host header you supply here will override what is stored in the SOAP UI projects , so you run these tests on different sites based on your environment.&lt;/p&gt;
&lt;p&gt;I have done a FileUpdate because i wanted to change Urls of the service from the old server to the ones on the new servers, you wont need this and it can be ignored&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt;   1:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum2"&gt;   2:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Target&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Name&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="ConfigureSoapUITests"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum3"&gt;   3:&lt;/span&gt;    &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;MakeDir&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Directories&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="$(SoapUIDir)\Report"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;    &lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum4"&gt;   4:&lt;/span&gt;    &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;ItemGroup&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum5"&gt;   5:&lt;/span&gt;      &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;SoapUIProjectFiles&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Include&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="$(SoapUIDir)\*-soapui-project.xml"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;      &lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum6"&gt;   6:&lt;/span&gt;    &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;ItemGroup&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum7"&gt;   7:&lt;/span&gt;    &lt;span style="color: #008000"&gt;&amp;lt;!-- Replace old server urls with new ones --&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum8"&gt;   8:&lt;/span&gt;    &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;FileUpdate&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Files&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="@(SoapUIProjectFiles)"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Regex&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="$(someurl)"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ReplacementText&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="$(newurl)"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;IgnoreCase&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="true"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum9"&gt;   9:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Target&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum10"&gt;  10:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum11"&gt;  11:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Target&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Name&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="RunFunctionalSoapUITests"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;DependsOnTargets&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="ConfigureSoapUITests"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum12"&gt;  12:&lt;/span&gt;    &lt;span style="color: #008000"&gt;&amp;lt;!--Run all the soap ui functional tests--&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum13"&gt;  13:&lt;/span&gt;    &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Exec&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Command&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="&amp;amp;quot;$(SoapTestTool)&amp;amp;quot; &amp;amp;quot;%(SoapUIProjectFiles.Identity)&amp;amp;quot; -h &amp;amp;quot;$(HostHeader)&amp;amp;quot; -I -r -a -j -f &amp;amp;quot;$(SoapUIDir)\Report&amp;amp;quot;"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum14"&gt;  14:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Target&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;At this point I hooked up the MSBuild target to run on Teamcity using the MSBuild runner, for the target “RunFunctionalSoapUITests”. The feedback wasn't good&lt;/p&gt;
&lt;p&gt;The final bit you need to do is configure Teamcity to read the xml styled junit reports that the test runner is spitting out. You can do this using the Build feature option for XmlReport processing as shown in the screen shot. &lt;/p&gt;
&lt;p&gt;Now trigger the build if you have sorted out all the other variables required you can run the build and see the output on Teamcity, pretty good really on test case by test case basis. &lt;/p&gt;
&lt;p&gt;&lt;a href="http://lh5.ggpht.com/-OSsmxL55WSY/TnMLrP3tMFI/AAAAAAAAAHo/6qgn25ItgaM/s1600-h/buildfeature%25255B2%25255D.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="buildfeature" border="0" alt="buildfeature" src="http://lh3.ggpht.com/-khHcwTK885c/TnMLrVP-4wI/AAAAAAAAAHs/srpAUE2fPPQ/buildfeature_thumb.jpg?imgmax=800" width="244" height="212"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;For failed tests I added a configuration for artifacts as follows, Teamcity will show you the response but to see the entire request response file , you need to setup artifacts as follows. All failed test cases create a .txt file which ends with FAILED.txt, so I push these as artifacts and i can see this for failed tests, &lt;/p&gt;
&lt;p&gt;SoapUI/Report/*FAILED.txt =&amp;gt; FailedTests&lt;/p&gt;
&lt;p&gt;I find this useful that with little effort so much could be done and feedback is really good&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4003504748921453462-5193791646076955068?l=www.agiledrivendevelopment.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.agiledrivendevelopment.net/feeds/5193791646076955068/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4003504748921453462&amp;postID=5193791646076955068' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/5193791646076955068'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/5193791646076955068'/><link rel='alternate' type='text/html' href='http://www.agiledrivendevelopment.net/2011/09/running-soap-ui-tests-in-teamcity-using.html' title='Running SOAP UI Tests in Teamcity using MSBuild'/><author><name>Log4Agile</name><uri>http://www.blogger.com/profile/04640347817726894882</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/-khHcwTK885c/TnMLrVP-4wI/AAAAAAAAAHs/srpAUE2fPPQ/s72-c/buildfeature_thumb.jpg?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4003504748921453462.post-8189488657340714024</id><published>2011-09-06T23:39:00.001+01:00</published><updated>2011-09-07T00:16:17.989+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='BDD'/><category scheme='http://www.blogger.com/atom/ns#' term='Acceptance Testing'/><category scheme='http://www.blogger.com/atom/ns#' term='Agile'/><title type='text'>User Story - A Promise to have a conversation</title><content type='html'>&lt;p&gt;&amp;nbsp; &lt;p&gt;Time and again it is important to constantly remind your team that a User story is not just a required but is actually the premise on which you promise to have conversations in the team and with the user. It is by no means a finalised description of what the system should be doing. The first time it is written the analyst or product owner only has as much information as the user gives them. This information is pretty much raw most often a wish list off some post-it notes on the edge of the users monitor. It will have information of what the user wants to achieve or the grand plan of how something could be done brilliantly to save money or achieve a business goal. It will not tell you what the user wants the system to do.  &lt;p&gt;This is where collaboration is fundamental to the idea of agile development ( or should i say &lt;img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://lh6.ggpht.com/-Uzw8fYnUAzY/TmahLZSuxUI/AAAAAAAAAHk/Fwv7UR994ZY/wlEmoticon-smile%25255B2%25255D.png?imgmax=800"&gt; ADD – Agile Driven Development). The user story is to be evolved by having conversations between various functional experts. By functional experts I mean a QA, a developer, an analyst even a UI designer for that matter. The question is why? I guess it’s because these functional experts can think of the software that is to be built with a view of what the system should do, A user story should convey both what the user wants to do and what the system will do to be complete, clearly the initial draft of these stories didn’t do this.  &lt;p&gt;If asked why collaborate, why don’t we just let each of these functional. The risk is probably as we can all guess  &lt;p&gt;When a developer evolves a story on his own he is going to make sure it is technically brilliant (may be not always) and eventually forget what the user wants , in most cases this conversation ends up in the developer trying to define what the system should do and what the user wants.. yes funny how many over engineered systems have we not seen and been part of in the past  &lt;p&gt;When a UI designer is going to evolve it on his own he is going to make sure it is pretty software and most likely to make it usable but with lack of clarity of the functionality that the user really needs, he just has his wireframes which show the user the dream he wants to have &lt;img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://lh6.ggpht.com/-Uzw8fYnUAzY/TmahLZSuxUI/AAAAAAAAAHk/Fwv7UR994ZY/wlEmoticon-smile%25255B2%25255D.png?imgmax=800"&gt;  &lt;p&gt;When a QA is going to evolves this on his own he is going to make sure it is very testable, infact so testable that they start defining behaviour of the application and the implementation of the software even though they may or may not match what the user wants.. oh well make it testable but so testable that the stuff you build is not usable.  &lt;p&gt;The analyst on the other hand is so caught up with making sure he conveys what the user wants he forgets most often how to test the functionality or in some case forgets to tell the team what the system should do &lt;img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://lh6.ggpht.com/-Uzw8fYnUAzY/TmahLZSuxUI/AAAAAAAAAHk/Fwv7UR994ZY/wlEmoticon-smile%25255B2%25255D.png?imgmax=800"&gt; , well don’t blame him they are not the functional experts on the technical implementation of a system  &lt;p&gt;We have seen these things happening all the time, any form of methodology without collaboration kind of summarises the situation in which these things happen. Alright then, so we can’t do without collaboration so what now and how far do we go with collaboration? How do we know where to stop, well I am going to have to be vague and say well it’s for the team to figure it out in the context of the system they are working but then, I guess some of the answer lies in the ability of the team and the user to work towards coming up with stories which adhere to INSPECT and the story itself becoming the documentation of the system. As Gojko says in his book “Specification by Example” stories evolve into living documentation of the system. When you can actually read a story and express in simple English the aspects of what the user wants to do and what the system is doing to achieve the users need you could say you have reached that point where you can stop and move on to the next bit of functionality. Again living documentation is not written once; it evolves over a period of time by refactoring constantly; similar to how a domain model is constantly built in code by constantly refactoring and entities in the model. Teams which collaborate constantly recognise this need to bring the stories used to build the system in line with the domain concepts in the system, and vice versa, it is a constant cycle of refactor and improve.. Oh should I say iterate and continuously improve... Rings a bell... Agile?. In the real life, collaboration is underrated by teams and it is something teams think they should do because it needs to be done. Most agile teams do this once for every story (I am laughing already) while estimating the story not so much while actually implementing it. That said there are also teams which constantly collaborate. I guess question is which team are you working in and what are you going to do about it ?&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4003504748921453462-8189488657340714024?l=www.agiledrivendevelopment.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.agiledrivendevelopment.net/feeds/8189488657340714024/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4003504748921453462&amp;postID=8189488657340714024' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/8189488657340714024'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/8189488657340714024'/><link rel='alternate' type='text/html' href='http://www.agiledrivendevelopment.net/2011/09/user-story-promise-to-have-conversation.html' title='User Story - A Promise to have a conversation'/><author><name>Log4Agile</name><uri>http://www.blogger.com/profile/04640347817726894882</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/-Uzw8fYnUAzY/TmahLZSuxUI/AAAAAAAAAHk/Fwv7UR994ZY/s72-c/wlEmoticon-smile%25255B2%25255D.png?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4003504748921453462.post-6892785943276172644</id><published>2011-06-27T09:12:00.001+01:00</published><updated>2011-07-04T08:42:17.276+01:00</updated><title type='text'>Screw Unit – Teamcity Integration</title><content type='html'>&lt;p&gt;I had to setup up client side tests to run for my team on Teamcity. I initially thought I should use rake to do this, but then I had to leverage the fact that my team is comfortable with the .Net stack and not so much with Ruby. At this point I just thought i should use a unit test to run my screw unit test via Watin in a browser. This idea is available in a lot of other blogs for QUnit tests. The unit test opens the suite.html , parses the file and reports if the test failed or passed.This works fine. But then when a test failed I had to either look at the logs of the build or had to navigate to the Url, this feedback was ok but not great &lt;/p&gt; &lt;p&gt;I tried to write a teamcity test runner for screw unit which will send messages to TeamCity , but this was hard work and the effort involved was simply too much&lt;/p&gt; &lt;p&gt;If not real time feedback from a test runner, at least seeing the suite.html as a tab on my build would be good.. so I just pushed the artifacts for the build to include the Screw Unit test pack and set up a new tab in TeamCity server config file (main.config file) called Screw Unit Report. This tab would open the html file for the tests from the artifacts. So now I have TeamCity showing the Screw Unit suite as a tab, that's better, the only thing is when you click on the tab it runs the tests every time, but that's not such a big deal really &lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://lh6.ggpht.com/-P9s-TrYbmdo/TfaBX3B0GyI/AAAAAAAAAHA/4llJZZGky1c/wlEmoticon-smile2.png?imgmax=800"&gt;. The effort involved in setting this up was 30 minutes. (I already knew how to setup tabs in TeamCity )&lt;/p&gt; &lt;p&gt;So to summarize&lt;/p&gt; &lt;p&gt;1. Write a unit test runner which will use Watin to open the Screw Unit test suite.html file. &lt;/p&gt; &lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt; &lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum2"&gt;   2:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum3"&gt;   3:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.Diagnostics;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum4"&gt;   4:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.IO;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum5"&gt;   5:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.Linq;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum6"&gt;   6:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.Threading;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum7"&gt;   7:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; MbUnit.Framework;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum8"&gt;   8:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; NHamcrest.Core;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum9"&gt;   9:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; WatiN.Core;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum10"&gt;  10:&lt;/span&gt;  &lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum11"&gt;  11:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;namespace&lt;/span&gt; Tests&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum12"&gt;  12:&lt;/span&gt; {&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum13"&gt;  13:&lt;/span&gt;     [TestFixture]&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum14"&gt;  14:&lt;/span&gt;     [Timeout(600)]&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum15"&gt;  15:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; TestRunner&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum16"&gt;  16:&lt;/span&gt;     {&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum17"&gt;  17:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; FireFox browser;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum18"&gt;  18:&lt;/span&gt;  &lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum19"&gt;  19:&lt;/span&gt;         [SetUp]&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum20"&gt;  20:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; SetupBrowser()&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum21"&gt;  21:&lt;/span&gt;         {&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum22"&gt;  22:&lt;/span&gt;             browser = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; FireFox();&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum23"&gt;  23:&lt;/span&gt;         }&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum24"&gt;  24:&lt;/span&gt;         &lt;span style="color: #008000"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum25"&gt;  25:&lt;/span&gt;         &lt;span style="color: #008000"&gt;/// Tests that ScrewUnit tests pass&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum26"&gt;  26:&lt;/span&gt;         &lt;span style="color: #008000"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum27"&gt;  27:&lt;/span&gt;         [Test]&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum28"&gt;  28:&lt;/span&gt;         [Category(&lt;span style="color: #006080"&gt;"ScrewUnitTests"&lt;/span&gt;)]&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum29"&gt;  29:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; RunAllTestsFromSuite()&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum30"&gt;  30:&lt;/span&gt;         {&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum31"&gt;  31:&lt;/span&gt;             var screwUnitTestFile = Path.Combine(Environment.CurrentDirectory, &lt;span style="color: #006080"&gt;@"Javascript\ScrewUnit\tests\spec\suite.html"&lt;/span&gt;);&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum32"&gt;  32:&lt;/span&gt;             browser.GoTo(&lt;span style="color: #006080"&gt;@"file:///"&lt;/span&gt; + screwUnitTestFile);&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum33"&gt;  33:&lt;/span&gt;             browser.WaitForComplete(5000);&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum34"&gt;  34:&lt;/span&gt;  &lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum35"&gt;  35:&lt;/span&gt;             var resultsDiv = browser.ElementWithTag(&lt;span style="color: #006080"&gt;"h3"&lt;/span&gt;, Find.ByClass(&lt;span style="color: #006080"&gt;"status"&lt;/span&gt;));&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum36"&gt;  36:&lt;/span&gt;             resultsDiv.WaitUntil(() =&amp;gt; resultsDiv.Exists &amp;amp;&amp;amp; !resultsDiv.Text.ToLower().Contains(&lt;span style="color: #006080"&gt;"Running"&lt;/span&gt;), 30000);&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum37"&gt;  37:&lt;/span&gt;  &lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum38"&gt;  38:&lt;/span&gt;             AssertThatTestsHavePassed(resultsDiv);&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum39"&gt;  39:&lt;/span&gt;         }&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum40"&gt;  40:&lt;/span&gt;  &lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum41"&gt;  41:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; AssertThatTestsHavePassed(Element resultsDiv)&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum42"&gt;  42:&lt;/span&gt;         {&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum43"&gt;  43:&lt;/span&gt;             var resultsArray = resultsDiv.Text.Split(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt;[] { &lt;span style="color: #006080"&gt;' '&lt;/span&gt; });&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum44"&gt;  44:&lt;/span&gt;  &lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum45"&gt;  45:&lt;/span&gt;             var numberOfFailures = Int32.Parse(resultsArray.ElementAt(2));&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum46"&gt;  46:&lt;/span&gt;  &lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum47"&gt;  47:&lt;/span&gt;             Assert.That(numberOfFailures, Is.EqualTo(0), &lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.Format(&lt;span style="color: #006080"&gt;"{0}. Click on the Screw Unit Report Tab to see the details"&lt;/span&gt;, resultsDiv.Text));&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum48"&gt;  48:&lt;/span&gt;         }&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum49"&gt;  49:&lt;/span&gt;  &lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum50"&gt;  50:&lt;/span&gt;         [TearDown]&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum51"&gt;  51:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; TearDownTestRunner()&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum52"&gt;  52:&lt;/span&gt;         {&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum53"&gt;  53:&lt;/span&gt;             browser.Dispose();&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum54"&gt;  54:&lt;/span&gt;             Thread.Sleep(2000);&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum55"&gt;  55:&lt;/span&gt;             var browserProcesses = Process.GetProcesses()&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum56"&gt;  56:&lt;/span&gt;                     .Where(process =&amp;gt; process.ProcessName.ToLower().Contains(&lt;span style="color: #006080"&gt;"firefox"&lt;/span&gt;) &amp;amp;&amp;amp; process.StartInfo.UserName.ToLower().Contains(&lt;span style="color: #006080"&gt;"build"&lt;/span&gt;));&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum57"&gt;  57:&lt;/span&gt;                     browserProcesses.Each(p =&amp;gt; p.Kill());&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum58"&gt;  58:&lt;/span&gt;         }&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum59"&gt;  59:&lt;/span&gt;        &lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum60"&gt;  60:&lt;/span&gt;  &lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum61"&gt;  61:&lt;/span&gt;     }&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum62"&gt;  62:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; Extensions&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum63"&gt;  63:&lt;/span&gt;     {&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum64"&gt;  64:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Each&amp;lt;T&amp;gt;(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt; IEnumerable&amp;lt;T&amp;gt; collection, Action&amp;lt;T&amp;gt; action)&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum65"&gt;  65:&lt;/span&gt;         {&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum66"&gt;  66:&lt;/span&gt;             &lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt; (var item &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; collection)&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum67"&gt;  67:&lt;/span&gt;             {&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum68"&gt;  68:&lt;/span&gt;                 action(item);&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum69"&gt;  69:&lt;/span&gt;             }&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum70"&gt;  70:&lt;/span&gt;         }&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum71"&gt;  71:&lt;/span&gt;       &lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum72"&gt;  72:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; WaitUntil(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt; Element element, Func&amp;lt;&lt;span style="color: #0000ff"&gt;bool&lt;/span&gt;&amp;gt; predicate, &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; timeout)&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum73"&gt;  73:&lt;/span&gt;         {&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum74"&gt;  74:&lt;/span&gt;             var startTime = DateTime.Now;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum75"&gt;  75:&lt;/span&gt;  &lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum76"&gt;  76:&lt;/span&gt;             &lt;span style="color: #0000ff"&gt;while&lt;/span&gt; (!predicate())&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum77"&gt;  77:&lt;/span&gt;             {&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum78"&gt;  78:&lt;/span&gt;                 Thread.Sleep(1000);&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum79"&gt;  79:&lt;/span&gt;                 var now = DateTime.Now;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum80"&gt;  80:&lt;/span&gt;  &lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum81"&gt;  81:&lt;/span&gt;                 &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; ((now - startTime).TotalMilliseconds &amp;gt; timeout) &lt;span style="color: #0000ff"&gt;throw&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; TimeoutException(&lt;span style="color: #006080"&gt;"Timed out waiting for condition to become true"&lt;/span&gt;);&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum82"&gt;  82:&lt;/span&gt;             }&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum83"&gt;  83:&lt;/span&gt;         }&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum84"&gt;  84:&lt;/span&gt;     }&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum85"&gt;  85:&lt;/span&gt; }&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;2. Push the Screw Unit test suite into the artifacts of your build in the team city configuration of your build&lt;/p&gt;
&lt;p&gt;3. Configure the main.config file located at &amp;lt;TeamCity Install Folder&amp;gt;\.BuildServer\configuration\confg to create a new tab. &lt;/p&gt;
&lt;p&gt;Run your build and you should be able to see the screwunit report on the build server now&lt;/p&gt;
&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
&lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt;   1:&lt;/span&gt; &amp;lt;server&amp;gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum2"&gt;   2:&lt;/span&gt;  &lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum3"&gt;   3:&lt;/span&gt; &amp;lt;report-tab title=&lt;span style="color: #006080"&gt;"Screw Unit Report"&lt;/span&gt; basePath=&lt;span style="color: #006080"&gt;"ScrewUnit.zip"&lt;/span&gt; startPage=&lt;span style="color: #006080"&gt;"tests/spec/suite.html"&lt;/span&gt; /&amp;gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum4"&gt;   4:&lt;/span&gt;  &lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum5"&gt;   5:&lt;/span&gt; &amp;lt;/server&amp;gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum6"&gt;   6:&lt;/span&gt;  &lt;/pre&gt;&lt;!--CRLF--&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://lh5.ggpht.com/-hY81Wb5YvnU/ThFuuE3vhNI/AAAAAAAAAHc/eCbAnLg6WZ8/s1600-h/screwunittests-report%25255B5%25255D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="screwunittests-report" border="0" alt="screwunittests-report" src="http://lh4.ggpht.com/-JBAVV6cVtrc/ThFuugqA5mI/AAAAAAAAAHg/F5DMa87dxRw/screwunittests-report_thumb%25255B3%25255D.png?imgmax=800" width="744" height="349"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;You could use the screwunit test sample i took from git hub to test this &lt;a href="https://skydrive.live.com/redir.aspx?cid=64f228694cfcbc1e&amp;amp;resid=64F228694CFCBC1E!399"&gt;Screw Unit Tests sample&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4003504748921453462-6892785943276172644?l=www.agiledrivendevelopment.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.agiledrivendevelopment.net/feeds/6892785943276172644/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4003504748921453462&amp;postID=6892785943276172644' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/6892785943276172644'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/6892785943276172644'/><link rel='alternate' type='text/html' href='http://www.agiledrivendevelopment.net/2011/06/screw-unit-teamcity-integration.html' title='Screw Unit – Teamcity Integration'/><author><name>Log4Agile</name><uri>http://www.blogger.com/profile/04640347817726894882</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/-P9s-TrYbmdo/TfaBX3B0GyI/AAAAAAAAAHA/4llJZZGky1c/s72-c/wlEmoticon-smile2.png?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4003504748921453462.post-1963027252792390764</id><published>2011-06-16T17:37:00.001+01:00</published><updated>2011-06-21T14:23:03.275+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Cucumber'/><category scheme='http://www.blogger.com/atom/ns#' term='BDD'/><category scheme='http://www.blogger.com/atom/ns#' term='Ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='Open Source'/><category scheme='http://www.blogger.com/atom/ns#' term='Acceptance Testing'/><category scheme='http://www.blogger.com/atom/ns#' term='Agile'/><category scheme='http://www.blogger.com/atom/ns#' term='Watir'/><title type='text'>Step by Step - Cucumber, WatiR and Ruby installation tips</title><content type='html'>&lt;p align="left"&gt;There are few road blocks you hit when you go about the process of installing Cucumber, Watir and Ruby the first time, you have to search all the information and then as you install there are some things that work while some dont , I just thought it may be a good idea to consolidate the information in one place for myself if i do run into this situation of having to install this again. I have tried and tested this thrice and use the same process to install our test agents.  &lt;ul&gt; &lt;li&gt; &lt;div align="left"&gt;&lt;strong&gt;Installing Ruby&lt;/strong&gt; &lt;/div&gt;&lt;/li&gt;&lt;/ul&gt; &lt;blockquote&gt; &lt;p align="left"&gt;#Tip – Choosing the version of Ruby installer &lt;/p&gt;&lt;/blockquote&gt; &lt;p align="left"&gt;Watir is stable with Ruby 1.8.7 so dont carried away and install 1.9.x of ruby , you learn the hard way that it is not going to work properly.  &lt;p align="left"&gt;See &lt;a href="http://watir.com/installation"&gt;Http://watir.com/installation&lt;/a&gt; for updates on when 1.9.x support will be provided. Go to &lt;a title="http://rubyforge.org/frs/download.php/74293/rubyinstaller-1.8.7-p334.exe" href="http://rubyforge.org/frs/download.php/74293/rubyinstaller-1.8.7-p334.exe"&gt;http://rubyforge.org/frs/download.php/74293/rubyinstaller-1.8.7-p334.exe&lt;/a&gt; download the exe and run the installer. I chose the installation folder to be called just ruby as I want to avoid installing multiple versions for now.  &lt;p align="left"&gt;&amp;nbsp; &lt;ul&gt; &lt;li&gt; &lt;div align="left"&gt;&lt;strong&gt;Ruby Path &lt;/strong&gt;&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p align="left"&gt;Check if "c:\ruby\bin" is included in the path (else run PATH=%PATH%;c:\ruby\bin at the command prompt) &lt;/p&gt; &lt;ul&gt; &lt;li&gt; &lt;div align="left"&gt;&lt;strong&gt;Installing the Dev Kit for Ruby&lt;/strong&gt;&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p align="left"&gt;Download &lt;a href="http://github.com/downloads/oneclick/rubyinstaller/DevKit-tdm-32-4.5.1-20101214-1400-sfx.exe"&gt;http://github.com/downloads/oneclick/rubyinstaller/DevKit-tdm-32-4.5.1-20101214-1400-sfx.exe&lt;/a&gt; .&lt;/p&gt; &lt;ol&gt; &lt;li&gt; &lt;div align="left"&gt;Click on it to extract files to a folder &amp;lt;DEV-KIT-FOLDER&amp;gt;. &lt;/div&gt; &lt;li&gt; &lt;div align="left"&gt;Open a command prompt for the &amp;lt;DEV-KIT-FOLDER&amp;gt;. &lt;/div&gt; &lt;li&gt; &lt;div align="left"&gt;Run the command “&lt;strong&gt;ruby dk.rb init&lt;/strong&gt;” &lt;/div&gt; &lt;li&gt; &lt;div align="left"&gt;Run the command “&lt;strong&gt;ruby dk.rb install&lt;/strong&gt;”&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt; &lt;p align="left"&gt;Not sure if you need this but run a “gem update system” and it should say Nothing to update :). &lt;/p&gt; &lt;ul&gt; &lt;li&gt; &lt;div align="left"&gt;&lt;strong&gt;Installing gems&lt;/strong&gt;&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p align="left"&gt;Now at the command prompt &lt;/p&gt; &lt;ol&gt; &lt;li&gt; &lt;div align="left"&gt;Run “gem install cucumber”. &lt;/div&gt; &lt;li&gt; &lt;div align="left"&gt;Run “gem install watir” &lt;/div&gt; &lt;li&gt; &lt;div align="left"&gt;Run “gem install “win32console” &lt;/div&gt; &lt;li&gt; &lt;div align="left"&gt;Run “gem install rspec”&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt; &lt;ul&gt; &lt;li&gt; &lt;div align="left"&gt;&lt;strong&gt;Installing ANSI con – &lt;/strong&gt;if you are unable to see colours on your console window when you run a cucumber feature, you may need to install ANSICON&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt; &lt;ol&gt; &lt;li&gt; &lt;div align="left"&gt;Go to &lt;a href="http://adoxa.110mb.com/ansicon"&gt;http://adoxa.110mb.com/ansicon&lt;/a&gt; . Download AnsiCon 140.&lt;/div&gt; &lt;li&gt; &lt;div align="left"&gt;Extract the files.&lt;/div&gt; &lt;li&gt; &lt;div align="left"&gt;Open a command prompt for the folder you have extracted the files in &lt;br&gt;cd to &lt;strong&gt;x64&lt;/strong&gt; folder if you use a 64 bit machine or x86 folder if you use a 32 bit machine&lt;br&gt;type "ansicon.exe -i"&lt;br&gt;Close the command prompt , open a new one &lt;/div&gt;&lt;/li&gt;&lt;/ol&gt; &lt;p align="left"&gt;This should be sufficient to run cucumber features now. In a weeks time I will post a project framework with some useful stuff for ruby / selenium / cucumber which can be downloaded so you can go about building tests quickly&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4003504748921453462-1963027252792390764?l=www.agiledrivendevelopment.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.agiledrivendevelopment.net/feeds/1963027252792390764/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4003504748921453462&amp;postID=1963027252792390764' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/1963027252792390764'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/1963027252792390764'/><link rel='alternate' type='text/html' href='http://www.agiledrivendevelopment.net/2011/06/step-by-step-cucumber-watir-and-ruby.html' title='Step by Step - Cucumber, WatiR and Ruby installation tips'/><author><name>Log4Agile</name><uri>http://www.blogger.com/profile/04640347817726894882</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4003504748921453462.post-3435535372632943880</id><published>2011-06-15T22:55:00.001+01:00</published><updated>2011-06-15T23:10:56.226+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Wiki'/><category scheme='http://www.blogger.com/atom/ns#' term='Web'/><category scheme='http://www.blogger.com/atom/ns#' term='ScrewTurn'/><category scheme='http://www.blogger.com/atom/ns#' term='Open Source'/><category scheme='http://www.blogger.com/atom/ns#' term='Software'/><category scheme='http://www.blogger.com/atom/ns#' term='ASP.Net'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>ScrewTurn Wiki</title><content type='html'>&lt;p&gt;I was looking for a some kind of ASP.Net sample site purely to demo some BDD scenarios at work, but then I wanted to do it on a site which is more complex than the usual ASP.Net sample site made of Customer/Order. &lt;/p&gt;  &lt;p&gt;I found a couple of Wikis, but the one that caught my eye was ScrewTurn Wiki. First things first it is free under the GPLv2 license (for more details on commercial licenses see &lt;a href="http://www.screwturn.eu/commercial.ashx"&gt;Commercial License Help&lt;/a&gt;)&lt;/p&gt;  &lt;p&gt;The installation took less than a few minutes using the Microsoft Web Platform installer, You install the Wiki in one of two modes file system storage mode or SqlServer storage mode (just use SqlExpress). To choose which mode you want to install. See &lt;a href="http://www.screwturn.eu/Help.Installation.ashx"&gt;Installation Help&lt;/a&gt; for more details. Apparently you can go with file storage mode and then switch to the SqlServer data storage mode later (&lt;a href="http://www.screwturn.eu/Help.DataMigration.ashx" target="_blank"&gt;Data Migration&lt;/a&gt;)&lt;/p&gt;  &lt;p&gt;The fact that you can manage the ScrewTurn Wiki using Microsoft WebMatrix is simply brilliant. The ease of use and ability to be able to publish the Wiki is simply useful. You can pretty much configure your hosting details if you wanted to host something on the internet and keep pushing your changes. &lt;/p&gt;  &lt;p&gt;Now for &lt;a href="http://www.screwturn.eu/Customize.MainPage.ashx" target="_blank"&gt;Plugins&lt;/a&gt;, quite a lot of them seem to be available. There are vast number of navigational, text editing and data provider plugins. In addition to this you can customise different portions of the Wiki using your own providers , this seems like one of those things that was given a great deal of thought. See &lt;a href="http://www.screwturn.eu/Dev.MainPage.ashx" target="_blank"&gt;Custom Providers&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;I guess I am very impressed by what the Wiki offers, but looking at the features I am actually wondering if a product which was a Wiki is evolving into a CMS? Not sure, cant say I am bothered either, the only reason I raised that concern is the Wiki as is, is pretty simplistic and this is what appealed to me, building too much into could make it bulky and complex. I am just a developer so I cant give an accurate view of what users of the Wiki would want. On the bright side there are some really new features that are coming and that can be leveraged. V4 CTP offers native Azure support which should be good if you wanted to use Cloud based services I guess. See &lt;a href="http://www.screwturn.eu/STW4.ashx" target="_blank"&gt;Roadmap&lt;/a&gt; for more details&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4003504748921453462-3435535372632943880?l=www.agiledrivendevelopment.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.agiledrivendevelopment.net/feeds/3435535372632943880/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4003504748921453462&amp;postID=3435535372632943880' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/3435535372632943880'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/3435535372632943880'/><link rel='alternate' type='text/html' href='http://www.agiledrivendevelopment.net/2011/06/screwturn-wiki.html' title='ScrewTurn Wiki'/><author><name>Log4Agile</name><uri>http://www.blogger.com/profile/04640347817726894882</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4003504748921453462.post-1291895070445750512</id><published>2011-06-13T11:21:00.001+01:00</published><updated>2011-06-13T11:35:10.189+01:00</updated><title type='text'>DDD eXchange 2011 Podcasts</title><content type='html'>&lt;p align="left"&gt;Attended this conference on Friday (10/06/2011) and was consolidating the links for the podcasts  &lt;p align="left"&gt;&lt;strong&gt;Some of my favourites are&lt;/strong&gt;  &lt;ul&gt; &lt;li&gt; &lt;div align="left"&gt;&lt;b&gt;&lt;/b&gt;· Greg Young on Assert.That(We.Understand) – related to TDD&lt;/div&gt; &lt;li&gt; &lt;div align="left"&gt;· Udi Dahan on Domain Models and Composite Applications&lt;/div&gt; &lt;li&gt; &lt;div align="left"&gt;· Jim Webber on REST and DDD - REST based APIs&lt;/div&gt; &lt;li&gt; &lt;div align="left"&gt;· Matthew Wall on REST &amp;amp; APIs in the Guardian's DDD Processes&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p align="left"&gt;&lt;b&gt;Podcast Links&lt;/b&gt;  &lt;ul&gt; &lt;li&gt; &lt;div align="left"&gt;&lt;a href="http://skillsmatter.com/podcast/design-architecture/dddx-welcome."&gt;Eric Evans on Welcome to DDD eXchange&lt;/a&gt; &lt;/div&gt; &lt;li&gt; &lt;div align="left"&gt;&lt;a href="http://skillsmatter.com/podcast/design-architecture/rest-and-ddd"&gt;Jim Webber on REST and DDD&lt;/a&gt;&lt;/div&gt; &lt;li&gt; &lt;div align="left"&gt;&lt;a href="http://skillsmatter.com/podcast/design-architecture/talk-from-udi-dahan"&gt;Udi Dahan on Domain Models and Composite Applications&lt;/a&gt;&lt;/div&gt; &lt;li&gt; &lt;div align="left"&gt;&lt;a href="http://skillsmatter.com/podcast/design-architecture/talk-by-patrick-fredriksson"&gt;Patrik Fredriksson on DDD in a Functional Programming Language&lt;/a&gt;&lt;/div&gt; &lt;li&gt; &lt;div align="left"&gt;&lt;a href="http://skillsmatter.com/podcast/design-architecture/talk-from-greg-young"&gt;Greg Young on Assert.That(We.Understand)&lt;/a&gt;&lt;/div&gt; &lt;li&gt; &lt;div align="left"&gt;&lt;a href="http://skillsmatter.com/podcast/design-architecture/how-apis-have-changed-our-views-on-the-domain-model-at-the-guardian."&gt;Matthew Wall on REST &amp;amp; APIs in the Guardian's DDD Processes&lt;/a&gt;&lt;/div&gt; &lt;li&gt; &lt;div align="left"&gt;&lt;a href="http://skillsmatter.com/podcast/design-architecture/talk-from-eric-evans"&gt;Eric Evans on Keynote - DDD Strategies for Moving Away from Legacy Systems&lt;/a&gt;&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4003504748921453462-1291895070445750512?l=www.agiledrivendevelopment.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.agiledrivendevelopment.net/feeds/1291895070445750512/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4003504748921453462&amp;postID=1291895070445750512' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/1291895070445750512'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/1291895070445750512'/><link rel='alternate' type='text/html' href='http://www.agiledrivendevelopment.net/2011/06/ddd-exchange-2011-podcasts.html' title='DDD eXchange 2011 Podcasts'/><author><name>Log4Agile</name><uri>http://www.blogger.com/profile/04640347817726894882</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4003504748921453462.post-5340633313115044364</id><published>2010-08-26T23:12:00.001+01:00</published><updated>2010-08-27T23:11:54.731+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='XP'/><category scheme='http://www.blogger.com/atom/ns#' term='Software'/><category scheme='http://www.blogger.com/atom/ns#' term='Scrum'/><category scheme='http://www.blogger.com/atom/ns#' term='Agile'/><title type='text'>The N+1 Iteration syndrome</title><content type='html'>&lt;p&gt;I constantly ask myself if i know what is next at the end of a sprint or iteration and that I should make an effort to know what is coming up next, I observe that just like me the members of the team are only focussing only on the card that there magnet is on in the current iteration. Adapting to a constant flow of user stories and requirement is not easy for any team and is as important as focussing on the stories in the current iteration. We as a team focus on the user stories in the board, but it may be worthwhile asking ourselves how many people in the team are really aware of what is coming up in the next iteration. If members in the team were asked to answer to this question honestly you will find that a vast majority probably don’t have much information or are totally ignorant. I prefer the term N+1 for the next iteration. In most teams I have worked this is a problem that is evident in one form or the other and some common symptoms I find are the ones mentioned below. &lt;/p&gt;  &lt;p&gt;Symptoms &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Analysts find it frustrating that they have to repeatedly read the story out and explain the same story more than a few times. &lt;/li&gt;    &lt;li&gt;Team velocity sways massively and the standard deviation to average velocity is quite high &lt;/li&gt;    &lt;li&gt;Requirements workshops are almost absent and it seems like analysts are in a different time zone on the user requirements on most occasions when compared to the team. &lt;/li&gt;    &lt;li&gt;Team members are not sure about the size of the story and try to come up to a size as close as possible to the rest of the team rather than putting any effort involved in understanding the size of the story. &lt;/li&gt;    &lt;li&gt;Constructive discussions, debate and any implementation concerns are almost absent &lt;/li&gt;    &lt;li&gt;The team seems to easily agree on the size of the story and gets swayed into a conclusion by anyone who can speak the team into a conclusion &lt;/li&gt;    &lt;li&gt;Large stories seem to be finished earlier than they ought to be and some of the smaller stories seem to take more time and some times end up looking like large stories. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;This syndrome manifests itself in different ways and consequences range to varying degrees of severity on the functioning of an agile team. The team should address this situation if they do find these symptoms, the effects of not addressing this problem could result in false velocities, skewed metrics, increase in cost of the project and finally manifests itself in a loss of trust from the users for whom we actually work on the project. I wonder if I am making a big deal out of this, but this may be because I perceive the consequences of this syndrome to grow exponentially into bigger problems and can be quite damaging for the future of the team and the project.&lt;/p&gt;  &lt;p&gt;We can mitigate some of these symptoms, a few ideas that allow you to improve and move in the right direction are below&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Introduce a N+1 sprint section on the left and side of your Kanban or sprint board and line up stories that will flow into the next sprint. &lt;/li&gt;    &lt;li&gt;Encourage analysts who are working on N+1 Q to speak about there analysis during your stand ups, this helps spread awareness of the N+1 iteration on a daily basis. Truth is in an iteration the analyst is probably working 50% of their time on the N+&lt;strike&gt;1&lt;/strike&gt; sprint and the other current sprint. &lt;/li&gt;    &lt;li&gt;Encourage your team members to pair with analysts and discuss and learn what they are working on, if you can allow your developers and QAs to pair for 5% of the iteration on a rotational basis with the analyst. These pairing sessions really helps non technical analysts to learn a few tricks and understand why you would think the story is complex or simple &lt;/li&gt;    &lt;li&gt;Have mini 15 minute sessions every day after the stand up to pick up one story from the N+1 board and discuss with the analyst, testability and implementation details. This will mitigate the loss of requirements workshop they are long and can be boring anyway , small cycles of these sessions will get the team to be constantly involved in requirements.. the term cross functional teams was not coined just for developers and QAs , it did mean all functions in the project. &lt;/li&gt;    &lt;li&gt;Have some ground rules for your planning session,      &lt;ul&gt;       &lt;li&gt;Team comes attend the planning session with an awareness of the stories flowing into the Kanban, &lt;/li&gt;        &lt;li&gt;You really don't want estimating to eat up all your planning time, clearly planning is not only to estimate it is also about discussing priorities and setting goals for your iteration, spend some time planning how you would action retrospectives as well. &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;You will see that the team will at least loose the perplexed “I don't know what you are talking about look “ and the “I cant be bothered” attitude , this could be a good starting point to address the problem. This will allow your team to be more involved in planning as much as they are involved in the progress of the sprints. &lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4003504748921453462-5340633313115044364?l=www.agiledrivendevelopment.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.agiledrivendevelopment.net/feeds/5340633313115044364/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4003504748921453462&amp;postID=5340633313115044364' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/5340633313115044364'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/5340633313115044364'/><link rel='alternate' type='text/html' href='http://www.agiledrivendevelopment.net/2010/08/n1-iteration-syndrome.html' title='The N+1 Iteration syndrome'/><author><name>Log4Agile</name><uri>http://www.blogger.com/profile/04640347817726894882</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4003504748921453462.post-4746279502543777661</id><published>2010-08-23T23:18:00.000+01:00</published><updated>2010-08-26T23:19:06.510+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Practices'/><category scheme='http://www.blogger.com/atom/ns#' term='Cucumber'/><category scheme='http://www.blogger.com/atom/ns#' term='BDD'/><category scheme='http://www.blogger.com/atom/ns#' term='Acceptance Testing'/><category scheme='http://www.blogger.com/atom/ns#' term='Software'/><category scheme='http://www.blogger.com/atom/ns#' term='Agile'/><category scheme='http://www.blogger.com/atom/ns#' term='TDD'/><title type='text'>Authoring and Automating - User Stories</title><content type='html'>&lt;p&gt;In most agile development teams the responsibility of writing user stories falls into the hands of the analyst. The analyst not in all cases may be well versed with the idea of writing stories. This is not because he does not know what to write but sometimes because he does not know the best way to express the story in the chosen story writing platform. This doesn't warrant a developer to pair with an analyst to author a story, In my opinion developers are not welcome to pair with the analyst to author user stories. Allowing this will allow implementation detail to find its way into the stories and sometimes they dictate the users intention. &lt;/p&gt;  &lt;h5&gt;Authoring stories&lt;/h5&gt;  &lt;p&gt;The best person for your analyst to pair with should be your QA, this proves to be the most useful.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;The QA looks at a story early in the life cycle and ensures all aspects of the story are testable. &lt;/li&gt;    &lt;li&gt;The ownership of the story is with the QA and he/she is able to identify any automation concerns of the story.. &lt;/li&gt;    &lt;li&gt;Any scenarios that have not been through in a story due to data related anomalies are identified. &lt;/li&gt;    &lt;li&gt;The QA is involved in this process early on before the iteration in which the story is picked up , this will allow the QA to bring in some valuable information on the size of the story to the planning session. &lt;/li&gt;    &lt;li&gt;Since the QA gets an understanding of the story before a developer is involved his view of the story is as close as possible to the users requirement in the story. This important to make sure the intention of the user is not skewed by the understanding of a developer. &lt;/li&gt;    &lt;li&gt;The QA is able to identify any smoke tests that may be required to be run when a release is deployed to UAT or Live. &lt;/li&gt; &lt;/ul&gt;  &lt;h5&gt;Automating stories&lt;/h5&gt;  &lt;p&gt;In our current project our QA starts automating user stories when he runs out of stories to test. In most cases the QA to dev ratio is 1:2 or 1:3 and so the QA gets bogged down with implementing acceptance criteria so the team has enough stories to dev on. It helps for devs to pair with QAs to automate acceptance tests and my observation has been the following&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;On a normal day we developers are more in sync with writing better code than QA’s, developers can always help in writing better test code. &lt;/li&gt;    &lt;li&gt;When developers implement the acceptance criteria in the form of Given When Then, they actually are implementing the story itself. &lt;/li&gt;    &lt;li&gt;Developers will get an idea of how to implement the story and tests required when they actually develop the story. &lt;/li&gt;    &lt;li&gt;Where the story is looking for new elements on the UI, developers can aid in mocking the UI for the story else automating all the steps of the user story could be a night mare for the QA all on his own. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;PS : My Selfish reason - Developers learn a new language .. I learnt ruby this way :)&lt;/p&gt;  &lt;p&gt;In effect when three different people with different skills are involved in the authoring and automation of the story, this will ensure a lot more analysis happens and more often than not edge cases are discovered ahead of development. Any edge cases which will increase the cost of the story can be identified and a decision made taken if they have any real value in development.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4003504748921453462-4746279502543777661?l=www.agiledrivendevelopment.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.agiledrivendevelopment.net/feeds/4746279502543777661/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4003504748921453462&amp;postID=4746279502543777661' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/4746279502543777661'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/4746279502543777661'/><link rel='alternate' type='text/html' href='http://www.agiledrivendevelopment.net/2010/08/authoring-and-automating-user-stories.html' title='Authoring and Automating - User Stories'/><author><name>Log4Agile</name><uri>http://www.blogger.com/profile/04640347817726894882</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4003504748921453462.post-7173681994101499891</id><published>2010-08-20T21:15:00.001+01:00</published><updated>2010-08-22T13:02:54.398+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Practices'/><category scheme='http://www.blogger.com/atom/ns#' term='XP'/><category scheme='http://www.blogger.com/atom/ns#' term='Scrum'/><category scheme='http://www.blogger.com/atom/ns#' term='Agile'/><category scheme='http://www.blogger.com/atom/ns#' term='TDD'/><title type='text'>Pair Usefully and Code Effectively</title><content type='html'>&lt;p&gt;Pairing is of real value when two developers work with each other in a such a manner that they allow the other person to teach and learn new ways of working. This mutual learning process will ensure that the competency of the team will grow uniformly. In my current job we almost never work alone we always pair. Recent retrospectives have been focussing on how we get the most out of our pairing sessions. Some developers said we don’t swap pairs enough, there were questions about how and when do we determine it is a good time to swap pairs.&lt;/p&gt;  &lt;p&gt;Well there is probably no hard and fast rule on pairing but some of the things we seem to recognise in a team are as follows. &lt;/p&gt;  &lt;p&gt;1. Story Champs - A story owner or champion should be present on the story who will see the story go through the board&lt;/p&gt;  &lt;p&gt;2. Story Progress - Having a story champion will allow you to swap pairs across a story reasonably well without affecting the progress of the story. &lt;/p&gt;  &lt;p&gt;3. Keyboard Policy – More often than not this is a reason for frustration among developers in a pairing session. Use TDD to pair effectively.&lt;/p&gt;  &lt;p&gt;Eg. Pair made of Dev A and Dev B.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;     &lt;div align="left"&gt;Dev A writes test to fail – Red&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div align="left"&gt;Dev B implements code to pass the test – Green&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div align="left"&gt;Dev A refactors the code &lt;/div&gt;   &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Alternate between the devs in this cycle will ensure pairing sessions are not driven by just one dev&lt;/p&gt;  &lt;p&gt;4.Pairing Overdrive - If at any point during a pairing session one of the two seem to be dictating code for more than a few minutes ( I call this overdrive mode). You should really stop pairing and determine if the pairing session is useful and how it can be made useful , the dev who is on overdrive mode should really take the initiative to bring his/her pair up to speed on the story they are working on and discuss any gaps in each others understanding.. get away from the computer go for coffee break.. really helps. &lt;/p&gt;  &lt;p&gt;5. Check-in frequency – When we pair due to reasons beyond our control one of the two dev may have to leave at any time before the other, frequent check-ins will allow you to make sure your CI is effective and also that you can switch machines quickly and effectively. &lt;/p&gt;  &lt;p&gt;6. Computer Policy - if a pair is working on machine and dev who owns the computer has to leave, the other dev should be able to continue working on the story ..In such a situation it helps to leave the computer unlocked till your pair can make a check-in and then pull the changes on his computer and continue work, locking your computer and leaving could really be annoying to some one who really wants to continue work.&lt;/p&gt;  &lt;p&gt;7. Early Birds –If you come in earlier than your pair, instead of just picking up the story and continuing work it helps to look at your CI server and fix any broker builds. If you do work on the story do make sure you explain what has been done and how far you have progressed so your pair gets up to speed, else you end up with Pairing Overdrive.&lt;/p&gt;  &lt;p&gt;8. Privacy Policy – If you are working on your pairs machine and when your pair is not around do not snoop around there mail or respond to IM that they receive even for fun, what seems to be fun may turn out to be an annoyance. Finally there is absolutely no need to get personal during a pairing session, every developer has his own style and strengths it is important to respect that , for all you know they might be really skilled in areas you are not so good yourself.. &lt;/p&gt;  &lt;p&gt;After every stand up it makes sense to discuss who can swap pairs. Infact before a stand up it helps to be in a checked in state if you want to make sure your team can swap pairs every day &lt;/p&gt;  &lt;p&gt;For now this is all.. code carefully and pair usefully&amp;#160; :)&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4003504748921453462-7173681994101499891?l=www.agiledrivendevelopment.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.agiledrivendevelopment.net/feeds/7173681994101499891/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4003504748921453462&amp;postID=7173681994101499891' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/7173681994101499891'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/7173681994101499891'/><link rel='alternate' type='text/html' href='http://www.agiledrivendevelopment.net/2010/08/pairing.html' title='Pair Usefully and Code Effectively'/><author><name>Log4Agile</name><uri>http://www.blogger.com/profile/04640347817726894882</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4003504748921453462.post-5772058381483264735</id><published>2010-08-10T09:21:00.002+01:00</published><updated>2010-08-10T11:15:35.858+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Web'/><category scheme='http://www.blogger.com/atom/ns#' term='Cucumber'/><category scheme='http://www.blogger.com/atom/ns#' term='BDD'/><category scheme='http://www.blogger.com/atom/ns#' term='Acceptance Testing'/><category scheme='http://www.blogger.com/atom/ns#' term='Watir'/><category scheme='http://www.blogger.com/atom/ns#' term='Specflow'/><title type='text'>Acceptance Testing</title><content type='html'>&lt;p&gt;After playing around with Cucumber/ Cuke4Nuke and Specflow.. turns out cucumber is the winner for me.. Cuke4Nuke took me a while to get going and seems considerably slow and is behind cucumber by some distance..  &lt;/p&gt;  &lt;p&gt;Specflow is alright however the idea of using attributes to match my step definitions is what i didn't like.. integration with VS and being able to use the NUnit test runner are clear winners.. the entry barrier to this is pretty much minimal.&lt;/p&gt;  &lt;p&gt;Well as for Cucumber/ Ruby / WATIR, the idea of using RubyMine to write my tests and debug them in the same doesn't make me miss VS integration and debugging.. I don't think i particularly miss writing my tests in different languages.. well i never do so why bother… The choice of gems available for Ruby and dynamic nature of ruby is something that makes the effort rewarding .. Build integration using a Rake runner is easy not much effort either..One other reason is may be because i use this at work .. there is yet one more to be looked at which is the WebDriver API for Selenium 2.0.  &lt;a href="http://google-opensource.blogspot.com/2009/05/introducing-webdriver.html"&gt;http://google-opensource.blogspot.com/2009/05/introducing-webdriver.html&lt;/a&gt; .. &lt;/p&gt;  &lt;p&gt;I took some time to play around with these since I don’t like skimming through the surface ..&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4003504748921453462-5772058381483264735?l=www.agiledrivendevelopment.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.agiledrivendevelopment.net/feeds/5772058381483264735/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4003504748921453462&amp;postID=5772058381483264735' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/5772058381483264735'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/5772058381483264735'/><link rel='alternate' type='text/html' href='http://www.agiledrivendevelopment.net/2010/08/acceptance-tests-tools.html' title='Acceptance Testing'/><author><name>Log4Agile</name><uri>http://www.blogger.com/profile/04640347817726894882</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4003504748921453462.post-9068666333750066227</id><published>2010-04-28T23:44:00.001+01:00</published><updated>2010-04-28T23:45:38.014+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SqLite'/><category scheme='http://www.blogger.com/atom/ns#' term='Database'/><category scheme='http://www.blogger.com/atom/ns#' term='NUnit'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><category scheme='http://www.blogger.com/atom/ns#' term='TDD'/><title type='text'>SqLite Manager plugin for firefox</title><content type='html'>&lt;p&gt;There is a good chance some of you use this or know about this already. However this is kind of new stuff for me.. In my current project we use SqLite&amp;#160; to run our integration tests for the repository tests and the some of the rhino ETL process classes. We use SqLite as a file based database rather than an in memory instance and while i was debugging through the code I hit a point where i wanted to see how the schema was created and the data stored, so i can be sure the foreign keys where stored with the right values &lt;/p&gt;  &lt;p&gt;SqLite Manager is a useful plugin for Firefox 3.6. This is browser based and allows you to work on the file based database just like Sql Server Enterprise Manager allows you to work with SQL 2000. This is a really useful tool when you are writing integration tests with SqLite.&lt;/p&gt;  &lt;p&gt;You can get the plugin at , you may need firefox 3.6 or above&lt;/p&gt;  &lt;p&gt;&lt;a href="https://addons.mozilla.org/en-US/firefox/addon/5817"&gt;https://addons.mozilla.org/en-US/firefox/addon/5817&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4003504748921453462-9068666333750066227?l=www.agiledrivendevelopment.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.agiledrivendevelopment.net/feeds/9068666333750066227/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4003504748921453462&amp;postID=9068666333750066227' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/9068666333750066227'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/9068666333750066227'/><link rel='alternate' type='text/html' href='http://www.agiledrivendevelopment.net/2010/04/sqlite-manager-plugin-for-firefox.html' title='SqLite Manager plugin for firefox'/><author><name>Log4Agile</name><uri>http://www.blogger.com/profile/04640347817726894882</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4003504748921453462.post-3086400404606871739</id><published>2010-04-25T22:48:00.010+01:00</published><updated>2010-04-29T22:29:49.538+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Teamcity'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='NUnit'/><category scheme='http://www.blogger.com/atom/ns#' term='TDD'/><title type='text'>NUnit - Teamcity - TestCaseSource tip</title><content type='html'>&lt;p&gt;If you are using features from NUnit 2.5 or above TestCaseSource attribute may sound familiar. This is a very useful feature in NUnit now which helps us reduce the clutter of repetitive code in our test class. I am sure everyone can see how this can be done on the NUnit website as well , but the point of this post is in relation to a problem I ran into when I used the TestCaseSource attribute. To elaborate on this let me use a simple example of a class which calculates the square of an integer.&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;SquareOfNumbers
&lt;/span&gt;{
&lt;span style="color: blue"&gt;   public static int &lt;/span&gt;Square(&lt;span style="color: blue"&gt;int &lt;/span&gt;x)
{
   &lt;span style="color: blue"&gt;return &lt;/span&gt;x * x;
}
}&lt;/pre&gt;

&lt;p&gt;When i first started writing tests i used the TestCaseSource attribute , so my test class looked like the one below &lt;/p&gt;

&lt;p&gt;&lt;span style="font-size: 85%"&gt;&lt;span style="font-family: courier new"&gt;&lt;span style="white-space: pre" class="Apple-style-span"&gt;[&lt;span style="color: #2b91af"&gt;&lt;span class="Apple-style-span"&gt;TestFixture&lt;/span&gt;&lt;/span&gt;]&lt;/span&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;div&gt;
  &lt;div&gt;
    &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;SquareOfNumberFixture
&lt;/span&gt;{
&lt;span style="color: blue"&gt;private static readonly &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;int&lt;/span&gt;, &lt;span style="color: blue"&gt;int&lt;/span&gt;&amp;gt; _testData = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;int&lt;/span&gt;, &lt;span style="color: blue"&gt;int&lt;/span&gt;&amp;gt;();

&lt;span style="color: blue"&gt;public static &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;int&lt;/span&gt;, &lt;span style="color: blue"&gt;int&lt;/span&gt;&amp;gt; TestData
{
   &lt;span style="color: blue"&gt;get
   &lt;/span&gt;{
       _testData.Add(2, 4);
       _testData.Add(0, 0);
       &lt;span style="color: blue"&gt;return &lt;/span&gt;_testData;
   }
}

[&lt;span style="color: #2b91af"&gt;Test&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;TestCaseSource&lt;/span&gt;(&lt;span style="color: #a31515"&gt;&amp;quot;TestData&amp;quot;&lt;/span&gt;)]
&lt;span style="color: blue"&gt;public void &lt;/span&gt;Test(&lt;span style="color: #2b91af"&gt;KeyValuePair&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;int&lt;/span&gt;, &lt;span style="color: blue"&gt;int&lt;/span&gt;&amp;gt; keyValuePair)
{
   &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.That(&lt;span style="color: #2b91af"&gt;SquareOfNumbers&lt;/span&gt;.Square(keyValuePair.Key ), &lt;span style="color: #2b91af"&gt;Is&lt;/span&gt;.EqualTo(keyValuePair.Value));
}
}&lt;/pre&gt;
  &lt;/div&gt;
  &lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

  &lt;p&gt;These tests run successfully, but when run as part of my teamcity build there is no detail about what the tests where as in there was no reference to the name of my test method. I did spend sometime trying to fix this and found a couple of issues.&lt;/p&gt;

  &lt;p&gt;1. Team city was not using the same nunit version that I was using to write tests, so the plugin had to be updated on team city, this way i made sure the build uses the same nunit framework as my source code does &lt;/p&gt;

  &lt;p&gt;2. I changed my tests to use TestCaseData class in conjunction with the TestCaseSource attribute, this allowed me to specify a name for each test scenario , so after refactoring the test class , I can now see the test names on the nunit test report generated by Team city, the code for the new test class is shown below&lt;/p&gt;

  &lt;p&gt;In addition to fixing the problem , TestCaseData class made the test code more readable.&lt;/p&gt;
&lt;/div&gt;

&lt;pre class="code"&gt;[&lt;span style="color: #2b91af"&gt;TestFixture&lt;/span&gt;]
&lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;SquareOfNumberFixture
&lt;/span&gt;{
  &lt;span style="color: blue"&gt;public static &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IEnumerable &lt;/span&gt;TestData
  {
      &lt;span style="color: blue"&gt;get
      &lt;/span&gt;{
          &lt;span style="color: #2b91af"&gt;TestCaseData &lt;/span&gt;squareOfZeroTest = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;TestCaseData&lt;/span&gt;(0).Returns(0);
          squareOfZeroTest.SetName(&lt;span style="color: #a31515"&gt;&amp;quot;SquareOfZeroReturnsZero&amp;quot;&lt;/span&gt;);
          &lt;span style="color: blue"&gt;yield return &lt;/span&gt;squareOfZeroTest;

          &lt;span style="color: #2b91af"&gt;TestCaseData &lt;/span&gt;squareOfIntegerTest = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;TestCaseData&lt;/span&gt;(2).Returns(4);
          squareOfIntegerTest.SetName(&lt;span style="color: #a31515"&gt;&amp;quot;SquareOfTwoReturnsFour&amp;quot;&lt;/span&gt;);
          &lt;span style="color: blue"&gt;yield return &lt;/span&gt;squareOfIntegerTest;
      }
  }

  [&lt;span style="color: #2b91af"&gt;Test&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;TestCaseSource&lt;/span&gt;(&lt;span style="color: #a31515"&gt;&amp;quot;TestData&amp;quot;&lt;/span&gt;)]
  &lt;span style="color: blue"&gt;public int &lt;/span&gt;TestSquareOfNumbers(&lt;span style="color: blue"&gt;int &lt;/span&gt;x)
  {
      &lt;span style="color: blue"&gt;return &lt;/span&gt;&lt;span style="color: #2b91af"&gt;SquareOfNumbers&lt;/span&gt;.Square(x);
  }
}&lt;/pre&gt;

&lt;p&gt;&lt;/p&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;On second thoughts further refactoring the class makes it more readable if i had done the following…&lt;/p&gt;

&lt;p&gt;[&lt;span style="color: #2b91af"&gt;TestFixture&lt;/span&gt;]&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;SquareOfNumberFixtureNew
&lt;/span&gt;{
  [&lt;span style="color: #2b91af"&gt;TestCase&lt;/span&gt;(0, Description = &lt;span style="color: #a31515"&gt;&amp;quot;SquareOfZero&amp;quot;&lt;/span&gt;, Result = 0)]
  [&lt;span style="color: #2b91af"&gt;TestCase&lt;/span&gt;(2, Description = &lt;span style="color: #a31515"&gt;&amp;quot;SquareOfTwo&amp;quot;&lt;/span&gt;, Result = 4)]
  [&lt;span style="color: #2b91af"&gt;Test&lt;/span&gt;]
  &lt;span style="color: blue"&gt;public int &lt;/span&gt;TestSquareOfNumbers(&lt;span style="color: blue"&gt;int &lt;/span&gt;x)
  {
           &lt;span style="color: blue"&gt;return &lt;/span&gt;&lt;span style="color: #2b91af"&gt;SquareOfNumbers&lt;/span&gt;.Square(x);
  }
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4003504748921453462-3086400404606871739?l=www.agiledrivendevelopment.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.agiledrivendevelopment.net/feeds/3086400404606871739/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4003504748921453462&amp;postID=3086400404606871739' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/3086400404606871739'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/3086400404606871739'/><link rel='alternate' type='text/html' href='http://www.agiledrivendevelopment.net/2010/04/nunit-teamcity-testcasesource.html' title='NUnit - Teamcity - TestCaseSource tip'/><author><name>Log4Agile</name><uri>http://www.blogger.com/profile/04640347817726894882</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4003504748921453462.post-291214962085047557</id><published>2010-04-22T01:38:00.005+01:00</published><updated>2010-04-22T09:02:49.133+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Cucumber'/><category scheme='http://www.blogger.com/atom/ns#' term='BDD'/><category scheme='http://www.blogger.com/atom/ns#' term='Watin'/><category scheme='http://www.blogger.com/atom/ns#' term='Acceptance Testing'/><category scheme='http://www.blogger.com/atom/ns#' term='Agile'/><category scheme='http://www.blogger.com/atom/ns#' term='Watir'/><category scheme='http://www.blogger.com/atom/ns#' term='Specflow'/><category scheme='http://www.blogger.com/atom/ns#' term='TDD'/><title type='text'>Acceptance Testing – Cucumber? Specflow? Cuke4Nuke</title><content type='html'>&lt;p&gt;I have been pretty much dormant on this blog due to my part time MBA coupled with a some tight deadlines at work. And to get me back into the blog bandwagon I just thought I will do this small pet project of mine outside work for which I have been exploring the acceptance testing tool to use infact functional test tool which will allow me to translate my acceptance criteria on stories to tests from plain english. &lt;/p&gt;&lt;p&gt;I found something about Specflow on a few blogs,it is a set of libraries to write specifications using &lt;a href="http://blog.dynamicprogrammer.com/ct.ashx?id=d0a61fd3-2800-4390-b3e2-82121ab202bd&amp;amp;url=http%3a%2f%2fwiki.github.com%2faslakhellesoy%2fcucumber%2fgherkin"&gt;Gherkin&lt;/a&gt;. You can check the &lt;a href="http://blog.dynamicprogrammer.com/ct.ashx?id=d0a61fd3-2800-4390-b3e2-82121ab202bd&amp;amp;url=http%3a%2f%2fwww.specflow.org%2fspecflow%2fscreencast.aspx"&gt;screencast here&lt;/a&gt; or read &lt;a href="http://blog.dynamicprogrammer.com/ct.ashx?id=d0a61fd3-2800-4390-b3e2-82121ab202bd&amp;amp;url=http%3a%2f%2fryanlanciaux.com%2fryanlanciaux%2fpost%2fGherkin-style-BDD-testing-in-NET.aspx"&gt;this post&lt;/a&gt; from Ryan Lanciaux. SpecFlow can use either NUnit or MsTest as the engine. You could use specflow and drive WATIN.&lt;/p&gt;&lt;p&gt;Being a .Net developer I am quite inclined to use Specflow and Watin after having had a look at it mainly because i dont need to learn a new language and i can use my c# knowledge to write tests, However previous experience with WATIN a couple of years was not great and it always seemed be behind some of the things you could do with WATIR, hopefully this has changed now, In my current job we use Cucumber + Watir to write acceptance tests and we use Ruby, Although I found it a bit steep on the learning curve initially and mainly because i havent worked in anything but .Net. Now after a couple of weeks into it I am beginning to think if this is may be the right choice, for e.g I am not even a novice in Ruby but RubyMine from JetBrains makes it easy when you are a new bee. &lt;/p&gt;&lt;p&gt;I still didnt want to give up exploring a .Net + cucumber combination and my search led me to this article by Richard Lawrence in his blog which compares the pros and cons of Watir and Watin.. &lt;a href="http://www.richardlawrence.info/2009/01/19/web-testing-for-net-teams-watin-or-watir/"&gt;go to&lt;/a&gt; . Interestingly Richard and a group of other people started driving this project called &lt;strong&gt;Cuke4Nuke &lt;/strong&gt;sometime ago now which should allow us to write tests in C# for cucumber, That sounds great to me, because I am not looking at any advanced usage of cucumber, i guess my needs are pretty basic for now, I have not used it yet but all i can say at the moment is having looked at the screen cast and the &lt;a href="http://www.richardlawrence.info/2009/09/19/cuke4nuke-cucumber-for-net-teams/"&gt;background&lt;/a&gt; the creators of the project have given it quite a bit of thought on performance (if you read the blog you will find that they did explore using Iron Python over WATIN which was horribly slow).&lt;/p&gt;&lt;p&gt;A couple of months ago they released 0.3 which supports almost everything you can do with &lt;a href="http://cukes.info/"&gt;Cucumber&lt;/a&gt; in Ruby or Java, making C# a first class language for Cucumber. (The only missing features are small things like tags on Before and After hooks and a richer Table object.)&lt;/p&gt;&lt;p&gt;To install and have a play with this go to the Cuke4Nuke Wiki at &lt;a href="http://wiki.github.com/richardlawrence/Cuke4Nuke/"&gt;http://wiki.github.com/richardlawrence/Cuke4Nuke/&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Screen Cast on Cuke4Nuke and WATIN&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.richardlawrence.info/2009/12/03/screencast-testing-web-applications-in-net-with-cuke4nuke-and-watin/"&gt;http://www.richardlawrence.info/2009/12/03/screencast-testing-web-applications-in-net-with-cuke4nuke-and-watin/&lt;/a&gt;&lt;/p&gt;&lt;p&gt;I am going to give this a go for a spike on my new project so lets see how this goes :). &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4003504748921453462-291214962085047557?l=www.agiledrivendevelopment.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.agiledrivendevelopment.net/feeds/291214962085047557/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4003504748921453462&amp;postID=291214962085047557' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/291214962085047557'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/291214962085047557'/><link rel='alternate' type='text/html' href='http://www.agiledrivendevelopment.net/2010/04/acceptance-testing-cucumber-specflow.html' title='Acceptance Testing – Cucumber? Specflow? Cuke4Nuke'/><author><name>Log4Agile</name><uri>http://www.blogger.com/profile/04640347817726894882</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4003504748921453462.post-7082199719807762615</id><published>2008-09-19T11:56:00.001+01:00</published><updated>2008-09-19T11:58:14.428+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Build'/><category scheme='http://www.blogger.com/atom/ns#' term='Nant'/><title type='text'>Nant Task for Sandcastle</title><content type='html'>&lt;p&gt;I have been thinking of writing a Nant task for Sandcastle for quite some time so I decided to knock something up . I have been fairly busy at work and havent been able to spend time on this. As i find some time on the train I just finished this piece of code.&lt;/p&gt;  &lt;p&gt;I am quite a fan of Nant and the Nant contrib project has a task for NDoc which kind of inspired me to do one for Sandcastle. Sandcastle supports the new frameworks in .Net quite well and most people who were using NDoc would have migrated to Sandcastle due to its capabilities for build purposes.&lt;/p&gt;  &lt;p&gt;This task is intended to allow users who do not want to use sandcastle command line builder in there nant scripts as an external process. The logging of this task and the sandcastle output is also streamed into the nant log. &lt;/p&gt;  &lt;p&gt;I have based my task schema on the bare minimal that will require direct configuration in nant. In any case you should be able to do all the configuration in the sandcastle project. What’s shown below is purely a because i am a developer and I need these features and so i think everyone is going to be happy with it :). ' &lt;style type="text/css"&gt;


.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;/p&gt;  &lt;p&gt;The following readme is placed in a text file along side the installer zip file.&lt;/p&gt;  &lt;p&gt;The Sandcastle for task is built using the following components    &lt;br /&gt;Nant 0.86     &lt;br /&gt;Sandcastle Help File Builder     &lt;br /&gt;Sandcastle UI Builder &lt;/p&gt;  &lt;p&gt;The core components required by the task are installed by the installer. &lt;/p&gt;  &lt;p&gt;The installer allows you to install the task into a folder that you choose but does not check to see if Nant is installed in the same directory    &lt;br /&gt;Generally C:\Program Files\Nant\bin     &lt;br /&gt;Installing the task in the same folder as Nant is the only scenario that has been tested. &lt;/p&gt;  &lt;p&gt;The path of nant should be added to the path variable as instructed in the Nant installation instructions &lt;/p&gt;  &lt;p&gt;In addition to installing the task the following configuration for the Nant.exe.config file needs to be added. &lt;/p&gt;  &lt;p&gt;Under the elements    &lt;br /&gt;&amp;lt;configuration&amp;gt;     &lt;br /&gt;...&amp;lt;nant&amp;gt;     &lt;br /&gt;......&amp;lt;frameworks&amp;gt;     &lt;br /&gt;...........&amp;lt;platform&amp;gt;     &lt;br /&gt;................&amp;lt;task-assemblies&amp;gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;!-- Nant sandcastle task--&amp;gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;include name=&amp;quot;NAnt.Contrib.Tasks.Sandcastle.dll&amp;quot;/&amp;gt;     &lt;br /&gt;If you wish to add the Sandcastle task into another folder, the Nant probing paths need to be set to look at this folder. It is not recommended however &lt;/p&gt;  &lt;p&gt;Source code is also provided and feel free to customise it or edit it , The source code is present at Install folder\sandcastle task\Src&lt;/p&gt;  &lt;p&gt;I have tested this on my system by installing sandcastle, nant and this task and it works fine. Obviously i am saying “Works on my machine”, if you see any problems using it please let me know about it.&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;The Sandcastle task schema for the Nant script should be as below, project and output are the only two required attributes,&lt;/p&gt;  &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;sandcastle&lt;/span&gt; 
    &lt;span style="color: #ff0000"&gt;project&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;${Sandcastle project file path}&amp;quot;&lt;/span&gt; 
    &lt;span style="color: #ff0000"&gt;output&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;Output location for Sandcastle files&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;

    &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;showMissing&lt;/span&gt; 
        &lt;span style="color: #ff0000"&gt;remarks&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;false&amp;quot;&lt;/span&gt; 
        &lt;span style="color: #ff0000"&gt;params&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;false&amp;quot;&lt;/span&gt; 
        &lt;span style="color: #ff0000"&gt;returns&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;false&amp;quot;&lt;/span&gt; 
        &lt;span style="color: #ff0000"&gt;values&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;false&amp;quot;&lt;/span&gt; 
        &lt;span style="color: #ff0000"&gt;namespaces&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;false&amp;quot;&lt;/span&gt; 
        &lt;span style="color: #ff0000"&gt;summaries&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;false&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;showMissing&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
    
    &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;document&lt;/span&gt; 
        &lt;span style="color: #ff0000"&gt;internals&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;false&amp;quot;&lt;/span&gt; 
        &lt;span style="color: #ff0000"&gt;privates&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;false&amp;quot;&lt;/span&gt; 
        &lt;span style="color: #ff0000"&gt;protected&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;quot;=&amp;quot;&lt;/span&gt;&lt;span style="color: #ff0000"&gt;false&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;quot; 
        attributes=&amp;quot;&lt;/span&gt;&lt;span style="color: #ff0000"&gt;false&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;quot;
        copyrightText=&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;quot; 
        feedbackemail=&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;quot; 
        footer=&amp;quot;&lt;/span&gt;&amp;quot;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;document&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;sandcastle&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;e.g Nant build file &lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;?&lt;/span&gt;&lt;span class="html"&gt;xml&lt;/span&gt; &lt;span class="attr"&gt;version&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;1.0&amp;quot;&lt;/span&gt;?&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;project&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Hello World&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;default&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;build&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;property&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;projfile&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;value&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;C:\Documentation.shfb&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
     &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;target&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;build&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;sandcastle&lt;/span&gt; &lt;span class="attr"&gt;project&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;${projfile}&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;output&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;C:\Documentation\Help&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;document&lt;/span&gt; &lt;span class="attr"&gt;copyrightText&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Copyright@ TSQLDOTNET Limited&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;feedbackemail&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;srinivas.s@tsqldotnet.com&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
 &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;sandcastle&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;target&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
 &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;project&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;Link: &lt;a href="http://cid-2cd165f70c749840.skydrive.live.com/self.aspx/Public/Nant/Nant%20Sandcaste%20Release.zip" target="_blank"&gt;&lt;strong&gt;Nant Sandcastle Installer&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The download consists of the prerequisites hence it is bulky at 40MB, The prerequistes include Sandcastle installer , Win 3.1 installer and DotnetFx&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4003504748921453462-7082199719807762615?l=www.agiledrivendevelopment.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.agiledrivendevelopment.net/feeds/7082199719807762615/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4003504748921453462&amp;postID=7082199719807762615' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/7082199719807762615'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/7082199719807762615'/><link rel='alternate' type='text/html' href='http://www.agiledrivendevelopment.net/2008/09/nant-task-for-sandcastle.html' title='Nant Task for Sandcastle'/><author><name>Log4Agile</name><uri>http://www.blogger.com/profile/04640347817726894882</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4003504748921453462.post-2243295756265149627</id><published>2008-09-02T22:49:00.001+01:00</published><updated>2008-09-02T22:49:05.715+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Web'/><category scheme='http://www.blogger.com/atom/ns#' term='Browser'/><title type='text'>Google Chrome</title><content type='html'>&lt;p&gt;Now as is all over the news i went about downloading the browser to get a feel of it. The download of the click once installer was about 474 KB so how big is that :) really neat start, then the download of the installer and install takes about 1 minute (4 MB line) and in another minute it imports all settings from IE. Now that was really impressive , two and half minutes all set and up and running.&lt;/p&gt;  &lt;p&gt;Features that clearly stand out are the Search history, Dynamic Tabs and the simplicity of book marking pages, there is more but these make be happy already :).&lt;/p&gt;  &lt;p&gt;A useful thing is the Search your history box, I have wished for something like this for ages and its nice to see this feature. Hope Google does this for favourites as well.. I having accumulating favourites for the last seven years and i some times wish i could search through surely useful to me :)&lt;/p&gt;  &lt;p&gt;The UI is definitely better than the heavy IE7, tabs are not new in a browser these days just checkout the dynamic tabs feature in Google Chrome, it is definitely cool , drag the tab out and see how it works&lt;/p&gt;  &lt;p&gt;Bookmarking is easier and the download feature is different to other browsers. &lt;/p&gt;  &lt;p&gt;Seems like Google has just started , I am already thinking of using this browser , but i am not sure about any bottle necks .. gotta wait and see &lt;/p&gt;  &lt;p&gt;I am quite happy with what the beta offers,&amp;#160; if Google manages to hold off IE , I bet we could see this being used more widely..&lt;/p&gt;  &lt;p&gt;If you want to download go to &lt;a href="http://tools.google.com/chrome/?hl=en-GB"&gt;http://tools.google.com/chrome/?hl=en-GB&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4003504748921453462-2243295756265149627?l=www.agiledrivendevelopment.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.agiledrivendevelopment.net/feeds/2243295756265149627/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4003504748921453462&amp;postID=2243295756265149627' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/2243295756265149627'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/2243295756265149627'/><link rel='alternate' type='text/html' href='http://www.agiledrivendevelopment.net/2008/09/google-chrome.html' title='Google Chrome'/><author><name>Log4Agile</name><uri>http://www.blogger.com/profile/04640347817726894882</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4003504748921453462.post-4267993452952113142</id><published>2008-08-13T13:27:00.001+01:00</published><updated>2008-08-13T13:28:59.123+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='T-SQL'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>Determine a Leap Year?</title><content type='html'>&lt;p&gt;Armando Prato Armando Prato had written a SQL tip on how to determine a leap year the trick used is pretty neat, His example is in TSQL as below , but i guess we could use the idea in any language &lt;/p&gt;  &lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; background-color: #f4f4f4"&gt;   &lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;     &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;create&lt;/span&gt; &lt;span style="color: #0000ff"&gt;function&lt;/span&gt; dbo.fn_IsLeapYear&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   2:&lt;/span&gt;  (@&lt;span style="color: #0000ff"&gt;year&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt;)&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   3:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;returns&lt;/span&gt; &lt;span style="color: #0000ff"&gt;bit&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   4:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;as&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   5:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;begin&lt;/span&gt;    &lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   6:&lt;/span&gt;    &lt;span style="color: #0000ff"&gt;return&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   7:&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;select&lt;/span&gt; &lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   8:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;case&lt;/span&gt; datepart(mm, dateadd(dd, 1, &lt;span style="color: #0000ff"&gt;cast&lt;/span&gt;((&lt;span style="color: #0000ff"&gt;cast&lt;/span&gt;(@&lt;span style="color: #0000ff"&gt;year&lt;/span&gt; &lt;span style="color: #0000ff"&gt;as&lt;/span&gt; &lt;span style="color: #0000ff"&gt;varchar&lt;/span&gt;(4)) + &lt;span style="color: #006080"&gt;'0228'&lt;/span&gt;) &lt;span style="color: #0000ff"&gt;as&lt;/span&gt; datetime)))     &lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   9:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;when&lt;/span&gt; 2 &lt;span style="color: #0000ff"&gt;then&lt;/span&gt; 1     &lt;span style="color: #0000ff"&gt;else&lt;/span&gt; 0     &lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  10:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;end&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  11:&lt;/span&gt; )&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  12:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;end&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  13:&lt;/span&gt; go&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;I like the idea of appending 0228 to the year and finding out if it is a leap year, The function takes in the year, appends '0228' to it (for February 28th) and adds a day. If the month of the next day is a 2, then we're still in February so it must be a leap year!&amp;#160; If not, it is not a leap year. &lt;/p&gt;

&lt;p&gt;In C# this could be something like , I just thought its worth mentioning this on the blog for my record at the least&lt;/p&gt;

&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; background-color: #f4f4f4"&gt;
  &lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;
    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; isLeapYear = ((&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; DateTime(&amp;lt;&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; year &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;&amp;gt;, 02, 28)).AddDays(1).Date.Month.ToString() == &lt;span style="color: #006080"&gt;&amp;quot;2&amp;quot;&lt;/span&gt;)&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4003504748921453462-4267993452952113142?l=www.agiledrivendevelopment.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.agiledrivendevelopment.net/feeds/4267993452952113142/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4003504748921453462&amp;postID=4267993452952113142' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/4267993452952113142'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/4267993452952113142'/><link rel='alternate' type='text/html' href='http://www.agiledrivendevelopment.net/2008/08/determine-leap-year.html' title='Determine a Leap Year?'/><author><name>Log4Agile</name><uri>http://www.blogger.com/profile/04640347817726894882</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4003504748921453462.post-5905057691199032117</id><published>2008-08-08T23:40:00.001+01:00</published><updated>2008-08-08T23:40:20.575+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Database'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server 2008 - Katmai'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server'/><title type='text'>Tracking v/s Capturing changes</title><content type='html'>&lt;p&gt;Change Data Capture has by far been my favourite feature everytime i think about SQL Server 2008. The really neat bit is something I missed during my learning process, There are two flavours to capturing changes, the change itself and the data that has changed, this is what distinguishes Change Data Tracking and Change Data Capture in SQL Server 2008&lt;/p&gt;  &lt;p&gt;Change data capture provides historical change information for a user table by capturing both the fact that DML changes were made and the actual data that was changed. Changes are captured by using an asynchronous process that reads the transaction log and has a low impact on the system.. When you want to stage data in logical blocks such as a website publishing engine, or a clearing system this feature could prove very useful. This is mainly because of the granularity of the changes that are captured and the nature in which they are stored providing no coupling to the object whose changes are captured.&lt;/p&gt;  &lt;p&gt;Change tracking on the other hand captures the rows in a table that changed, but does not capture the data itself. This allows applications to determine rows that have changed only with the latest row data being available in the user tables. Therefore, change tracking is more limited in the historical questions it can answer compared to change data capture. However, for applications that do not require historical information, there is far less storage overhead because of the changed data not being captured. It is the data captured which causes the database to grow. A synchronous tracking mechanism is used to track the changes and has been designed to have minimal overhead to the DML operations. &lt;/p&gt;  &lt;p&gt;Either of these features can be used to synchronize applications or there database engines. Synchronization can be implemented in applications in two directions, one-way and two way. &lt;/p&gt;  &lt;p&gt;In One-way synchronization applications, such as a client or mid-tier caching application, can be built that use change tracking. e.g, a caching application requires data to be stored in the database and to be cached in other data stores. In this scenario the application must be able to keep the cache up-to-date with any changes that have been made to the database. There are no changes to pass back to the Database Engine. &lt;/p&gt;  &lt;p&gt;In two way synchronization, the data in the Database Engine is synchronized with one or more data stores. The data in those stores can be updated and the changes must be synchronized back to the database. A good example of two-way synchronization is an application which is occasionally connected such as a mobile application. In this type of application, a client application queries and updates a local store. When a connection is available between a client and server, the application will synchronize with a server, and changed data flows in both directions. In two-way synchronization applications must be able to detect conflicts. A conflict would occur if the same data was changed in both data stores in the time between synchronization's. With the ability to detect conflicts, an application can make sure that changes are not lost. &lt;/p&gt;  &lt;p&gt;So my misinterpretation that change capture and change tracking meant the same proved to be wrong. This really useful feature could be put to use effectively in a scalable manner by choosing the right flavour of change capture which is based on the needs or nature of your application. There is no denial that applications on SQL Server versions prior to 2005 will need a major overhaul if there is an existing mechanism in place, that said it is best not to underestimate the implementation of Change Data Capture for a existing application. However new applications could base there designs around this feature and seek to benefit rapidly. &lt;/p&gt;  &lt;p&gt;On this note a quick note to people who use Log shipping, The feature is useful when batch processing of transactions is to be done on a regular frequency, however it is still limited in not being able to identify each transaction individually, there is no denial however that is the best choice for Disaster Recovery options.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4003504748921453462-5905057691199032117?l=www.agiledrivendevelopment.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.agiledrivendevelopment.net/feeds/5905057691199032117/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4003504748921453462&amp;postID=5905057691199032117' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/5905057691199032117'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/5905057691199032117'/><link rel='alternate' type='text/html' href='http://www.agiledrivendevelopment.net/2008/08/tracking-vs-capturing-changes.html' title='Tracking v/s Capturing changes'/><author><name>Log4Agile</name><uri>http://www.blogger.com/profile/04640347817726894882</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4003504748921453462.post-529038509785538146</id><published>2008-07-28T18:06:00.001+01:00</published><updated>2008-07-28T18:06:05.497+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Architecture'/><category scheme='http://www.blogger.com/atom/ns#' term='Software'/><category scheme='http://www.blogger.com/atom/ns#' term='Database'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>Concurrency Control in .Net Data Tiers</title><content type='html'>&lt;p&gt;Most of our data in applications is stored in relational databases, although there are other ways of storing data I guess about 75% of applications use RDBMS. While using these databases we write .Net code which functions correctly but may incorrectly write, read or handle data in the run time. e.g. I have found a common case where developers tend not to use some of the features built into the RDBMS system under the covers, and concentrate so much on getting the application tier right, that they fall into pitfalls that arise out of data handling , One such issue is concurrency of data, It is one of those things developers don’t look at when they hit a data handling issue. a consequence is a lack of transaction capabilities , sometimes they don’t analyse that the root cause could be data handling. Agree or deny I at the least cannot think of applications used for business not to have transactions. More often than not business processes in a application translate into a transaction block or unit. &lt;/p&gt;  &lt;p&gt;Concurrency is one such issue which can be controlled and exercised. It can be in an optimistic or pessimistic mechanism, whatever be the mode exercised it is important to understand the concept and how it can be exercised.&lt;/p&gt;  &lt;p&gt;Optimistic concurrency lets the last update succeed and can make data viewed by the end user dirty, if a update happened since data was displayed to the user. It is the applications responsibility to determine stale data and then decide to perform an update based on the decision it takes. Optimistic concurrency is used extensively in .NET to address the needs of mobile    &lt;br /&gt;and disconnected applications, where locking data rows for prolonged periods of time would be infeasible. Also, maintaining record locks requires a persistent connection to the database server, which is not possible in disconnected applications&lt;/p&gt;  &lt;p&gt;In the pessimistic scenario, read locks are obtained by the consumer of the data and any updates to the same data are prevented, Pessimistic concurrency requires a persistent connection to the database and is not a scalable option when users are interacting with data, because records might be    &lt;br /&gt;locked for relatively large periods of time.&lt;/p&gt;  &lt;p&gt;These are the mechanisms you adopt. To implement this in a data tier of a .Net application developers use transactions &lt;/p&gt;  &lt;p&gt;Most of today’s applications need to support transactions for maintaining the integrity of a system’s data. There are several approaches to transaction management; however, each approach fits into one of two basic programming models:&lt;/p&gt;  &lt;p&gt;Manual transactions. You write code that uses the transaction support features of either ADO.NET or Transact-SQL directly in your component code or stored procedures, respectively.&lt;/p&gt;  &lt;p&gt;Automatic transactions. Using Enterprise Services (COM+), you add declarative&amp;#160; attributes to your .NET classes to specify the transactional requirements of your objects at run time. You can use this model to easily configure multiple components to perform work within the same transaction.&lt;/p&gt;  &lt;p&gt;To decide if u want to use transactions in SQL code, ADO.Net or Automatic transaction I found a simple decision tree which allows you to make a decision on which method to use to implement transactions, of course you make the decision if you need to use transactions in .Net&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/sritsqldotnet/SI38eaA5qRI/AAAAAAAAAFI/yI58xiocCJ8/s1600-h/image2.png"&gt;&lt;img title="image" style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="327" alt="image" src="http://lh3.ggpht.com/sritsqldotnet/SI38fCKBnDI/AAAAAAAAAFM/gUJRzpSSHUo/image_thumb1.png?imgmax=800" width="459" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4003504748921453462-529038509785538146?l=www.agiledrivendevelopment.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.agiledrivendevelopment.net/feeds/529038509785538146/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4003504748921453462&amp;postID=529038509785538146' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/529038509785538146'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/529038509785538146'/><link rel='alternate' type='text/html' href='http://www.agiledrivendevelopment.net/2008/07/concurrency-control-in-net-data-tiers.html' title='Concurrency Control in .Net Data Tiers'/><author><name>Log4Agile</name><uri>http://www.blogger.com/profile/04640347817726894882</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/sritsqldotnet/SI38fCKBnDI/AAAAAAAAAFM/gUJRzpSSHUo/s72-c/image_thumb1.png?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4003504748921453462.post-8982717749486250194</id><published>2008-07-25T21:35:00.001+01:00</published><updated>2008-07-25T21:35:51.911+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Astoria'/><category scheme='http://www.blogger.com/atom/ns#' term='IIS'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server'/><title type='text'>Astoria Data Services – IIS + SQL Server ?</title><content type='html'>&lt;p&gt;&lt;/p&gt;  &lt;p&gt;A few months ago I had the opportunity to preview Astoria Data Services in a NextGen User Group meeting and I was thinking I have seen this before, but i failed to recollect where at that time, read the following you will see why i am pointing this out. At the time of preview MS promised to add security to Astoria, Basically all I could see was SQL queries on the browser URL / request URL&lt;/p&gt;  &lt;p&gt;When you install IIS on a machine , in management console of windows you have an option to configure SQL XML support for IIS. Do this and then configure a Virtual directory in IIS, which offers quite a list of decent security settings. Configure these and browse to the URL with a SQL query in the URL and see what happens, there ain’t much difference? &lt;/p&gt;  &lt;p&gt;I am not cynical but i want to point out this is not new, we will however have to wait and see what additional features are offered by Astoria before we can comment&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4003504748921453462-8982717749486250194?l=www.agiledrivendevelopment.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.agiledrivendevelopment.net/feeds/8982717749486250194/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4003504748921453462&amp;postID=8982717749486250194' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/8982717749486250194'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/8982717749486250194'/><link rel='alternate' type='text/html' href='http://www.agiledrivendevelopment.net/2008/07/astoria-data-services-iis-sql-server.html' title='Astoria Data Services – IIS + SQL Server ?'/><author><name>Log4Agile</name><uri>http://www.blogger.com/profile/04640347817726894882</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4003504748921453462.post-4969924211686957270</id><published>2008-07-23T19:21:00.001+01:00</published><updated>2008-07-23T19:24:23.943+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Database'/><category scheme='http://www.blogger.com/atom/ns#' term='ASP.Net'/><category scheme='http://www.blogger.com/atom/ns#' term='Oracle'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>Oracle 9i and 11g Data Access Components for .Net</title><content type='html'>&lt;p&gt;I am currently working with SQL Servers and Oracle servers and products communicate with both databases, In my previous job where we used only SQL Server everything was easy as it was native to Microsoft’s products, however the world of .Net with Oracle has its pain points. A particular scenario i came across today was having a web server with Oracle 9i Data Access Components and 11g Data Access Components on the same server and getting them to work for two different ASP.Net sites. I initially installed the ODAC components without the client thinking it was enough for the ASP.Net site to work, however as it turns out there is more to it than i thought it would be &lt;/p&gt;  &lt;p&gt;When i started Oracle 9i client components where already installed on the server and the Products using 9i components where working fine. However the moment I installed the 11g Data Access Components the Products using 9i stopped working throwing exceptions and neither where products using 11g components working. So i had to uninstall 11g Data Access components and leave Product A working. So sort this problem i googled’ a lot and found information scattered all over the place, In my need to have everything in one place i thought i jot down a few notes. So to fix the issue I had to do the following&lt;/p&gt;  &lt;p&gt;Install a Oracle 11i client home.&lt;/p&gt;  &lt;p&gt;Install Oracle 11i Data Access components into the home created in the previous step&lt;/p&gt;  &lt;p&gt;The we have to make sure the odp.net folder which resides under the home directory has permissions for ASP.Net and Network Service accounts for read and execute on all sub folders and files. &lt;/p&gt;  &lt;p&gt;It doesn’t end there if your connection strings use TNS names configure tnsnames.ora in the network\admin folder of the 11i client folder. In our case the 11i Components where used to access 9i databases so i just copied the 9i tnsnames.ora file into the 11i client.&lt;/p&gt;  &lt;p&gt;Once all this is done you should be good to go with your applications. Most provider related exceptions should be resolved when you follow this procedure.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4003504748921453462-4969924211686957270?l=www.agiledrivendevelopment.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.agiledrivendevelopment.net/feeds/4969924211686957270/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4003504748921453462&amp;postID=4969924211686957270' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/4969924211686957270'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/4969924211686957270'/><link rel='alternate' type='text/html' href='http://www.agiledrivendevelopment.net/2008/07/oracle-9i-and-11g-data-access.html' title='Oracle 9i and 11g Data Access Components for .Net'/><author><name>Log4Agile</name><uri>http://www.blogger.com/profile/04640347817726894882</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4003504748921453462.post-7384795935615588063</id><published>2008-07-23T11:28:00.002+01:00</published><updated>2008-07-23T11:54:56.789+01:00</updated><title type='text'>Through with the 2nd year, 1 more to go</title><content type='html'>La la lalalalalala !!! Just checked my 2nd year MBA results, quite a relief to have passed with some good scores.. I was a bit worried I wouldnt get through... considering the power naps between assignment work ...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4003504748921453462-7384795935615588063?l=www.agiledrivendevelopment.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.agiledrivendevelopment.net/feeds/7384795935615588063/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4003504748921453462&amp;postID=7384795935615588063' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/7384795935615588063'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/7384795935615588063'/><link rel='alternate' type='text/html' href='http://www.agiledrivendevelopment.net/2008/07/through-with-2nd-year-1-more-to-go.html' title='Through with the 2nd year, 1 more to go'/><author><name>Log4Agile</name><uri>http://www.blogger.com/profile/04640347817726894882</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4003504748921453462.post-4653423370348404347</id><published>2008-07-22T22:24:00.001+01:00</published><updated>2008-07-22T22:24:08.919+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Business'/><title type='text'>Processes, Engineering and Organisations</title><content type='html'>&lt;p&gt;I reflect on my miniscule career of eight years and some management studies and I find myself thinking about how i would want to do business or run an organisation, I understand profit is the basis for any business being brutally factual about it , but my point is as profit increases and businesses grow rate of returns decrease due to scalability and efficiency issues. As I start my rant I have to mention there is a clear difference in engineering process and quality processes. Processes which are used to engineer a product are different from processes using to perform business. Trying to smudge one with the other in the name of organisational vision is in itself a game most service providers play and the IT industry is full of such innuendos , does any organisation care to mention what engineering processes are going to be used in there project tenders, I guess not.. some how the most important things for engineering which is the task in hand fail to make the list of priorities. We are too busy to pay attention to detail and want the bare bones in place.&lt;/p&gt;  &lt;p&gt;I have been working on improving engineering processes for sometime now and have been at both ends, creating and consuming processes. Some organisations use the fixed cost project model and would probably say I will pass as the stakeholders are only interested in there projects and not the engineering process itself, however what they do like is a accreditation such as ISO etc. Even though the PMO as a functional body exists, it doesn't really work as a unified body other than trying to sort out dependencies and integration issues and they wonder why most projects are over budgeted and running longer they should be , If these organisations join the bandwagon of adopting a process like Scrum, Prince or CMM they are not going to find much mileage unless they have there fundamentals sorted out , simple things like infrastructure, configuration management and engineering processes some how manage to get to the list of requisites of a project only at the end of a disaster, or in some cases where you have outsourced your development in a Root Cause Analysis, the funny thing about the RCA is in my experience no one bothers or cares to look at it and there are no lessons learnt either, funny the person who has to come up with it also has mask the most obvious factors which increase cost.. &lt;/p&gt;  &lt;p&gt;To run an organisation with innovative engineering and quality processes takes more than training a bunch of individuals on some process and asking them to get on with it, Organisational leaders such as CTO’s and CEO’s need to understand that unless it is pipelined form the top in the form of actions, they are not going to maximise return on investment. Unless they do so , PMO' bodies will not action anything because at the moment every organisation is so concerned about short term goals and profits that they have laid the rules of sustainability in business to rest, It is not that organisations don’t do enough , it is just that they try to do something only when the eggs are rotten.. &lt;/p&gt;  &lt;p&gt;Oh i work in IT so the references to CMM/ Scrum/ Prince you can take anything for an example Six Sigma, ISO, TQM , I am on a train at 10 in the night and this is so not what i should be thinking about&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4003504748921453462-4653423370348404347?l=www.agiledrivendevelopment.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.agiledrivendevelopment.net/feeds/4653423370348404347/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4003504748921453462&amp;postID=4653423370348404347' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/4653423370348404347'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/4653423370348404347'/><link rel='alternate' type='text/html' href='http://www.agiledrivendevelopment.net/2008/07/processes-engineering-and-organisations.html' title='Processes, Engineering and Organisations'/><author><name>Log4Agile</name><uri>http://www.blogger.com/profile/04640347817726894882</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4003504748921453462.post-5704990255202011694</id><published>2008-07-09T13:01:00.001+01:00</published><updated>2008-07-09T13:01:04.625+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Software'/><category scheme='http://www.blogger.com/atom/ns#' term='Database'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server'/><title type='text'>Data Modelling Jazz</title><content type='html'>&lt;p&gt;When we often think of data modelling it is a pretty picture created in Visio and for the some one more serious about data modelling it is representing entities, attributes and relationships in a meaningful manner. I didn’t realise modelling languages are different and a tool such as Visio supports/ works on such languages. e.g IDEFIX(Integration Definition for Information Modelling) is modelling language .. Woah that definition really woke me up .. and as usual this was developed in the US Airforce in 1985 &lt;/p&gt;  &lt;p&gt;The primary tool of a database designer is the data model. It’s such a great tool because it can show the details not only of single tables at a time, but the relationships between several    &lt;br /&gt;entities at a time. Of course it is not the only way to document a database; &lt;/p&gt;  &lt;p&gt;• Often a product that features a database as the central focus will include a document that lists all tables, data types, and relationships. &lt;strong&gt;(developers think can’t be bothered)&lt;/strong&gt;     &lt;br /&gt;• Every good DBA has a script of the database saved somewhere for re-creating the database. &lt;strong&gt;(developers think am still not bothered)&lt;/strong&gt;     &lt;br /&gt;• SQL Server’s metadata includes ways to add properties to the database to describe the objects. &lt;strong&gt;(developers by now would think oh get a life will you)&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;Some common terms you would come across are Entities which are synonymous to tables in database, attributes which are synonymous to column definitions in a table and relationships represent how two entities relate to each other.&amp;#160; We represent these pictorially or grammatically in written text Anyway my idea of blogging about Data Modelling was to drop a few notes on some practices we could adopt while modelling data.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;Entity names&lt;/strong&gt; There are two ways you can go about these: plural or singular. Some argue tables names should be singular , but many feel that the table name refers to the set of rows and should be plural. Whatever convention you choose be consistent with it, mixing and matching could end up confusing the person reading the data model.&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Attribute names&lt;/strong&gt;: It’s generally not necessary to repeat the entity name in the attribute name, except for the primary key. The entity name is implied by the attribute’s inclusion in the entity. The chosen attribute name should reflect precisely what is contained in the attribute and how it relates to the entity. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Relationship&lt;/strong&gt;s: Name relationships with verb phrases, which make the relationship between a parent and child entity a readable sentence. The sentence expresses the       &lt;br /&gt;relationship using the entity names and the relationship cardinality. The relationship sentence is a very powerful tool for communicating the purpose of the relationships with non technical members of the project team (e.g., customer representatives. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Domains&lt;/strong&gt;: Define domains for your attributes, implementing type inheritance wherever possible to take advantage of domains that are similar. Using domains gives you a set of standard templates to use when building databases that ensures consistency across your database.&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Objects&lt;/strong&gt;: Define every object so it is clear what you had in mind when you created a given object. This is a tremendously valuable practice to get into, as it will pay off later when questions are asked about the objects, and it will serve as documentation to provide to other programmers and/or users. &lt;/li&gt; &lt;/ul&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4003504748921453462-5704990255202011694?l=www.agiledrivendevelopment.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.agiledrivendevelopment.net/feeds/5704990255202011694/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4003504748921453462&amp;postID=5704990255202011694' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/5704990255202011694'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/5704990255202011694'/><link rel='alternate' type='text/html' href='http://www.agiledrivendevelopment.net/2008/07/data-modelling-jazz.html' title='Data Modelling Jazz'/><author><name>Log4Agile</name><uri>http://www.blogger.com/profile/04640347817726894882</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4003504748921453462.post-8555881795950648175</id><published>2008-06-26T01:17:00.001+01:00</published><updated>2008-06-26T01:17:37.901+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Scrum'/><title type='text'>Implementing Scrum</title><content type='html'>&lt;p&gt;&lt;a href="http://www.scrumalliance.org/articles/99-implementing-scrum--questions-to-answer-before-you-begin" target="_blank"&gt;8 Questions to Answer Before You Begin&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4003504748921453462-8555881795950648175?l=www.agiledrivendevelopment.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.agiledrivendevelopment.net/feeds/8555881795950648175/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4003504748921453462&amp;postID=8555881795950648175' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/8555881795950648175'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/8555881795950648175'/><link rel='alternate' type='text/html' href='http://www.agiledrivendevelopment.net/2008/06/implementing-scrum.html' title='Implementing Scrum'/><author><name>Log4Agile</name><uri>http://www.blogger.com/profile/04640347817726894882</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4003504748921453462.post-4480138545451965497</id><published>2008-06-26T01:02:00.001+01:00</published><updated>2008-06-26T01:02:35.892+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Business'/><title type='text'>Meet the Antipreneurs</title><content type='html'>&lt;p&gt;They profit from the free market, but they criticize it, too. So how do they get away with it? &lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.businessweek.com/magazine/content/08_66/s0806032873701.htm?chan=magazine+channel_bwsmallbiz+--+top+stories" target="_blank"&gt;http://www.businessweek.com/magazine/content/08_66/s0806032873701.htm?chan=magazine+channel_bwsmallbiz+--+top+stories&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4003504748921453462-4480138545451965497?l=www.agiledrivendevelopment.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.agiledrivendevelopment.net/feeds/4480138545451965497/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4003504748921453462&amp;postID=4480138545451965497' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/4480138545451965497'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/4480138545451965497'/><link rel='alternate' type='text/html' href='http://www.agiledrivendevelopment.net/2008/06/meet-antipreneurs.html' title='Meet the Antipreneurs'/><author><name>Log4Agile</name><uri>http://www.blogger.com/profile/04640347817726894882</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4003504748921453462.post-1828208652977917169</id><published>2008-06-25T00:09:00.001+01:00</published><updated>2008-06-25T00:15:04.839+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Software'/><category scheme='http://www.blogger.com/atom/ns#' term='Scrum'/><title type='text'>Iteration Length?</title><content type='html'>&lt;p&gt;Our organisation has always used two week iterations and sometimes we do wonder if two weeks is optimum, Well the first thought was for enhancement projects two weeks fits the bill, these could be projects where the solution to implement the features is available to the team, but for a brand new project which includes a technical learning curve and innovation, three weeks might be be apt. This is subject to discussion with the teams. Although Scum recommends a 30 day iteration, 2 week iterations yield results and 3 week iterations will yield innovative results. At the end of the day both iteration lengths are within the realm of Scrum and it is a variable available to teams and the product owner, how it is varied or used as long as the goals of the release are met, is not important.&lt;/p&gt;  &lt;p&gt;Based on previous experience with two week iterations I have made some observations which kind of remind us the strength of the two week iteration&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Two weeks is just about enough time to get some amount of meaningful development done. &lt;/li&gt;    &lt;li&gt;Two week iterations indicate and provide more opportunities to succeed or fail.e.g, within a 90 day release plan, 5 - 2-week iterations of development and 1 stabilisation iteration at the end make it possible to have checkpoints on the way to the release. &lt;/li&gt;    &lt;li&gt;The 2-week rhythm is a natural calendar cycle that is easy for all participants to remember and lines up well with typical 1 or 2 week vacation plans, simplifying capacity estimates for the team. &lt;/li&gt;    &lt;li&gt;Velocity can be measured and scope can be adjusted more quickly. &lt;/li&gt;    &lt;li&gt;The overhead in planning and closing an iteration is proportioned to the amount of work that can be accomplished in a two week sprint. &lt;/li&gt;    &lt;li&gt;A two week iteration allows the team to break down work into small chunks where the define/build/test cycle is concurrent. With longer iterations, there is a tendency for teams to build a more waterfall-like process. &lt;/li&gt;    &lt;li&gt;Margin of error for capacity planned and available is lesser in two week iterations. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Well the above is on the basis of what I have observed and may be different in your organisation.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4003504748921453462-1828208652977917169?l=www.agiledrivendevelopment.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.agiledrivendevelopment.net/feeds/1828208652977917169/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4003504748921453462&amp;postID=1828208652977917169' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/1828208652977917169'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/1828208652977917169'/><link rel='alternate' type='text/html' href='http://www.agiledrivendevelopment.net/2008/06/iteration-length.html' title='Iteration Length?'/><author><name>Log4Agile</name><uri>http://www.blogger.com/profile/04640347817726894882</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4003504748921453462.post-4064275012707670314</id><published>2008-06-24T02:18:00.001+01:00</published><updated>2008-06-24T02:18:08.516+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Scrum'/><title type='text'>Five Levels of Planning in Scrum</title><content type='html'>&lt;p&gt; In agile methods, a team gets work through iteration planning. Due to the shortness of the iteration a planning gains importance than an actual plan. The disadvantage of iteration planning when applied to projects that run for more then a few iterations or with multiple teams is that view of long term implications of iteration activities can be lost. In other words: the view of &amp;#8216;the project as a whole&amp;#8217; is lost. &lt;/p&gt;  &lt;p&gt;Planning activities for large-scale development efforts should rely on five levels&lt;/p&gt;  &lt;p&gt;&amp;#8226; Product Vision    &lt;br /&gt;&amp;#8226; Product Roadmap     &lt;br /&gt;&amp;#8226; Release Plan     &lt;br /&gt;&amp;#8226; Sprint Plan     &lt;br /&gt;&amp;#8226; Daily Commitment     &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/sritsqldotnet/SGBLTDURKtI/AAAAAAAAADw/CGJ5OhfS3VE/s1600-h/Five%20Levels%20of%20Planning%5B2%5D.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="119" alt="Five Levels of Planning" src="http://lh6.ggpht.com/sritsqldotnet/SGBLT-Gy_NI/AAAAAAAAAD0/s4XGDJGbWaw/Five%20Levels%20of%20Planning_thumb.png?imgmax=800" width="244" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Each of the five levels of planning help us address fundamental planning principles of priorities, estimates and commitments.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4003504748921453462-4064275012707670314?l=www.agiledrivendevelopment.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.agiledrivendevelopment.net/feeds/4064275012707670314/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4003504748921453462&amp;postID=4064275012707670314' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/4064275012707670314'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/4064275012707670314'/><link rel='alternate' type='text/html' href='http://www.agiledrivendevelopment.net/2008/06/five-levels-of-planning-in-scrum.html' title='Five Levels of Planning in Scrum'/><author><name>Log4Agile</name><uri>http://www.blogger.com/profile/04640347817726894882</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/sritsqldotnet/SGBLT-Gy_NI/AAAAAAAAAD0/s4XGDJGbWaw/s72-c/Five%20Levels%20of%20Planning_thumb.png?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4003504748921453462.post-5918017983590797325</id><published>2008-06-20T07:35:00.001+01:00</published><updated>2008-06-20T07:36:35.404+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Architecture'/><category scheme='http://www.blogger.com/atom/ns#' term='WCF'/><title type='text'>Principles of SOA</title><content type='html'>&lt;p&gt;Although there is no official standard for SOA, the community seems to agree that there are four guiding principles to achieve SOA.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;Service boundaries are explicit. &lt;/strong&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;blockquote&gt;   &lt;p&gt;Services expose business functionality by using well defined contracts, and these contracts fully describe a set of concrete operations and messages. Implementation details of the service are unknown, and the consumer of the service is agnostic to this, so the technology platform of the service is irrelevant to the client. What is relevant though is where the service is present so that the client can reach it to consume it.&lt;/p&gt; &lt;/blockquote&gt;  &lt;blockquote&gt;   &lt;p&gt;Remoting, WCF and Web Services all support this principle. But what distinguishes WCF is its ability to answer some of the limitations in the other technologies. e.g for Remoting to be used, the underlying CLR types have to be shared between the client and the service, not so in WCF. Web Services with WSE allows a service to address this principle as well.&lt;/p&gt; &lt;/blockquote&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;Services are autonomous.&lt;/strong&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;blockquote&gt;   &lt;p&gt;As previously mentioned services expose business functionality, to achieve this they encapsulate the business functionality, what this means is that the service should encapsulate all tiers in the functionality from database access to business tier and the contract itself. At the end of the day the service should be replaceable and movable without affecting the consumer. As a rule of thumb to achieve this any external dependencies should be eliminated during the design process. Any component changes in&amp;#160; the service should change the version of the service as a logical unit. This is otherwise called atomicity.&lt;/p&gt; &lt;/blockquote&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;Clients and Services share contracts, not code.&lt;/strong&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;blockquote&gt;   &lt;p&gt;Given that we said service boundaries are explicit, the contract enforces the boundary between the client and service, and this leads us to conclude that a service once published cannot be changed and all future versions should be backward compatible. There is an argument that contracts may or may not be tied to a particular technology or platform. I am unable to comment on this but seems to be only fair is as long as the service can be consumed by a client and the client can remain agnostic to the technology used to implement the service, this principle is achieved.&lt;/p&gt; &lt;/blockquote&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;Compatibility is based on policy.&lt;/strong&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;blockquote&gt;   &lt;p&gt;Contracts define functionality offered by a service, while a policy defines the constraints imposed by the service on the consumer for attributes like security, communication protocol and reliability requirements. Prior to WCF , Web Services with WSE 3.0 helped developers achieve this, I have had the opportunity to do this on .Net 2.0 using WSE and i can say that this is pretty crucial to how your service behaves with the consumer :). At the end of the day the policy is also exposed in WSDL to the client , so that client knows the constraints imposed by the service.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;As a architect/developer we may try to meet the principles listed above in our applications, but due to the influence of technology in implementation and deployment we may not be able to abide by these principles strictly, but that is probably alright. For e.g if we had three Services which encapsulate functionality for order processing, accounts and sales, we cant really have three databases for each service to work individually, we may have a reporting service which may need access to the three databases, in which case we may consolidate everything into a single database, and use schemas in the database to isolate functionality at the database level, then build a database access layer which servers the functionality required by the service. Relational data seems to be quite limiting in this respect, but would the Entity Framework allow us to address, May be may be not it is yet to be seen&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4003504748921453462-5918017983590797325?l=www.agiledrivendevelopment.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.agiledrivendevelopment.net/feeds/5918017983590797325/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4003504748921453462&amp;postID=5918017983590797325' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/5918017983590797325'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/5918017983590797325'/><link rel='alternate' type='text/html' href='http://www.agiledrivendevelopment.net/2008/06/principles-of-soa.html' title='Principles of SOA'/><author><name>Log4Agile</name><uri>http://www.blogger.com/profile/04640347817726894882</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4003504748921453462.post-6638857037139919732</id><published>2008-06-19T13:00:00.000+01:00</published><updated>2008-06-19T13:08:52.613+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><category scheme='http://www.blogger.com/atom/ns#' term='WCF'/><title type='text'>WCF Fundamentals</title><content type='html'>&lt;p&gt;I have been trying to read some stuff on some WCF concepts and thought it would be useful to jot down some of the concepts outlined by Michele Leroux Bustamante in the book &amp;quot;Learning WCF&amp;quot; for reference purposes. Although it is pure theory it is useful to get an understanding of WCF. If you have used WSE before these may seem familiar ..&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Messaging, Serialization and RPC&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Enterprise applications communicate with each other using remote calls across process and machine boundaries. The format of the message is what determines the application's ability to communicate with other applications. RPC and XML are two common ways of achieving this. RPC calls are used to communication with objects or components across boundaries (process and machine implied). A RPC call is marshaled by converting it into a message and sent over a transport protocol such as TCP. At the destination the message is unmarshaled into a stack frame that invokes the object. Generally a proxy is used at the client and stub at the destination to marshal and unmarshal calls at either end points. This process is serialization and deserialization. Now the proxy and the stub can use only. Remoting in .Net works with this principle of messaging. Now RPC comes in many flavours, but each flavour is not compatible with another , this means it is not interoperable.. so have this applied in a interoperable way we use Web Services or WCF. WCF however wins over the two, RPC and Web Services because of its ability to operate in both RPC style messaging and Web Service messaging. In both cases the service type is used and the life time of the service type can be controlled using configuration settings defined for the service model&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Services&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;In WCF all services use CLR types to encapsulate business functionality and for a CLR type to be qualified as a service it must implement a &lt;em&gt;service contract&lt;/em&gt;. Marking a class or interface with an attribute &lt;em&gt;ServiceContractAttribute&lt;/em&gt; makes a class a service type or the class implementing the interface a service type. To mark a method as a service operation (in a contract definition) , we use the attrubute &lt;em&gt;OperationContractAttribute.&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Hosting&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;WCF Services can be self hosted or on IIS like ASP.Net applications. The host is important for the service, and therefore a &lt;em&gt;ServiceHost&lt;/em&gt; instance is associated with a Service type. We construct a &lt;em&gt;ServiceHost&lt;/em&gt; and provide it with a service type to activate incoming messages.The &lt;em&gt;ServiceHost&lt;/em&gt; manages the lifetime of the communication channels for the service.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Metadata&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;The client to understand how it should communicate with a WCF service needs data about the address, binding and contract. This is the part of the metadata of the service. Clients rely on this metadata to invoke the service. It can be exposed by the service in two ways, the Service host can expose metadata exchange endpoint to access metadata at runtime or using a WSDL. In either case clients use tools to generate proxies .&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Proxies&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Clients use proxies to communicate with the WCF service. A proxy is a type which represents the service contract and hides serialization details from the client. Like Web Services, in WCF if you have access to the service contract you can create a proxy using a tool. The proxy only gives information about the service and its operations, the client will still need metadata to generate endpoint configuration and there are tools available to do this.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Endpoints&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;When a service host opens a communication channel for a service it must expose one or more endpoints for the client to invoke. An endpoint is made of three parts Address (a URI), Binding (protocols supported), and Contract (Operations). A service host is generally provided with one or more endpoints before it opens a communication channel.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Addresses&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Each endpoint for the service is represented by an Address. The Address is in the format &lt;strong&gt;&lt;em&gt;scheme://domain:port/path.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;Scheme&lt;/strong&gt; represents the transport protocol. Http, TCP/IP, named pipes or MSMQ are some of them, scheme for MSMQ is &lt;strong&gt;&lt;em&gt;net.msmq&lt;/em&gt;&lt;/strong&gt;, for TCP it is &lt;strong&gt;&lt;em&gt;net.tcp&lt;/em&gt;&lt;/strong&gt; and named pipes is &lt;strong&gt;&lt;em&gt;net.pipe&lt;/em&gt;&lt;/strong&gt;. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Port&lt;/strong&gt; is the communication port to be used for the scheme other than the default port if required, for default ports it is not required to be specified. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Domain&lt;/strong&gt; represents the machine name or the web domain. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Path&lt;/strong&gt; is usually provided as part of the address to disambiguate service endpoints. E.g &lt;strong&gt;&lt;em&gt;net.tcp://localhost:9000 &lt;/em&gt;&lt;/strong&gt;or &lt;strong&gt;&lt;em&gt;net.msmq://localhost/QueuedServices/ServiceA&lt;/em&gt;&lt;/strong&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;Bindings&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;A binding describes the protocols supported by a particular endpoint, specifically&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Transport protocol, TCP, MSMQ, HTTP or named pipes. &lt;/li&gt;    &lt;li&gt;Message Encoding format , XML or binary. &lt;/li&gt;    &lt;li&gt;Other protocols for messaging, security and reliability, plus anything else that is custom. Several predefined bindings are available as standard bindings in WCF, however these only cover some common communication scenarios. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;Channels&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Channels facilitate communication between the client and the WCF service. The ServiceHost creates a &lt;strong&gt;&lt;em&gt;channel listener&lt;/em&gt;&lt;/strong&gt; for each end point which generates a communication channel. The proxy on the client creates a&lt;strong&gt;&lt;em&gt;&amp;#160; channel factory&lt;/em&gt;&lt;/strong&gt; which generates a communication channel for the client. Both these channels should be compatible for communication to be successful between the client and the service.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Behaviors&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Behaviors are local to the service or the client and are used to control features such as exposing metadata, authorisation, authentication or transactions etc. &lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4003504748921453462-6638857037139919732?l=www.agiledrivendevelopment.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.agiledrivendevelopment.net/feeds/6638857037139919732/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4003504748921453462&amp;postID=6638857037139919732' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/6638857037139919732'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/6638857037139919732'/><link rel='alternate' type='text/html' href='http://www.agiledrivendevelopment.net/2008/06/wcf-fundamentals.html' title='WCF Fundamentals'/><author><name>Log4Agile</name><uri>http://www.blogger.com/profile/04640347817726894882</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4003504748921453462.post-8563077906169520536</id><published>2008-06-18T20:56:00.001+01:00</published><updated>2008-06-18T20:58:05.759+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Database'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server 2008 - Katmai'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server'/><category scheme='http://www.blogger.com/atom/ns#' term='Katmai'/><title type='text'>SQL Server 2008 RC0 is out</title><content type='html'>&lt;p&gt;RC0 SQL Server 2008 for some reason seems to be quietly done, didn't realise it was out, it is available to download at &lt;a title="SQL Server 2008 RC" href="http://www.microsoft.com/downloads/details.aspx?FamilyId=35F53843-03F7-4ED5-8142-24A4C024CA05&amp;amp;displaylang=en" target="_blank"&gt;SQL Server 2008 RC&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;PS: SQL Server 2008 RC0 will automatically expire after 180 days&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4003504748921453462-8563077906169520536?l=www.agiledrivendevelopment.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.agiledrivendevelopment.net/feeds/8563077906169520536/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4003504748921453462&amp;postID=8563077906169520536' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/8563077906169520536'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/8563077906169520536'/><link rel='alternate' type='text/html' href='http://www.agiledrivendevelopment.net/2008/06/sql-server-2008-rc0-is-out.html' title='SQL Server 2008 RC0 is out'/><author><name>Log4Agile</name><uri>http://www.blogger.com/profile/04640347817726894882</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4003504748921453462.post-6261977772275113073</id><published>2008-06-15T03:33:00.001+01:00</published><updated>2008-06-16T11:21:23.732+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Architecture'/><category scheme='http://www.blogger.com/atom/ns#' term='Software'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>Enterprise Application Integration</title><content type='html'>&lt;p&gt;I have been recently thinking about integration scenarios for different applications and how to take decisions on the way two applications should be integrated.. Infact my question is what are the factors i would consider to make a decision on how two applications will integrate. On the same note as much as there is a benefit that comes out of integration of two applications more often than not there is a resulting consequence based on how the applications integrated&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Should the two applications be loosely coupled?&lt;/strong&gt; This is first one that comes to my mind ,on most occasions the answer is yes it should be loosely coupled, the more loosely coupled the two applications are the more opportunities they have to extend there functionality without affecting each other and the integration itself. If tightly coupled its obvious that the integration breaks when applications change.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Simplicity&lt;/strong&gt;, if we as developers minimize code involved in the integration of the applications, it becomes easily maintainable and provides better integration.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Integration technology&lt;/strong&gt; Different integration techniques require varying amounts of specialized software and hardware. These special tools can be expensive, can lead to vendor lock-in, and increase the burden on developers to understand how to use the tools to integrate applications.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Data format&lt;/strong&gt; , The format in which data is exchanged is important, and it should be borne in mind that the format should be compatible with an independent translator other than the integrating applications itself so that at some point these applications are also able to talk to other applications should there be a need. A related issue is data format evolution and extensibility and how the format can change over time and how that will affect the applications.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Data timeliness&lt;/strong&gt; , we need to minimize the length of time between when one application decides to share some data and other applications have that data. Data should be exchanged in small chunks, rather than large sets. Latency in data sharing has to be factored into the integration design; the longer, the more opportunity for shared data to become stale, and the more complex integration becomes.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Data or functionality&lt;/strong&gt;, Integrated applications may also wish to share functionality such that each application can invoke the functionality in the others. But this may have significant consequences for how well the integration works.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Asynchronicity&lt;/strong&gt;, This is a aspect developers start realising after implementation and performance tests fail, By default we think and code synchronously,&amp;#160; This is especially true of integrated applications, where the remote application may not be running or the network may be unavailable, the source application may wish to simply make shared data available or log a request.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4003504748921453462-6261977772275113073?l=www.agiledrivendevelopment.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.agiledrivendevelopment.net/feeds/6261977772275113073/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4003504748921453462&amp;postID=6261977772275113073' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/6261977772275113073'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/6261977772275113073'/><link rel='alternate' type='text/html' href='http://www.agiledrivendevelopment.net/2008/06/enterprise-application-integration.html' title='Enterprise Application Integration'/><author><name>Log4Agile</name><uri>http://www.blogger.com/profile/04640347817726894882</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4003504748921453462.post-5322945698558473955</id><published>2008-06-13T18:03:00.001+01:00</published><updated>2008-06-13T18:04:10.146+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='COM'/><category scheme='http://www.blogger.com/atom/ns#' term='Threads'/><category scheme='http://www.blogger.com/atom/ns#' term='ASP.Net'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>ASP.Net and COM Interop</title><content type='html'>&lt;p&gt;At some point in time we have had to use a COM component in .Net applications as part of migrating legacy code to new technologies, but kind of puts me off is doing it without knowing why we are doing it or at the least how the legacy component works. Visual Studio makes it so easy to use COM components by doing all the work for you under the covers. In this article i would like to see how COM is used and get into some of the aspects of dealing with COM.. in the .Net world. A COM component can be consumed in .Net either by Early binding or Late binding.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Early binding&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;This is where type information about the COM component is available to the consumer at design time to the consumer, e.g most common thing we do is reference it in VS.Net and the studio runs tlbimp.exe to generate the Interop assembly for consumption by .Net code, this is because .Net needs meta data information about the assembly before hand. Another reason this is most prefered way of consuming COM objects is that Early binding is much faster in its access than Late bindinig, In addition to this developers are able to use the COM object as if it was another .Net object by creating an instance using the new keyword.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Late Binding &lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Information of the COM component is not known until code is executed or in the runtime.A classic example of this is using HttpServerUtility.CreateObject used in ASP pages You will need to pass the component program ID of the COM component to this method.. Now it is important to consider how COM components are instantiated. In windows XP and 2000 how the COM component is instantiated depends on how the threading model of the COM compoenent is marked in the registry as Free, Apartment, Neutral or Both.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Components marked Free&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;When we call a COM component marked as free in ASP.Net the instance is on the same threadpool thread that the ASP.Net page started running.&amp;#160; The ASP.Net thread pool is initialised as a Multi Threaded Apartment (MTA) and since the COM component is marked as Free, no thread switch is necessary and performance penalty is minimal&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Components marked Apartment&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Traditionally, business COM components that are called from either ASP have been marked Apartment. The single-threaded apartment (STA) threading model is not compatible with the default threading model for the ASP.NET thread pool, which is MTA. As a result, calling a native COM component marked Apartment from an ASP.NET page results in a thread switch and COM cross-apartment marshalling. &lt;/p&gt;  &lt;p&gt;Under stress, this presents a severe bottleneck. To work around this issue, a new directive called ASPCompat was introduced to the System.Web.UI.Page object. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;How ASPCompat Works &lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;The ASPCompat attribute minimizes thread switching due to incompatible COM threading models. More specifically, if a COM component is marked Apartment, the ASPCompat = &amp;quot;true&amp;quot; directive on an ASP.NET page runs the component marked Apartment on one of the COM+ STA worker threads. Assume that you are requesting a page called UnexpectedCompat.aspx that contains the directive ASPCompat =&amp;quot;true&amp;quot;. When the page is compiled, the page compiler checks to see if the page requires ASPCompat mode. Because this value is present, the page compiler modifies the generated page class to implement the IHttpAsyncHandler interface, adds methods to implement this interface, and modifies the page class constructor to reflect that ASPCompatMode will be used.&lt;/p&gt;  &lt;p&gt;The two methods that are required to implement the IHttpAsyncHandler interface are BeginProcessRequest and EndProcessRequest. The implementation of these methods contains calls to this.ASPCompatBeginProcessRequest and this.ASPCompatEndProcessRequest, respectively.    &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;You can view the code that the page compiler creates by setting Debug=&amp;quot;true&amp;quot; in the &amp;lt;compilation&amp;gt; section of the web.config or machine.config files. &lt;/p&gt;  &lt;p&gt;The Page.ASPCompatBeginProcessRequest() method determines if the page is already running on a COM+ STA worker thread. If it is, the call can continue to execute synchronously. A more common scenario is a page running on a .NET MTA thread-pool thread. ASPCompatBeginProcessRequest() makes an asynchronous call to the native function ASPCompatProcessRequest() within Aspnet_isapi.dll. &lt;/p&gt;  &lt;p&gt;The following describes what happens when invoking COM+ in the latter scenario:    &lt;br /&gt;1. The native ASPCompatProcessRequest() function constructs an ASPCompatAsyncCall class that contains the callback to the ASP.NET page and a context object created by ASP.NET. The native ASPCompatProcessRequest() function then calls a method that creates a COM+ activity and posts the activity to COM+. &lt;/p&gt;  &lt;p&gt;2. COM+ receives the request and binds the activity to an STA worker thread.&lt;/p&gt;  &lt;p&gt;3. Once the thread is bound to an activity, it calls the ASPCompatAsyncCall::OnCall() method, which initializes the intrinsics so they can be called from the ASP.NET (this is similar to classic ASP code). This function calls back into managed code so that the ProcessRequest() method of the page can continue executing.&lt;/p&gt;  &lt;p&gt;4. The page callback is invoked and the ProcessRequest() function on that page continues to run on that STA thread. This reduces the number of thread switches required to run native COM components marked Apartment.&lt;/p&gt;  &lt;p&gt;5. Once the ASP.NET page finishes executing, it calls Page.ASPCompat EndProcessRequest() to complete the request&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4003504748921453462-5322945698558473955?l=www.agiledrivendevelopment.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.agiledrivendevelopment.net/feeds/5322945698558473955/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4003504748921453462&amp;postID=5322945698558473955' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/5322945698558473955'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/5322945698558473955'/><link rel='alternate' type='text/html' href='http://www.agiledrivendevelopment.net/2008/06/aspnet-and-com-interop.html' title='ASP.Net and COM Interop'/><author><name>Log4Agile</name><uri>http://www.blogger.com/profile/04640347817726894882</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4003504748921453462.post-3361039569285176832</id><published>2008-05-22T13:22:00.001+01:00</published><updated>2008-05-22T13:22:58.915+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='T-SQL'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server'/><title type='text'>RESEED</title><content type='html'>&lt;p&gt;Just learnt a new TSQL term , although i did know this functionality is achievable in other ways, i hadn't come across this one before. RESEED resets the seed value of the IDENTITY. However, SQL Server 2000 works differently on RESEED for virgin tables when compared with 2005/2008.&lt;/p&gt;  &lt;p&gt;For the table_name, to reset the seed value of the identity column to a new_value &lt;em&gt;DBCC CHECKIDENT(table_name, RESEED, new_value)&lt;/em&gt; does the trick.&lt;/p&gt;  &lt;p&gt;In SQL Server 2000 RESEED always increments the seed value but on 2005/2008, it doesn't increment but starts with the new_value. &lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4003504748921453462-3361039569285176832?l=www.agiledrivendevelopment.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.agiledrivendevelopment.net/feeds/3361039569285176832/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4003504748921453462&amp;postID=3361039569285176832' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/3361039569285176832'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/3361039569285176832'/><link rel='alternate' type='text/html' href='http://www.agiledrivendevelopment.net/2008/05/reseed.html' title='RESEED'/><author><name>Log4Agile</name><uri>http://www.blogger.com/profile/04640347817726894882</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4003504748921453462.post-514063722787650124</id><published>2008-05-20T17:33:00.001+01:00</published><updated>2008-05-20T17:33:04.385+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Cruise Control.Net'/><category scheme='http://www.blogger.com/atom/ns#' term='Nant'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>Cruise Control .Net farms</title><content type='html'>&lt;p&gt;In the present organisation that i work for , we work as four teams continuously developing code and checking it into TFS and as a consequence of this we have adopted the process of continuous integration using Cruise Control.Net . Well using Cruise Control.Net along side Nant to have automated build processes is nothing new, but what we have achieved and are planning to achieve is hopefully a unique implementation of a automated build platform. We have about nine different projects having there own automated builds and since Nant is not able to scale across multiple CPUs, the resources on the server are underutilized and wait times have increased considerably. So as a solution to this we have not installed two instances of Cruise Control on the main build server one called the current build which developers use to build binaries and test , while the nightly build runs on a scheduled basis generating the end product installers. Sometimes people may still need a setup and nightly build allows forcing builds manually using the CC Tray application. &lt;/p&gt;  &lt;p&gt;So to achieve this there were a few bottle necks we had to work around.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Cruise Control does not install two instances completely, for starters it does install the windows service for itself when you install a second instance. So you have to manually install the service using the installutil.exe in the .Net framework.&lt;/li&gt;    &lt;li&gt;Since you will have two instances building simultaneously you will need to isolate the identities under which these build run and the physical locations of these builds.&lt;/li&gt;    &lt;li&gt;The cruise control server web dashboard also has to be configured manually as separate virtual directories. &lt;/li&gt;    &lt;li&gt;The cruise control manager for each instance has to be configured to use a different port, the default install of CC.Net using 21234, we could use something like 21244 as a series . In case you have a firewall make sure your network admin allows requests to this port (CC Tray uses these ports to communicate with the server)&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Now that said we have a single server which has two instances of Cruise Control, The build outputs are copied on to a network share. We now have another build server where we are going to replicate the set up of the first server and then split the CC projects across the two physical servers to share the load of the builds. It all looks simple, but thanks to the guy who authored a Templated build where I have been able to enhance it to achieve the following,&amp;#160; We have been constantly updating the build or the last one year and we are close to achieving end to end automation for the product, so when we check-in code to TFS , we are able to dish out a CD ISO image for the products to the network share in the nightly build. We also have switches as properties in the build scripts which can allow the current builds to create setups incase the nightly build is overloaded. Due to constant development work and support issues we have to squeeze work like this as part of our non functional sprint work. But then scrum treats engineering work as Non functional and is rightly justified in doing so.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4003504748921453462-514063722787650124?l=www.agiledrivendevelopment.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.agiledrivendevelopment.net/feeds/514063722787650124/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4003504748921453462&amp;postID=514063722787650124' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/514063722787650124'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/514063722787650124'/><link rel='alternate' type='text/html' href='http://www.agiledrivendevelopment.net/2008/05/cruise-control-net-farms.html' title='Cruise Control .Net farms'/><author><name>Log4Agile</name><uri>http://www.blogger.com/profile/04640347817726894882</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4003504748921453462.post-114690204667822703</id><published>2008-05-20T00:05:00.001+01:00</published><updated>2008-05-20T00:05:46.322+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Database'/><category scheme='http://www.blogger.com/atom/ns#' term='T-SQL'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server 2008 - Katmai'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server'/><category scheme='http://www.blogger.com/atom/ns#' term='Katmai'/><title type='text'>Storing Hierarchical Data - HeirarchyID</title><content type='html'>&lt;p&gt;In SQL Server 2000 we were limited by the 32 level recursion limit for TSQL, and storing and querying hierarchical data in the form&amp;#160; of trees was really difficult and inefficient, We used Cursors or temporary tables to write these queries. But simplicity, maintenance or performances were sacrificed. Ofcourse we could bundle a bit of code in the data layer of your application to share the load however this didn't the solve the problem in reporting scenarios where the data processing was to be done on the database server&lt;/p&gt;  &lt;p&gt;As we moved on to SQL Server 2005 it improved because of the introduction of CTE's, CTE's where beautiful solutions to solving querying hierarchical data,&amp;#160; I use the word beautiful because it looked nicer on the outset when you used it without knowing the limitations it worked well on development environments For e.g using the AdventureWorks database we could use a CTE to query employee manager data as shown below&lt;/p&gt;  &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; height: 229px; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;WITH&lt;/span&gt; UpperHierarchy(EmployeeId, LastName, Manager, HierarchyOrder)
 &lt;span style="color: #0000ff"&gt;AS&lt;/span&gt;
 (
    &lt;span style="color: #0000ff"&gt;SELECT&lt;/span&gt; emp.EmployeeId, emp.LoginId, emp.LoginId, 1 &lt;span style="color: #0000ff"&gt;AS&lt;/span&gt; HierarchyOrder
    &lt;span style="color: #0000ff"&gt;FROM&lt;/span&gt; HumanResources.Employee &lt;span style="color: #0000ff"&gt;AS&lt;/span&gt; emp
      &lt;span style="color: #0000ff"&gt;WHERE&lt;/span&gt; emp.ManagerId isNull
    &lt;span style="color: #0000ff"&gt;UNION&lt;/span&gt; &lt;span style="color: #0000ff"&gt;ALL&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;SELECT&lt;/span&gt; emp.EmployeeId, emp.LoginId, Parent.LastName, HierarchyOrder + 1
    &lt;span style="color: #0000ff"&gt;FROM&lt;/span&gt; HumanResources.Employee &lt;span style="color: #0000ff"&gt;AS&lt;/span&gt; emp
           &lt;span style="color: #0000ff"&gt;INNER&lt;/span&gt; &lt;span style="color: #0000ff"&gt;JOIN&lt;/span&gt; UpperHierarchy &lt;span style="color: #0000ff"&gt;AS&lt;/span&gt; Parent
                 &lt;span style="color: #0000ff"&gt;ON&lt;/span&gt; emp.ManagerId = parent.EmployeeId
 )
 &lt;span style="color: #0000ff"&gt;SELECT&lt;/span&gt; *
 &lt;span style="color: #0000ff"&gt;From&lt;/span&gt; UpperHierarchy&lt;/pre&gt;

&lt;p&gt;Although this decreased the complexity of writing queries, performance of these queries was still challenged on large databases, the optimisation of the CTE execution plans did improve things but as in any database situation the optimizer is handicapped without indexing capabilities. Indexes reduce the load on the query increasing performance and scalability. In addition in SQL 2005 the underlying storage structure was still something users had to design to suit there requirements. This just got better with the introduction of a new managed SQL CLR data type called HeirarchyID in SQL Server 2008., It is available ready to use in the databarse server now... If you now look back and remember the introduction of the CLR into SQL Server in Yukon you will appreciate this feature even more and how it has been panned out.. &lt;/p&gt;

&lt;p&gt;This data type does not store the identifier of the parent element but a set of information to locate the element in the hierarchy. This type represents a node in the tree structure. If you look at values contained in a column of &lt;b&gt;HeirarchyID&lt;/b&gt; type, you realize that they are binary values.It is extremely compact and supports arbitrary inserts and deletions. As per MS a node in an organizational hierarchy of 100,000 people with an average fanout of 6 levels takes about 38 bits. This is rounded up to 40 bits, or 5 bytes, for storage. Because it stores the elements hierarchy in its entirety it is also indexable now..&lt;/p&gt;

&lt;p&gt;As always there are a few limitations &lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;It can hold upto 892 bytes but to be honest that should allow you to span out into a really big tree structure under a single node. &lt;/li&gt;

  &lt;li&gt;A query with the FOR XML clause will fail on a table with &lt;b&gt;HeirarchyID&lt;/b&gt; unless the column is first converted to a character data type. Use the ToString() method to convert the &lt;b&gt;HeirarchyID&lt;/b&gt; value to the logical representation as a &lt;b&gt;nvarchar(4000)&lt;/b&gt; data type &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We can represent the HeirarchyID type in a string format. This format shows clearly information carried by this type. Indeed, string representation is formatted as is:/&amp;lt;index level 1&amp;gt;/&amp;lt;index level 2&amp;gt;/&amp;#8230;/&amp;lt;index level N&amp;gt;. This representation corresponds to atree structure . Note that first child of a node does not have a value of 1 all the time but can have the /1.2/ value. So to play around a bit we first need a table with a column of HeirarchyID type and an index on the hierarchy ID column&lt;/p&gt;

&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; height: 180px; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;CREATE&lt;/span&gt; &lt;span style="color: #0000ff"&gt;TABLE&lt;/span&gt; Organization
(
    EmployeeID heirarchyid &lt;span style="color: #0000ff"&gt;NOT&lt;/span&gt; &lt;span style="color: #0000ff"&gt;NULL&lt;/span&gt;,
    EmployeeName nvarchar(50) &lt;span style="color: #0000ff"&gt;NOT&lt;/span&gt; &lt;span style="color: #0000ff"&gt;NULL&lt;/span&gt;
)

&lt;span style="color: #0000ff"&gt;ALTER&lt;/span&gt; &lt;span style="color: #0000ff"&gt;TABLE&lt;/span&gt; dbo.Organization
&lt;span style="color: #0000ff"&gt;ADD&lt;/span&gt; HierarchyLevel &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; EmployeeID.GetLevel()

&lt;span style="color: #0000ff"&gt;CREATE&lt;/span&gt; &lt;span style="color: #0000ff"&gt;INDEX&lt;/span&gt; IX_Employee
&lt;span style="color: #0000ff"&gt;ON&lt;/span&gt; Organization(HierarchyLevel,EmployeeID);&lt;/pre&gt;

&lt;p&gt;To populate the data table we use the CTE we mentioned earlier to&amp;#160; just modify the SELECT statement like the following &lt;/p&gt;

&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; height: 51px; background-color: #f4f4f4; border-bottom-style: none"&gt;Insert &lt;span style="color: #0000ff"&gt;Into&lt;/span&gt; dbo.Organization(EmployeeId, EmployeeName)
&lt;span style="color: #0000ff"&gt;Select&lt;/span&gt; Node, LastName 
 &lt;span style="color: #0000ff"&gt;From&lt;/span&gt; UpperHierarchy&lt;/pre&gt;

&lt;p&gt;Now Hierarchical data can be queried using the functions &lt;/p&gt;

&lt;p&gt;HeirarchyID data type can be manipulated through a set of functions.&amp;#183; GetAncestor, GetDescendant, GetLevel, GetRoot, ToString, IsDescendant, Parse, Read, Reparent, Write, for details on the functions please refer to the CTP documentation of Katmai but most of them are self explanatory #&lt;/p&gt;

&lt;p&gt;For e.g to see how we use these functions, let us insert a node as the last child of an existing node.To do this we first retrieve the sibling node.&lt;/p&gt;

&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; height: 116px; background-color: #f4f4f4; border-bottom-style: none"&gt;--finding sibling node
&lt;span style="color: #0000ff"&gt;SELECT&lt;/span&gt; @sibling = &lt;span style="color: #0000ff"&gt;Max&lt;/span&gt;(EmployeeID)
&lt;span style="color: #0000ff"&gt;FROM&lt;/span&gt; dbo.Organization
&lt;span style="color: #0000ff"&gt;WHERE&lt;/span&gt; EmployeeId.GetAncestor(1)= @Parent;
--inserting node
INSERT dbo.Organization(EmployeeId, EmployeeName)
&lt;span style="color: #0000ff"&gt;VALUES&lt;/span&gt;(@Parent.GetDescendant(@sibling,&lt;span style="color: #0000ff"&gt;NULL&lt;/span&gt;), @Name)&lt;/pre&gt;

&lt;p&gt;We do not always want to (or can) recover the sibling node to perform insertion. There is perhaps an implied policy to determine node position. For example, let&amp;#8217;s say we have an [order] column which position nodes among its siblings. We can compute node path as string: In this example, since the node @Parent is the root, that will give/&amp;lt;order&amp;gt;/. Thanks to the Parse() function, we can use this value to create the new node.&lt;/p&gt;

&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; height: 62px; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;Declare&lt;/span&gt; @Parent &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; HeirarchyID = HeirarchyID::GetRoot() 
&lt;span style="color: #0000ff"&gt;Declare&lt;/span&gt; @NewPath &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;varchar&lt;/span&gt;(10)= @Parent.ToString()+ &lt;span style="color: #0000ff"&gt;CAST&lt;/span&gt;([&lt;span style="color: #0000ff"&gt;Order&lt;/span&gt;] &lt;span style="color: #0000ff"&gt;AS&lt;/span&gt; &lt;span style="color: #0000ff"&gt;varchar&lt;/span&gt;(3))+ &lt;span style="color: #006080"&gt;'/'&lt;/span&gt;
INSERT dbo.Organization(EmployeeId, EmployeeName) &lt;span style="color: #0000ff"&gt;VALUES&lt;/span&gt;(HierarchyId::Parse(@NewPath),&lt;span style="color: #006080"&gt;'aChild'&lt;/span&gt;)&lt;/pre&gt;

&lt;p&gt;You will have note the new syntax of SQL Server 2008 to declare and assign variables in only one line. :: denotes a static method on a SQL CLR type in TSQL. So what am i getting to finally the CTE is not so much of a beauty anymore, just run this query to see what it returns&lt;/p&gt;

&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;Select&lt;/span&gt; *
&lt;span style="color: #0000ff"&gt;From&lt;/span&gt; dbo.Organization
&lt;span style="color: #0000ff"&gt;Where&lt;/span&gt; @BossNode.IsDescendant(EmployeeId)&lt;/pre&gt;

&lt;p&gt;If&amp;#160; you run this query along side the CTE query and compare the execution plan of these queries you would see why this new feature is being talked about :)&lt;/p&gt;

&lt;p&gt;&lt;iframe style="border-right: #dde5e9 1px solid; padding-right: 0px; border-top: #dde5e9 1px solid; padding-left: 0px; padding-bottom: 0px; margin: 3px; border-left: #dde5e9 1px solid; width: 240px; padding-top: 0px; border-bottom: #dde5e9 1px solid; height: 26px; background-color: #ffffff" marginwidth="0" marginheight="0" src="http://cid-2cd165f70c749840.skydrive.live.com/embedrow.aspx/sql%202008/Heirarchy.zip" frameborder="0" scrolling="no"&gt;&lt;/iframe&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4003504748921453462-114690204667822703?l=www.agiledrivendevelopment.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.agiledrivendevelopment.net/feeds/114690204667822703/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4003504748921453462&amp;postID=114690204667822703' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/114690204667822703'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/114690204667822703'/><link rel='alternate' type='text/html' href='http://www.agiledrivendevelopment.net/2008/05/storing-hierarchical-data-heirarchyid.html' title='Storing Hierarchical Data - HeirarchyID'/><author><name>Log4Agile</name><uri>http://www.blogger.com/profile/04640347817726894882</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4003504748921453462.post-7993753256107374701</id><published>2008-05-19T10:22:00.001+01:00</published><updated>2008-05-19T10:22:36.747+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server 2005'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server'/><title type='text'>SQL Profiler for 2005 Express Edition</title><content type='html'>&lt;p&gt;I was trying to see how i can profile SQL 2005 Express Edition as the management studio does not have a profiler. I found one at the following location though , it is very useful and quite a light weight tool &lt;a href="http://code.google.com/p/sqlexpressprofiler/downloads/list" target="_blank"&gt;http://code.google.com/p/sqlexpressprofiler/downloads/list&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4003504748921453462-7993753256107374701?l=www.agiledrivendevelopment.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.agiledrivendevelopment.net/feeds/7993753256107374701/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4003504748921453462&amp;postID=7993753256107374701' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/7993753256107374701'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/7993753256107374701'/><link rel='alternate' type='text/html' href='http://www.agiledrivendevelopment.net/2008/05/sql-profiler-for-2005-express-edition.html' title='SQL Profiler for 2005 Express Edition'/><author><name>Log4Agile</name><uri>http://www.blogger.com/profile/04640347817726894882</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4003504748921453462.post-5118981175027184620</id><published>2008-05-16T09:17:00.001+01:00</published><updated>2008-05-16T09:17:56.663+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='T-SQL'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server 2008 - Katmai'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server'/><category scheme='http://www.blogger.com/atom/ns#' term='Katmai'/><title type='text'>NEW INSERT STATEMENT</title><content type='html'>&lt;p&gt;In SQL 2008 some new row value constructors have been added, we are familiar with the INSERT statement which has been around for ages the ANSI way&lt;/p&gt;  &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;INSERT &lt;span style="color: #0000ff"&gt;INTO&lt;/span&gt; Table1 (column1 ,column2 ,... columnN) &lt;span style="color: #0000ff"&gt;VALUES&lt;/span&gt; (value1,value2,....valueN)&lt;/pre&gt;

&lt;p&gt;Another way of inserting a single row of data is as follows&lt;/p&gt;

&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;INSERT &lt;span style="color: #0000ff"&gt;INTO&lt;/span&gt; Table1 &lt;span style="color: #0000ff"&gt;SELECT&lt;/span&gt; value1,value2,....valueN&lt;/pre&gt;

&lt;p&gt;Similarly for multiple rows of data&lt;/p&gt;

&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;INSERT &lt;span style="color: #0000ff"&gt;INTO&lt;/span&gt; Table1 
&lt;span style="color: #0000ff"&gt;SELECT&lt;/span&gt; value1,value2,....valueN
&lt;span style="color: #0000ff"&gt;UNION&lt;/span&gt; &lt;span style="color: #0000ff"&gt;SELECT&lt;/span&gt; value1,value2,....valueN
&lt;span style="color: #0000ff"&gt;UNION&lt;/span&gt; &lt;span style="color: #0000ff"&gt;SELECT&lt;/span&gt; value1,value2,....valueN&lt;/pre&gt;

&lt;p&gt;Now the new ROW VALUE CONSTRUCTOR allows the following to add multiple rows of data&lt;/p&gt;

&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;INSERT &lt;span style="color: #0000ff"&gt;INTO&lt;/span&gt; Table1(column1 ,column2 ,... columnN) &lt;span style="color: #0000ff"&gt;VALUES&lt;/span&gt;
(value1 , value2 , ... valueN),
(value1 , value2 , ... valueN),
(value1 , value2 , ... valueN),
(value1 , value2 , ... valueN),
(value1 , value2 , ... valueN),&lt;/pre&gt;

&lt;p&gt;We normally use INSERT statements in stored procedures using parameters to the stored procedure, so the above row value constructor is not very useful , it seems to be use of a table valued parameter to insert multiple rows of data is a better option in SQL Server 2008&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4003504748921453462-5118981175027184620?l=www.agiledrivendevelopment.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.agiledrivendevelopment.net/feeds/5118981175027184620/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4003504748921453462&amp;postID=5118981175027184620' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/5118981175027184620'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/5118981175027184620'/><link rel='alternate' type='text/html' href='http://www.agiledrivendevelopment.net/2008/05/new-insert-statement.html' title='NEW INSERT STATEMENT'/><author><name>Log4Agile</name><uri>http://www.blogger.com/profile/04640347817726894882</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4003504748921453462.post-3281968845346717731</id><published>2008-05-16T00:07:00.001+01:00</published><updated>2008-05-16T00:15:50.558+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Software'/><category scheme='http://www.blogger.com/atom/ns#' term='Database'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server 2008 - Katmai'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server'/><category scheme='http://www.blogger.com/atom/ns#' term='Katmai'/><title type='text'>Databases and Software Development</title><content type='html'>&lt;p&gt;&lt;font face="v" size="2"&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="v" size="2"&gt;Database is a form of software development and yet all too often the database is thought of as a secondary entity when development teams discuss architecture and test plans&amp;#8212;many developers do not seem to believe, understand or leave alone feel the need to understand that standard software development best practices apply to database development. Virtually every application imaginable requires some form of data store. And many in the development community go beyond simply persisting data, creating applications that are data driven. Given this dependency upon data and databases, Data is the central factor that dictates the value any application can bring to its users. Without the data, there is no need for the application. &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="v" size="2"&gt;The very reason we use the word legacy to refer to an application as old as 3 years is more often than not because of the database. As applications grow in size with new features , the amount of thought put into refactoring front end code or developing new code by developers is not put into the database development, ,so what happens essentially is a situation where your front end is two years ahead of the database , and as time progresses your applications capabilities and features get pulled back by the limitations of database quality and standard. We can all deny this but in reality it results either in a limitation or extra cost on creating work arounds.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="v" size="2"&gt;The central argument on many a database forum is what to do with that ever-present required logic. Sadly, try as we might, developers have still not figured out how to develop an application without the need to implement business requirements. And so the debate rages on. Does &amp;#8220;business logic&amp;#8221; belong in the database? In the application tier? What about the user interface? And what impact do newer application architectures have on this age-old question?In recent times I have been able to have a look at technologies like Astoria, Linq and the Entity Model framework and Katmai. I was amazed at how little or no database code needs to be written by a developer who is doing UI or business layer development in a software. At the same time being a SQL Server fan myself.. I was worried that my database skills will slowly vaporise into thin air. Hmm that's not as bad as it sounds. All these new technologies such as Astoria, Linq or the Entity Framework are abstractions of the database and allow developing a logical data layer which maps to a physical database , so all developers who work primarily in the UI level or business layer level will slowly stop doing any SQL code at all, instead churning code that interests them against a logical data layer, but what contradicts this is the need to learn a new syntax in the form Linq, . On the other hand, database development will shift to being the specialist job...the design development and management activities of the database developer and Administrator will begin emerging as specialist skills as opposed to generalist skills in the near future. The future of the database specialist seems to be bright.. but what is to be seen is how organisations look at this shift in software development ideology.. To be fair this model of specialist and generalists is not new.. &lt;/font&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4003504748921453462-3281968845346717731?l=www.agiledrivendevelopment.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.agiledrivendevelopment.net/feeds/3281968845346717731/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4003504748921453462&amp;postID=3281968845346717731' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/3281968845346717731'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/3281968845346717731'/><link rel='alternate' type='text/html' href='http://www.agiledrivendevelopment.net/2008/05/databases-and-software-development.html' title='Databases and Software Development'/><author><name>Log4Agile</name><uri>http://www.blogger.com/profile/04640347817726894882</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4003504748921453462.post-5067320306078637939</id><published>2008-05-15T22:53:00.001+01:00</published><updated>2008-05-20T17:50:49.885+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ASP'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>How to consume a .Net ArrayList in classic ASP</title><content type='html'>&lt;div&gt;   &lt;p style="margin: 0cm 0cm 0pt"&gt;&lt;span lang="EN-GB"&gt;&lt;font color="#000000" size="2"&gt;I first followed the procedure to register a .Net assembly using regasm on the web server as below (&lt;/font&gt;&lt;a href="http://weblogs.asp.net/dneimke/archive/2004/01/31/65330.aspx"&gt;&lt;u&gt;&lt;font color="#800080" size="2"&gt;http://weblogs.asp.net/dneimke/archive/2004/01/31/65330.aspx&lt;/font&gt;&lt;/u&gt;&lt;/a&gt;&lt;font size="2"&gt;&lt;font color="#000000"&gt;)&lt;/font&gt;&lt;/font&gt;&lt;/span&gt; &lt;/p&gt;    &lt;ol style="margin-top: 0cm"&gt;     &lt;li style="margin: 0cm 0cm 0pt; tab-stops: list 36.0pt"&gt;&lt;span lang="EN-GB"&gt;&lt;font size="2"&gt;&lt;font color="#000000"&gt;Make sure your assembly has a strong name to install it in the GAC&lt;/font&gt;&lt;/font&gt;&lt;/span&gt; &lt;/li&gt;      &lt;li style="margin: 0cm 0cm 0pt; tab-stops: list 36.0pt"&gt;&lt;span lang="EN-GB"&gt;&lt;font size="2"&gt;&lt;font color="#000000"&gt;Run regasm /tlb &amp;#8220;&amp;lt;path of your assembly&amp;gt;&amp;#8221;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt; &lt;/li&gt;      &lt;li style="margin: 0cm 0cm 0pt; tab-stops: list 36.0pt"&gt;&lt;span lang="EN-GB"&gt;&lt;font size="2"&gt;&lt;font color="#000000"&gt;Add the assembly to the GAC&lt;/font&gt;&lt;/font&gt;&lt;/span&gt; &lt;/li&gt;   &lt;/ol&gt;    &lt;p style="margin: 0cm 0cm 0pt"&gt;&lt;span lang="EN-GB"&gt;&lt;font size="2"&gt;&lt;font color="#000000"&gt;This allows your assembly to be accessible in your ASP code to create server side objects&lt;/font&gt;&lt;/font&gt;&lt;/span&gt; &lt;/p&gt;    &lt;p style="margin: 0cm 0cm 0pt"&gt;&lt;span lang="EN-GB"&gt;&lt;font size="2"&gt;&lt;font color="#000000"&gt;In my example I have a .Net assembly which has a class as below&lt;/font&gt;&lt;/font&gt;&lt;/span&gt; &lt;/p&gt;    &lt;p style="margin: 0cm 0cm 0pt"&gt;&lt;span lang="EN-GB"&gt;&lt;font color="#000000" size="2"&gt;&amp;#160;&lt;/font&gt;&lt;/span&gt; &lt;/p&gt;    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System; 
&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.Collections; 
&lt;span style="color: #0000ff"&gt;namespace&lt;/span&gt; API 
{ 
      &lt;span style="color: #008000"&gt;/// &amp;lt;summary&amp;gt; &lt;/span&gt;
      &lt;span style="color: #008000"&gt;/// Summary description for Versions. &lt;/span&gt;
      &lt;span style="color: #008000"&gt;/// &amp;lt;/summary&amp;gt; &lt;/span&gt;
      &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; Versions 
      { 
            ArrayList versions = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ArrayList();
            &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; Versions() 
            { 
                  versions.Add(&amp;#8220;1&amp;#8221;); 
                  versions.Add(&amp;#8220;2&amp;#8221;); 
                  versions.Add(&amp;#8220;3&amp;#8221;); 
            } 

            &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; ArrayList List
            { 
                  get 
                  { 
                        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; versions; 
                  } 
            } 
      } 
} &lt;/pre&gt;

  &lt;p style="margin: 0cm 0cm 0pt"&gt;&lt;span lang="EN-GB"&gt;&lt;font size="2"&gt;&lt;font color="#000000"&gt;I initially tried to have a method in my .Net class return an ArrayList, Then I tried to create an object of type &amp;#8220;System.Collections.ArrayList&amp;#8221; in ASP and iterate the object in ASP, as the array list type definition was not supported when the asp code executed. So I created the class above which had a public property having a type of System.Collections.ArrayList&lt;/font&gt;&lt;/font&gt;&lt;/span&gt; &lt;/p&gt;

  &lt;p style="margin: 0cm 0cm 0pt"&gt;&lt;span lang="EN-GB"&gt;&lt;font color="#000000" size="2"&gt;&amp;#160;&lt;/font&gt;&lt;/span&gt; &lt;/p&gt;

  &lt;p style="margin: 0cm 0cm 0pt"&gt;&lt;span lang="EN-GB"&gt;&lt;font size="2"&gt;&lt;font color="#000000"&gt;So now in ASP I did the following and it printed out the arrray list on my asp page&lt;/font&gt;&lt;/font&gt;&lt;/span&gt; &lt;/p&gt;

  &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="background-color: #ffff00"&gt;&amp;lt;%@ codePage=&amp;quot;65001&amp;quot; %&amp;gt;&lt;/span&gt; 
&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;html&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; 
      &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;head&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; 
            &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;title&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Test Page&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;title&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; 
            &lt;span style="background-color: #ffff00"&gt;&amp;lt;%&lt;/span&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   1:&lt;/span&gt;  &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   2:&lt;/span&gt;                   set versions = Server.CreateObject(&lt;span style="color: #006080"&gt;&amp;quot;Versions&amp;quot;&lt;/span&gt;) &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   3:&lt;/span&gt;                   For Each v &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; versions.List &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   4:&lt;/span&gt;                         Response.Write(v &amp;amp; &lt;span style="color: #006080"&gt;&amp;quot;&amp;lt;/br&amp;gt;&amp;quot;&lt;/span&gt;) &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   5:&lt;/span&gt;                   Next &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   6:&lt;/span&gt;             &lt;/pre&gt;&lt;span style="background-color: #ffff00"&gt;%&amp;gt;&lt;/span&gt; 
      &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;head&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; 
      &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;body&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;body&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; 
&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;html&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; 

  &lt;/pre&gt;

  &lt;p style="margin: 0cm 0cm 0pt"&gt;&lt;span lang="EN-GB"&gt;&lt;font color="#000000" size="2"&gt;That can be further enhanced in your ASP code to achieve the functionality you need to &lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

  &lt;p style="margin: 0cm 0cm 0pt"&gt;&lt;span lang="EN-GB"&gt;&lt;font size="2"&gt;&lt;font color="#000080"&gt;&lt;font face="Courier New"&gt;&lt;font size="+0"&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&amp;#160; &lt;/p&gt;

  &lt;p style="margin: 0cm 0cm 0pt"&gt;&lt;span lang="EN-GB"&gt;&lt;font size="2"&gt;&lt;font color="#000080"&gt;&lt;font face="Courier New"&gt;&lt;font size="+0"&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;/p&gt;
&lt;/div&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4003504748921453462-5067320306078637939?l=www.agiledrivendevelopment.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.agiledrivendevelopment.net/feeds/5067320306078637939/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4003504748921453462&amp;postID=5067320306078637939' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/5067320306078637939'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/5067320306078637939'/><link rel='alternate' type='text/html' href='http://www.agiledrivendevelopment.net/2008/05/how-to-consume-net-arraylist-in-classic_15.html' title='How to consume a .Net ArrayList in classic ASP'/><author><name>Log4Agile</name><uri>http://www.blogger.com/profile/04640347817726894882</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4003504748921453462.post-5701271694089258629</id><published>2008-05-15T22:52:00.001+01:00</published><updated>2008-05-15T22:52:09.428+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='T-SQL'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server 2005'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server 2000'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server 2008 - Katmai'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server'/><category scheme='http://www.blogger.com/atom/ns#' term='Katmai'/><title type='text'>TSQL - GROUP BY and ALL</title><content type='html'>&lt;p&gt;   &lt;br /&gt;We sure have used Group By in our SQL queries to group data and get result sets with aggregates from SQL Server, But before I explain lets create a temporary table with order details table using the Northwind database in SQL 2000&lt;/p&gt;  &lt;p&gt;I will just join orders and [order detail] table in Northwind to get the data i need into a temporary table as shown below&lt;/p&gt;  &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; height: 281px; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;SELECT&lt;/span&gt; 
  O.OrderID, 
  ProductID, 
  UnitPrice, 
  Quantity, 
  (UnitPrice*Quantity) &lt;span style="color: #0000ff"&gt;AS&lt;/span&gt; Amount,
  CustomerID
&lt;span style="color: #0000ff"&gt;INTO&lt;/span&gt; 
  #tempOrders
&lt;span style="color: #0000ff"&gt;FROM&lt;/span&gt; 
  Orders O 
&lt;span style="color: #0000ff"&gt;INNER&lt;/span&gt; &lt;span style="color: #0000ff"&gt;JOIN&lt;/span&gt;
  [&lt;span style="color: #0000ff"&gt;order&lt;/span&gt; details] D 
&lt;span style="color: #0000ff"&gt;ON&lt;/span&gt;
  O.[orderid] = D.[orderid]
&lt;span style="color: #0000ff"&gt;ORDER&lt;/span&gt; &lt;span style="color: #0000ff"&gt;BY&lt;/span&gt;
  ProductID&lt;/pre&gt;

&lt;p&gt;So now i have a table called #tempOrders with the order details i need.&lt;/p&gt;

&lt;p&gt;Now suppose I'd like to see the customers that were sold Product #1 along with the total amount that they spent. I will usea query with a GROUP BY clause as below with a WHERE condition to filter records&lt;/p&gt;

&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;SELECT&lt;/span&gt; 
   CustomerID,
   &lt;span style="color: #0000ff"&gt;SUM&lt;/span&gt;(Amount) &lt;span style="color: #0000ff"&gt;AS&lt;/span&gt; TotalAmount
 &lt;span style="color: #0000ff"&gt;FROM&lt;/span&gt;
   #tempOrders
 &lt;span style="color: #0000ff"&gt;WHERE&lt;/span&gt; 
   ProductID = 1
 &lt;span style="color: #0000ff"&gt;GROUP&lt;/span&gt; &lt;span style="color: #0000ff"&gt;BY&lt;/span&gt; 
   CustomerID&lt;/pre&gt;

&lt;p&gt;
  &lt;br /&gt;Now, let's say that I'd like to see &lt;span style="font-style: italic"&gt;all &lt;/span&gt;customers that have been sold &lt;span style="font-style: italic"&gt;any &lt;/span&gt;products, but we still just want to see the &amp;quot;TotalAmount&amp;quot; for ProductID #1. For customers that have never ordered ProductID #1, it should output a &amp;quot;TotalAmount&amp;quot; value of 0. One way to do this is with a CASE expression as shown below&lt;/p&gt;

&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;SELECT&lt;/span&gt; 
  CustomerID,
  &lt;span style="color: #0000ff"&gt;SUM&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;CASE&lt;/span&gt; &lt;span style="color: #0000ff"&gt;WHEN&lt;/span&gt; ProductID = 1 &lt;span style="color: #0000ff"&gt;THEN&lt;/span&gt; Amount &lt;span style="color: #0000ff"&gt;ELSE&lt;/span&gt; 0 &lt;span style="color: #0000ff"&gt;END&lt;/span&gt;) &lt;span style="color: #0000ff"&gt;AS&lt;/span&gt; TotalAmount
&lt;span style="color: #0000ff"&gt;FROM&lt;/span&gt;
  #tempOrders
&lt;span style="color: #0000ff"&gt;GROUP&lt;/span&gt; &lt;span style="color: #0000ff"&gt;BY&lt;/span&gt; 
  CustomerID&lt;/pre&gt;

&lt;p&gt;Now this would return customers who haven't purchased Product #1 with a total of 0. In situations like these the SUM(CASE...) expression can be replaced with a &lt;strong&gt;GROUP BY ALL.&lt;/strong&gt;&lt;/p&gt;

&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;SELECT&lt;/span&gt; 
    CustomerID,
    ISNULL(&lt;span style="color: #0000ff"&gt;SUM&lt;/span&gt;(Amount), 0) &lt;span style="color: #0000ff"&gt;AS&lt;/span&gt; TotalAmount
  &lt;span style="color: #0000ff"&gt;FROM&lt;/span&gt;
    #tempOrders
  &lt;span style="color: #0000ff"&gt;WHERE&lt;/span&gt; 
    ProductID = 1
  &lt;span style="color: #0000ff"&gt;GROUP&lt;/span&gt; &lt;span style="color: #0000ff"&gt;BY&lt;/span&gt; &lt;span style="color: #0000ff"&gt;ALL&lt;/span&gt; CustomerID&lt;/pre&gt;

&lt;p&gt;&lt;/courier&gt;Values that are excluded from the aggregation according to the WHERE clause have NULL values returned, the ISNULL function makes sure all customers who haven't ordered Product #1 have a total of 0 instead of NULL. The ALL option basically says &amp;quot;ignore the WHERE clause when doing the GROUPING, but still apply it for any aggregate functions&amp;quot;. So, in this case, the WHERE clause is not considered when generating the population of CustomerID values, but it is applied when calculating the SUM. This is very much like our first solution, where we removed the WHERE clause completely, and used a SUM(CASE...) expression to conditionally calculate the aggregate. 
  &lt;br /&gt;

  &lt;br /&gt;GROUP BY ALL is kind of obscure and neat to know, but not really useful in most situations since there are usually easier or better ways to get this result. This won't work if we want all Customers to be displayed, since a customer &lt;span style="font-style: italic"&gt;must have at least one order &lt;/span&gt;to show up in the result.Another limitation is we can not use GROUP BY ALL if we want to return a grand total for all orders &lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4003504748921453462-5701271694089258629?l=www.agiledrivendevelopment.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.agiledrivendevelopment.net/feeds/5701271694089258629/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4003504748921453462&amp;postID=5701271694089258629' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/5701271694089258629'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/5701271694089258629'/><link rel='alternate' type='text/html' href='http://www.agiledrivendevelopment.net/2008/05/tsql-group-by-and-all_15.html' title='TSQL - GROUP BY and ALL'/><author><name>Log4Agile</name><uri>http://www.blogger.com/profile/04640347817726894882</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4003504748921453462.post-7537230924169597882</id><published>2008-05-14T08:52:00.001+01:00</published><updated>2008-05-14T08:54:36.462+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>How to consume a .Net ArrayList in classic ASP</title><content type='html'>&lt;div&gt;   &lt;p style="margin: 0cm 0cm 0pt"&gt;&lt;span lang="EN-GB"&gt;&lt;font color="#000000" size="2"&gt;I first followed the procedure to register a .Net assembly using regasm on the web server as below (&lt;/font&gt;&lt;a href="http://weblogs.asp.net/dneimke/archive/2004/01/31/65330.aspx"&gt;&lt;u&gt;&lt;font color="#800080" size="2"&gt;http://weblogs.asp.net/dneimke/archive/2004/01/31/65330.aspx&lt;/font&gt;&lt;/u&gt;&lt;/a&gt;&lt;font size="2"&gt;&lt;font color="#000000"&gt;)&lt;/font&gt;&lt;/font&gt;&lt;/span&gt; &lt;/p&gt;    &lt;ol style="margin-top: 0cm"&gt;     &lt;li style="margin: 0cm 0cm 0pt; tab-stops: list 36.0pt"&gt;&lt;span lang="EN-GB"&gt;&lt;font size="2"&gt;&lt;font color="#000000"&gt;Make sure your assembly has a strong name to install it in the GAC&lt;/font&gt;&lt;/font&gt;&lt;/span&gt; &lt;/li&gt;      &lt;li style="margin: 0cm 0cm 0pt; tab-stops: list 36.0pt"&gt;&lt;span lang="EN-GB"&gt;&lt;font size="2"&gt;&lt;font color="#000000"&gt;Run regasm /tlb &amp;#8220;&amp;lt;path of your assembly&amp;gt;&amp;#8221;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt; &lt;/li&gt;      &lt;li style="margin: 0cm 0cm 0pt; tab-stops: list 36.0pt"&gt;&lt;span lang="EN-GB"&gt;&lt;font size="2"&gt;&lt;font color="#000000"&gt;Add the assembly to the GAC&lt;/font&gt;&lt;/font&gt;&lt;/span&gt; &lt;/li&gt;   &lt;/ol&gt;    &lt;p style="margin: 0cm 0cm 0pt"&gt;&lt;span lang="EN-GB"&gt;&lt;font size="2"&gt;&lt;font color="#000000"&gt;This allows your assembly to be accessible in your ASP code to create server side objects&lt;/font&gt;&lt;/font&gt;&lt;/span&gt; &lt;/p&gt;    &lt;p style="margin: 0cm 0cm 0pt"&gt;&lt;span lang="EN-GB"&gt;&lt;font size="2"&gt;&lt;font color="#000000"&gt;In my example I have a .Net assembly which has a class as below&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span lang="EN-GB"&gt;&lt;font color="#000000" size="2"&gt;&amp;#160;&lt;/font&gt;&lt;/span&gt; &lt;/p&gt;    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System;                                                     
&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.Collections; 

&lt;span style="color: #0000ff"&gt;namespace&lt;/span&gt; API 
{ 
      &lt;span style="color: #008000"&gt;/// &amp;lt;summary&amp;gt; &lt;/span&gt;
      &lt;span style="color: #008000"&gt;/// Summary description for Versions. &lt;/span&gt;
      &lt;span style="color: #008000"&gt;/// &amp;lt;/summary&amp;gt; &lt;/span&gt;
      &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; Versions 
      { 
            ArrayList versions = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ArrayList(); 

            &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; Versions() 
            { 
                  versions.Add(&amp;#8220;1&amp;#8221;); 
                  versions.Add(&amp;#8220;2&amp;#8221;); 
                  versions.Add(&amp;#8220;3&amp;#8221;); 
            }   

            &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; ArrayList List 
            { 
                  get { &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; versions; } 
            } 
      } 
} &lt;/pre&gt;

  &lt;p style="margin: 0cm 0cm 0pt"&gt;&lt;span lang="EN-GB"&gt;&lt;font size="2"&gt;&lt;font color="#000000"&gt;I initially tried to have a method in my .Net class return an ArrayList, Then I tried to create an object of type &amp;#8220;System.Collections.ArrayList&amp;#8221; in ASP and iterate the object in ASP, as the array list type definition was not supported when the asp code executed. So I created the class above which had a public property having a type of System.Collections.ArrayList&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span lang="EN-GB"&gt;&lt;font color="#000000" size="2"&gt; .&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

  &lt;p style="margin: 0cm 0cm 0pt"&gt;&lt;span lang="EN-GB"&gt;&lt;font size="2"&gt;&lt;font color="#000000"&gt;So now in ASP I did the following and it printed out the arrray list on my asp page&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&amp;#160; &lt;/p&gt;

  &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="background-color: #ffff00"&gt;&amp;lt;%@ codePage=&amp;quot;65001&amp;quot; %&amp;gt;&lt;/span&gt; 
&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;html&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; 
      &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;head&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; 
            &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;title&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Test Page&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;title&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
            &lt;span style="background-color: #ffff00"&gt;&amp;lt;%&lt;/span&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   1:&lt;/span&gt;     set versions = Server.CreateObject(&lt;span style="color: #006080"&gt;&amp;quot;Versions&amp;quot;&lt;/span&gt;) &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   2:&lt;/span&gt;                   For Each v &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; versions.List &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   3:&lt;/span&gt;                         Response.Write(v &amp;amp; &lt;span style="color: #006080"&gt;&amp;quot;&amp;lt;/br&amp;gt;&amp;quot;&lt;/span&gt;)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   4:&lt;/span&gt;                   Next&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   5:&lt;/span&gt;             &lt;/pre&gt;&lt;span style="background-color: #ffff00"&gt;%&amp;gt;&lt;/span&gt; 
      &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;head&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; 
      &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;body&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;body&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; 
&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;html&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;/pre&gt;

  &lt;p style="margin: 0cm 0cm 0pt"&gt;&lt;span lang="EN-GB"&gt;&lt;font color="#000000" size="2"&gt;&lt;/font&gt;&lt;/span&gt;&amp;#160; &lt;span lang="EN-GB"&gt;&lt;font color="#000000" size="2"&gt;That can be further enhanced in your ASP code to achieve the functionality you need to &lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

  &lt;p style="margin: 0cm 0cm 0pt"&gt;&lt;span lang="EN-GB"&gt;&lt;font size="2"&gt;&lt;font color="#000080"&gt;&lt;font face="Courier New"&gt;&lt;font size="+0"&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&amp;#160; &lt;/p&gt;

  &lt;p style="margin: 0cm 0cm 0pt"&gt;&lt;span lang="EN-GB"&gt;&lt;font size="2"&gt;&lt;font color="#000080"&gt;&lt;font face="Courier New"&gt;&lt;font size="+0"&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;/p&gt;
&lt;/div&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4003504748921453462-7537230924169597882?l=www.agiledrivendevelopment.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.agiledrivendevelopment.net/feeds/7537230924169597882/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4003504748921453462&amp;postID=7537230924169597882' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/7537230924169597882'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/7537230924169597882'/><link rel='alternate' type='text/html' href='http://www.agiledrivendevelopment.net/2008/05/how-to-consume-net-arraylist-in-classic.html' title='How to consume a .Net ArrayList in classic ASP'/><author><name>Log4Agile</name><uri>http://www.blogger.com/profile/04640347817726894882</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4003504748921453462.post-5226740139858815013</id><published>2008-05-13T11:06:00.001+01:00</published><updated>2008-05-15T22:54:33.574+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='T-SQL'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server 2005'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server 2008 - Katmai'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server'/><category scheme='http://www.blogger.com/atom/ns#' term='Katmai'/><title type='text'>PIVOT and UNPIVOT</title><content type='html'>&lt;p&gt;There may be situations while writing SQL code where we would like to have totals or aggregates of columns alongside a column, e.g number of points scored by a sales person with their sales, as well as separate sales by month or year.&lt;/p&gt;  &lt;p&gt;So lets first create a table which represents sales data as below&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" color="#0000ff"&gt;CREATE TABLE #tempTest      &lt;br /&gt;(       &lt;br /&gt;&amp;#160; empName VARCHAR(25),       &lt;br /&gt;&amp;#160; noOfSales INT,       &lt;br /&gt;&amp;#160; [monthName] VARCHAR(3),       &lt;br /&gt;&amp;#160; Points INT       &lt;br /&gt;) &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;Just add a few rows of data to this table&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" color="#0000ff"&gt;INSERT INTO #tempTest VALUES('James',2,'Jan', 2);      &lt;br /&gt;INSERT INTO #tempTest VALUES('Jason',1,'Jan', 1);       &lt;br /&gt;INSERT INTO #tempTest VALUES('Mark',3,'Jan', 3);       &lt;br /&gt;INSERT INTO #tempTest VALUES('Mark',1,'Jan', 1);       &lt;br /&gt;INSERT INTO #tempTest VALUES('James',1,'Feb', 1);       &lt;br /&gt;INSERT INTO #tempTest VALUES('James',2,'Feb', 2);       &lt;br /&gt;INSERT INTO #tempTest VALUES('Jason',3,'Feb', 3);       &lt;br /&gt;INSERT INTO #tempTest VALUES('Jason',2,'Feb', 2);       &lt;br /&gt;INSERT INTO #tempTest VALUES('Mark',1,'Mar', 1);       &lt;br /&gt;INSERT INTO #tempTest VALUES('James',2,'Mar', 2);       &lt;br /&gt;INSERT INTO #tempTest VALUES('Jason',2,'Mar', 2);&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;Now to show how many sales each sales person gets per month we could use PIVOT to achieve this easily&lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;&lt;font face="Courier New" color="#0000ff"&gt;SELECT      &lt;br /&gt;&amp;#160; empName,       &lt;br /&gt;&amp;#160; [Jan] AS Total_Sales_Jan,       &lt;br /&gt;&amp;#160; [Feb] AS Total_Sales_Feb,       &lt;br /&gt;&amp;#160; [Mar] AS Total_Sales_Mar       &lt;br /&gt;FROM       &lt;br /&gt;&amp;#160; (       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; SELECT       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; empName, noOfSales, [monthName]       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; FROM       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; #tempTest       &lt;br /&gt;&amp;#160; ) AS Source PIVOT (SUM(noOfSales) for [monthName] IN ([Jan],[Feb],[Mar]) )AS PivotTable&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;This query results in the following result &lt;/p&gt;  &lt;p&gt;&lt;a href="http://cid-2cd165f70c749840.skydrive.live.com/self.aspx/Public/PIVOT1.png"&gt;Results Pivot 1&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Please note that PIVOT can have only one non pivoted column, Example below shows how PIVOT can be used incorrectly &lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" color="#0000ff"&gt;SELECT      &lt;br /&gt;&amp;#160; empName,       &lt;br /&gt;&amp;#160; SUM([Jan]) AS Jan,       &lt;br /&gt;&amp;#160; SUM([Feb]) AS Feb,       &lt;br /&gt;&amp;#160; SUM([Mar]) AS Mar,       &lt;br /&gt;&amp;#160; SUM(Points) AS Points       &lt;br /&gt;FROM       &lt;br /&gt;&amp;#160; (       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; SELECT       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; empName,       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; noOfSales,       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; [monthName],       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Points       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; FROM       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; #tempTest       &lt;br /&gt;&amp;#160; ) AS Source PIVOT (SUM(noOfSales) for [monthName] IN ([Jan],[Feb],[Mar]) )AS PivotTable       &lt;br /&gt;GROUP BY       &lt;br /&gt;&amp;#160; empName&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://cid-2cd165f70c749840.skydrive.live.com/self.aspx/Public/PIVOT2.png"&gt;Results Pivot 2&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Note that the results are incorrect for Points, they dont sum up correctly for each sales person as expected, this is because you cannot use more than one unpivoted column&lt;/p&gt;  &lt;p&gt;UNPIVOT is the exact opposite of PIVOT although the usage of it is likely to be minimal there are chances this may be used in some occassions&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4003504748921453462-5226740139858815013?l=www.agiledrivendevelopment.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.agiledrivendevelopment.net/feeds/5226740139858815013/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4003504748921453462&amp;postID=5226740139858815013' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/5226740139858815013'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/5226740139858815013'/><link rel='alternate' type='text/html' href='http://www.agiledrivendevelopment.net/2008/05/pivot-and-unpivot.html' title='PIVOT and UNPIVOT'/><author><name>Log4Agile</name><uri>http://www.blogger.com/profile/04640347817726894882</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4003504748921453462.post-4911087159543434467</id><published>2008-05-09T10:34:00.001+01:00</published><updated>2008-05-09T10:34:45.499+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server'/><title type='text'>Deleting Duplicates using CTE's</title><content type='html'>&lt;p&gt;While writing stored procedures and dealing with temporary data within the scope of a stored procedure we come across a situation where our temporary data has duplicate records and we want to get rid of duplicated. What we do normally in SQL 2000 would be to create a new temporary table and select distinct records from the temporary table which has duplicates. Then we select the data from the new cleaned up table. &lt;/p&gt;  &lt;p&gt;This is not very performant as is evident, SQL 2005 onwards we have been able to do this with CTE's efficiently as below &lt;/p&gt;  &lt;p&gt;Deleting from the CTE actually changes the underlying table. Be careful how you setup your CTE. You could have some unintended deletes without the right logic. &lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" color="#0000ff"&gt;CREATE TABLE #itemtable(      &lt;br /&gt;&amp;#160; Item_Code varchar(10),       &lt;br /&gt;&amp;#160; Item_Name varchar(100)       &lt;br /&gt;) &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" color="#0000ff"&gt;&amp;#160; INSERT INTO #itemtable(Item_Code, Item_Name)      &lt;br /&gt;&amp;#160; VALUES ('1','Item 1'); &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" color="#0000ff"&gt;&amp;#160; INSERT INTO #itemtable(Item_Code, Item_Name)      &lt;br /&gt;&amp;#160; VALUES ('2','Item 2');       &lt;br /&gt;&amp;#160; INSERT INTO #itemtable(Item_Code, Item_Name)       &lt;br /&gt;&amp;#160; VALUES ('3','Item 3'); &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" color="#0000ff"&gt;&amp;#160; INSERT INTO #itemtable(Item_Code, Item_Name)      &lt;br /&gt;&amp;#160; VALUES ('3','Item 3'); &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" color="#0000ff"&gt;&amp;#160; INSERT INTO #itemtable(Item_Code, Item_Name)      &lt;br /&gt;&amp;#160; VALUES ('4','Item 4'); &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" color="#0000ff"&gt;&amp;#160; INSERT INTO #itemtable(Item_Code, Item_Name)      &lt;br /&gt;&amp;#160; VALUES ('5','Item 5'); &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" color="#0000ff"&gt;&amp;#160; INSERT INTO #itemtable(Item_Code, Item_Name)      &lt;br /&gt;&amp;#160; VALUES ('6','Item 6'); &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" color="#0000ff"&gt;&amp;#160; INSERT INTO #itemtable(Item_Code, Item_Name)      &lt;br /&gt;&amp;#160; VALUES ('6','Item 6'); &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" color="#0000ff"&gt;&amp;#160; INSERT INTO #itemtable(Item_Code, Item_Name)      &lt;br /&gt;&amp;#160; VALUES ('7','Item 7'); &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" color="#0000ff"&gt;GO &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" color="#0000ff"&gt;&amp;#160; SELECT * FROM #itemtable; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" color="#0000ff"&gt;&amp;#160; WITH Duplicates AS      &lt;br /&gt;&amp;#160; (       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; SELECT       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; *,       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; row_number() OVER(PARTITION BY Item_Code ORDER BY Item_Code) as RowNum       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; FROM       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; #itemtable       &lt;br /&gt;&amp;#160; ) &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" color="#0000ff"&gt;&amp;#160; DELETE FROM Duplicates WHERE RowNum &amp;gt; 1; -- &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" color="#0000ff"&gt;SELECT * FROM #itemtable; &lt;/font&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4003504748921453462-4911087159543434467?l=www.agiledrivendevelopment.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.agiledrivendevelopment.net/feeds/4911087159543434467/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4003504748921453462&amp;postID=4911087159543434467' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/4911087159543434467'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/4911087159543434467'/><link rel='alternate' type='text/html' href='http://www.agiledrivendevelopment.net/2008/05/deleting-duplicates-using-cte_09.html' title='Deleting Duplicates using CTE&amp;#39;s'/><author><name>Log4Agile</name><uri>http://www.blogger.com/profile/04640347817726894882</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4003504748921453462.post-5957882599087618960</id><published>2008-05-07T16:07:00.002+01:00</published><updated>2008-05-15T23:00:58.486+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='T-SQL'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server 2008 - Katmai'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server'/><category scheme='http://www.blogger.com/atom/ns#' term='Katmai'/><title type='text'>Table Valued Parameters</title><content type='html'>In recent times I haven&amp;#8217;t written any complex TSQL code which needed to scale, possible a scenario you may come across while working on a reporting application where most of the processing is done on the database server using TSQL. In SQL 2005 user defined types were available but in Katmai this has been furthered to allow table valued parameters to be passed to stored procedures. Well we can also think of them as instances of user defined types. At the end of the day it boils down to being able to efficient and more performant code , but then this feature seems to have a limitation at the moment.  &lt;br /&gt;  &lt;br /&gt;The table data type allows variables that are, in effect, tables. They also allow you to return tabular data from functions without doing a SELECT at the end of the function. That's great, but don't temporary tables do the same? Yes and No &amp;#8230;. While table variables and temporary tables are similar, there are several key differences that determine which option you use.  &lt;br /&gt;E.g. Consider the sample below in SQL 2005 to add orders to the database table using TSQL, I will need a stored procedure which takes each column in a row as a parameter, and more over each row needs a round trip to the database server..  &lt;br /&gt;  &lt;br /&gt;&lt;span style="font-size: 85%; color: #3366ff; font-family: courier new"&gt;CREATE PROC sp_add_order(@order_id int, @customer_id int, @order_total money )   &lt;br /&gt;AS    &lt;br /&gt;INSERT INTO Order    &lt;br /&gt;(    &lt;br /&gt;order_id,    &lt;br /&gt;customer_id,    &lt;br /&gt;order_total    &lt;br /&gt;)    &lt;br /&gt;VALUES    &lt;br /&gt;(    &lt;br /&gt;@order_id,    &lt;br /&gt;@customer_id,    &lt;br /&gt;@order_total    &lt;br /&gt;)    &lt;br /&gt;GO    &lt;br /&gt;&lt;/span&gt;  &lt;br /&gt;Now with SQL 2008 we are able to insert several rows of data with just one round trip to the server by using a user defined type called OrderType which has a table structure. That is efficient and quite performant&amp;#8230;  &lt;br /&gt;  &lt;br /&gt;&lt;span style="font-size: 85%; color: #3366ff; font-family: courier new"&gt;CREATE TYPE OrderType AS TABLE   &lt;br /&gt;(    &lt;br /&gt;[order_id] int NOT NULL,    &lt;br /&gt;customer_id int NOT NULL,    &lt;br /&gt;[OrderTotal] [money] NULL    &lt;br /&gt;)    &lt;br /&gt;GO    &lt;br /&gt;    &lt;br /&gt;ALTER PROC sp_new_order (@order OrderType READONLY)    &lt;br /&gt;AS    &lt;br /&gt;INSERT INTO [OrderTest]    &lt;br /&gt;(    &lt;br /&gt;order_id,    &lt;br /&gt;customer_id,    &lt;br /&gt;[OrderTotal]    &lt;br /&gt;)    &lt;br /&gt;SELECT * FROM @order     &lt;br /&gt;    &lt;br /&gt;RETURN    &lt;br /&gt;GO    &lt;br /&gt;&lt;/span&gt;  &lt;br /&gt;The one limitation to note here is the READONLY option on the parameter, At the moment the CTP only allows us to pass read-only table valued parameters, We are unable to use OUT parameters of Table Value Type, It would be great to be able to do this, as we don&amp;#8217;t have to make nested calls to stored procedures in reporting scenarios&amp;#8230; It is to be seen how this pans out in the final release, although the feature doesn&amp;#8217;t look big, the sheer benefits of being able to use Table Valued Parameters comes as blessing in disguise for many TSQL developers.  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4003504748921453462-5957882599087618960?l=www.agiledrivendevelopment.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.agiledrivendevelopment.net/feeds/5957882599087618960/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4003504748921453462&amp;postID=5957882599087618960' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/5957882599087618960'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/5957882599087618960'/><link rel='alternate' type='text/html' href='http://www.agiledrivendevelopment.net/2008/05/table-valued-parameters.html' title='Table Valued Parameters'/><author><name>Log4Agile</name><uri>http://www.blogger.com/profile/04640347817726894882</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4003504748921453462.post-2336923960063230187</id><published>2008-05-06T23:45:00.002+01:00</published><updated>2008-05-15T22:59:37.581+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='T-SQL'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server 2008 - Katmai'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server'/><category scheme='http://www.blogger.com/atom/ns#' term='Katmai'/><title type='text'>Spatial Data - Delivering Location based Intelligence</title><content type='html'>&lt;div align="left"&gt;&lt;span style="font-size: 85%; font-family: verdana"&gt;     &lt;br /&gt;I have been on and off blogging recently due to my part time course at the Uni which has kept me busy.. By the way I did look through most of the new features on Katmai and actually did a small lunch time session at work on Katmai, one of the topics I did speak in details was spatial data support on Katmai.      &lt;br /&gt;      &lt;br /&gt;SQL Server 2008 provides the geography (for geodetic spatial data) and the geometry(for planar spatial data) data types. Both are .NET CLR types, just like your Hierarchy data type which I will post about in another blog soon. The presence of the CLR in SQL Server provides an avenue for some really new and exciting features in SQL Server. When the CLR was introduced on the Server in Yukon I did think it is a bit too much to be present in a database server, but then now that some of the new features in Katmai have panned out as a result of that it does all seem to make sense now.      &lt;br /&gt;      &lt;br /&gt;The geography data type provides a storage structure for spatial data which is ellipsoidal in nature, and is represented by latitude and longitude coordinates. Typical uses of this kind of data include defining roads, buildings, or geographical features as vector data that can be overlaid onto a raster-based map, basically any round earth data.      &lt;br /&gt;      &lt;br /&gt;The geometry data type provides a storage structure for spatial data which is planar or in other words Euclidean in nature. This kind of data is commonly used for maps and interior floor plans where the curvature of the Earth does not need to be taken into account.      &lt;br /&gt;      &lt;br /&gt;To create data that is of the type geometry or geography we could create instances using input in the format called Well Known Text (WKT) or Well Known Binary(WKB). Well WKB is the format specified by the Open Geospatial Consortium that permits the geometry data to be exchanged between the client and the SQL server. The geometry data type provides properties and methods that are aligned with the Open Geospatial Consortium (OGC) Simple Features Specification for SQL and enable you to perform operations on geometric data that produce industry-standard behavior.      &lt;br /&gt;      &lt;br /&gt;SQL Server 2008 increases the maximum size for CLR types in the database from the 8000 bytes limit that was imposed in SQL Server 2005 to two gigabytes (2 GB), which makes it possible to store extremely complex spatial data elements, such as polygons, which are defined by a large number of points. By storing spatial data in relational tables, SQL Server 2008 makes it possible to combine spatial data with any other kind of business data; this removes the need to maintain a separate, dedicated spatial data store and enables high performance queries that do not need to combine data from multiple external sources. Performance of queries against spatial data is further enhanced by the inclusion of spatial index support in SQL Server 2008.      &lt;br /&gt;      &lt;br /&gt;Both spatial data types in SQL Server 2008 provide a comprehensive set of instance and static methods that you can use to perform queries and operations on spatial data. If we explore these two data types we find that Point, MultiPoint, LineString, MultiLineString, Polygon, MultiPolygon, GeometryCollection are all instances of spatial data types recognized by both geometry and geography data types.      &lt;br /&gt;      &lt;br /&gt;To construct instances of a point, Multipoint etc. from WKT format Katmai provides functions as following      &lt;br /&gt;Point instance from WKT input use STPointFromText      &lt;br /&gt;MultiPoint instance from WKT input use STMPointFromText      &lt;br /&gt;LineString instance from WKT input use STLineFromText      &lt;br /&gt;MultiLineString instance from WKT input use STMLineFromText      &lt;br /&gt;Polygon instance from WKT input use STPolyFromText      &lt;br /&gt;MultiPolygon instance from WKT input use STMPolyFromText      &lt;br /&gt;GeometryCollection instance from WKT input STGeomCollFromText      &lt;br /&gt;      &lt;br /&gt;      &lt;br /&gt;To construct instances from WKB format Katmai provides the following functions      &lt;br /&gt;      &lt;br /&gt;Point instance from WKB input use STPointFromWKB      &lt;br /&gt;MultiPoint instance from WKB input use STMPointFromWKB.      &lt;br /&gt;LineString instance from WKB input use STLineFromWKB.      &lt;br /&gt;MultiLineString instance from WKB input use STMLineFromWKB      &lt;br /&gt;Polygon instance from WKB input use STPolyFromWKB      &lt;br /&gt;MultiPolygon instance from WKB input use STMPolyFromWKB.      &lt;br /&gt;GeometryCollection instance from WKB input use STGeomCollFromWKB      &lt;br /&gt;      &lt;br /&gt;There are also methods which allow developers to compare or determine the relationship between geometrical instances such as the ones listed below      &lt;br /&gt;      &lt;br /&gt;STEquals determines if two instances comprise the same point set      &lt;br /&gt;STDisjoint determines if two instances are disjoint      &lt;br /&gt;STIntersects determines if two instances intersect.      &lt;br /&gt;STTouches determines if two instances touch.      &lt;br /&gt;STOverlaps determines if two instances overlap.      &lt;br /&gt;STCrosses determines if two instances cross .      &lt;br /&gt;STWithin determines if one instance is within another .      &lt;br /&gt;STContains determines if one instance contains another.      &lt;br /&gt;STRelate determines if two instances are spatially related      &lt;br /&gt;STDistance determines the shortest distance between points in two geometries      &lt;br /&gt;      &lt;br /&gt;Equivalent set of functions and methods are available for Geographical types as well .      &lt;br /&gt;      &lt;br /&gt;To Create and add Spatial Data      &lt;br /&gt;      &lt;br /&gt;&lt;span style="color: #3333ff"&gt;USE Adventureworks       &lt;br /&gt;GO        &lt;br /&gt;        &lt;br /&gt;IF OBJECT_ID ( 'dbo.SpatialTable', 'U' ) IS NOT NULL DROP TABLE dbo.SpatialTable;        &lt;br /&gt;GO        &lt;br /&gt;        &lt;br /&gt;CREATE TABLE SpatialTable        &lt;br /&gt;( id int IDENTITY (1,1),        &lt;br /&gt;GeomCol1 geometry,        &lt;br /&gt;GeomCol2 AS GeomCol1.STAsText() );        &lt;br /&gt;GO&lt;/span&gt;      &lt;br /&gt;      &lt;br /&gt;&lt;span style="color: #3366ff"&gt;INSERT INTO SpatialTable (GeomCol1)       &lt;br /&gt;VALUES (geometry::STGeomFromText('LINESTRING (100 100, 20 180, 180 180)', 0));        &lt;br /&gt;        &lt;br /&gt;INSERT INTO SpatialTable (GeomCol1)        &lt;br /&gt;VALUES (geometry::STGeomFromText('POLYGON ((0 0, 150 0, 150 150, 0 150, 0 0))', 0));        &lt;br /&gt;GO&lt;/span&gt;      &lt;br /&gt;      &lt;br /&gt;To create a Geography instance from WKT format      &lt;br /&gt;      &lt;br /&gt;&lt;span style="color: #3366ff"&gt;DECLARE @g geography;       &lt;br /&gt;SET @g = geography::STGeomFromText('LINESTRING(47.656 -122.360, 47.656 -122.343)', 4326);        &lt;br /&gt;SELECT @g.ToString();        &lt;br /&gt;&lt;/span&gt;      &lt;br /&gt;To create a Geometry instance from WKB format&lt;/span&gt;&lt;/div&gt; &lt;span style="font-size: 85%; font-family: verdana"&gt;   &lt;div align="left"&gt;     &lt;br /&gt;&lt;span style="color: #3366ff"&gt;DECLARE @g geometry;       &lt;br /&gt;SET @g = geometry::STGeomFromWKB(0x010200000003000000000000000000594000000000000059400000000000003440000000000080664000000000008066400000000000806640, 0);        &lt;br /&gt;SELECT @g.STAsText();&lt;/span&gt;      &lt;br /&gt;      &lt;br /&gt;&lt;span style="color: #3366ff"&gt;-- Point from WKB       &lt;br /&gt;SET @g = geometry::STPointFromWKB(0x010100000000000000000059400000000000005940, 0);        &lt;br /&gt;SELECT @g.STAsText();        &lt;br /&gt;&lt;/span&gt;      &lt;br /&gt;To create a Geometry instance from WKT format      &lt;br /&gt;      &lt;br /&gt;&lt;span style="color: #3366ff"&gt;-- Creating an instance with WKT       &lt;br /&gt;DECLARE @g geometry;        &lt;br /&gt;SET @g = geometry::STGeomFromText('LINESTRING (100 100, 20 180, 180 180)', 0);        &lt;br /&gt;SELECT @g.ToString();        &lt;br /&gt;        &lt;br /&gt;-- Parse is also useful to convert data from WKT        &lt;br /&gt;SET @g = geometry::Parse('LINESTRING (100 100, 20 180, 180 180)');        &lt;br /&gt;SELECT @g.ToString();        &lt;br /&gt;        &lt;br /&gt;-- Point instance from WKT        &lt;br /&gt;SET @g = geometry::STPointFromText('POINT (100 100)', 0);        &lt;br /&gt;SELECT @g.ToString();        &lt;br /&gt;&lt;/span&gt;      &lt;br /&gt;Determining if the instances intersect      &lt;br /&gt;      &lt;br /&gt;&lt;span style="color: #3366ff"&gt;USE AdventureWorks       &lt;br /&gt;GO        &lt;br /&gt;        &lt;br /&gt;DECLARE @geom1 geometry;        &lt;br /&gt;DECLARE @geom2 geometry;        &lt;br /&gt;DECLARE @result geometry;        &lt;br /&gt;        &lt;br /&gt;SELECT @geom1 = GeomCol1 FROM SpatialTable WHERE id = 1;        &lt;br /&gt;SELECT @geom2 = GeomCol1 FROM SpatialTable WHERE id = 2;        &lt;br /&gt;SELECT @result = @geom1.STIntersection(@geom2);        &lt;br /&gt;SELECT @result.STAsText(); &lt;/span&gt;&lt;/div&gt; &lt;/span&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://cid-2cd165f70c749840.skydrive.live.com/self.aspx/sql%202008/Demo_Scripts.zip"&gt;Sample code&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="font-size: 85%; font-family: verdana"&gt;     &lt;br /&gt;As the integration of geospatial information into applications becomes more prevalent, we will require database systems that can store and manipulate spatial data. With the introduction of the spatial types, SQL Server 2008 provides a data storage solution for spatial data, and enables organizations of any scale to integrate geospatial features into their applications and services.&lt;/span&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4003504748921453462-2336923960063230187?l=www.agiledrivendevelopment.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.agiledrivendevelopment.net/feeds/2336923960063230187/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4003504748921453462&amp;postID=2336923960063230187' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/2336923960063230187'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/2336923960063230187'/><link rel='alternate' type='text/html' href='http://www.agiledrivendevelopment.net/2008/05/spatial-data-delivering-location-based.html' title='Spatial Data - Delivering Location based Intelligence'/><author><name>Log4Agile</name><uri>http://www.blogger.com/profile/04640347817726894882</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4003504748921453462.post-7522331935294842656</id><published>2008-02-15T00:36:00.000Z</published><updated>2008-05-15T22:58:41.145+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='T-SQL'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server 2008 - Katmai'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server'/><category scheme='http://www.blogger.com/atom/ns#' term='Katmai'/><title type='text'>Building Time Zone awareness - Date Time types</title><content type='html'>&lt;span style="font-size: 85%; font-family: verdana"&gt;   &lt;br /&gt;I have been working for the last two years on projects which involve synchronising data between web applications and many a the date and time on web application used as the source of the replication is not on the same time zone as the destination web application. Some times it is necessary that some portion of the date time values moved across these applications be time zone aware. In other words some date time values need to be moved into the local time where the server is present, while some needed to be moved at absolute times(same as specified on source).    &lt;br /&gt;    &lt;br /&gt;For eg.    &lt;br /&gt;    &lt;br /&gt;Consider a table with four columns on a web application in UK on SQL 2000 server    &lt;br /&gt;ID - identity    &lt;br /&gt;Name - VARCHAR(100)    &lt;br /&gt;sellingDate - datetime -- The date and time on which the product should start selling    &lt;br /&gt;ModifiedDate - datetime -- The date and time on which the product record or data was last modified    &lt;br /&gt;    &lt;br /&gt;Now when I move this data across to a web application in India the selling date should still remain on absolute date time specified, but the last modified time should be moved across as relative time to the time zone where this is present.    &lt;br /&gt;    &lt;br /&gt;This is quite a constraint since you would end up having a business rule for every datetime column of your database and this rule is only a adhoc one determined by functionality rather than any real type based information. It would be great to distinguish these time zone aware columns in the database level.    &lt;br /&gt;    &lt;br /&gt;Another problem when a .Net datetime value is serialised is it has an extra time offset appended at the end. This when passed to SQL 2000 parameters was not usable in its raw string form (say when passed as a XML fragment parameter containing this value)    &lt;br /&gt;    &lt;br /&gt;In SQL 2008 we have new date time data types as below    &lt;br /&gt;DATE. - Allows only dates, accuracy is a day    &lt;br /&gt;TIME - Allows only times to the accuracy of nano seconds    &lt;br /&gt;SMALLDATETIME - Allows dates and times , accuracy is one second    &lt;br /&gt;DATETIME - Allows date and time as before with 3ms accuracy, but the range of dates that can be specified has been increased to 01-01-1753 to 31-12-9999    &lt;br /&gt;DATETIME2 - Allows specifying date and time like the DATETIME type but to a accuracy of nano seconds , YYYY-MM-DD hh:mm:ss:[nnnnnnn]    &lt;br /&gt;DATETIMEOFFSET - Allows users to specify a date and time with a time zone offset.    &lt;br /&gt;    &lt;br /&gt;With these 6 new date time types in SQL server 2008, time zone aware applications can be more efficiently and easily designed/ developed.    &lt;br /&gt;    &lt;br /&gt;As we have seen the date time types, lets see what functions are available, its great to see an introduction of the datetimeoffset but it would even better to do some playing around with it at the database level    &lt;br /&gt;    &lt;br /&gt;Functions which return DATETIME values, These are as present in SQL 2000, 2005    &lt;br /&gt;GETDATE(), CURRENT_TIMESTAMP and GETUTCDATE() are still available.    &lt;br /&gt;    &lt;br /&gt;Functions which return DATETIME2 values, other wise refered to as HIGH PRECISION date time functions, SYSDATETIME(), SYSUTCDATETIME(),SYSDATETIMEOFFSET() (returns DATETIMEOFFSET type value).    &lt;br /&gt;    &lt;br /&gt;Other functions as in previous versions such as DATEPART, DATEDIFF, DATEADD are available , but two new useful functions which complement the DATETIMEOFFSET datatype hav been introduced.    &lt;br /&gt;    &lt;br /&gt;SWITCHOFFSET() and TODATETIMEOFFSET()    &lt;br /&gt;    &lt;br /&gt;e.g.    &lt;br /&gt;    &lt;br /&gt;&lt;span style="color: #000099"&gt;SELECT SWITCHOFFSET(sysdatetimeoffset(), '+08:00'     &lt;br /&gt;&lt;/span&gt;    &lt;br /&gt;The SWITCHOFFSET function converts a value of datetimeoffset type from stored time zone to specified time zone    &lt;br /&gt;    &lt;br /&gt;&lt;span style="color: #000099"&gt;SELECT TODATETIMEOFFSET ( GETDATE() , '+08:00' )     &lt;br /&gt;&lt;/span&gt;    &lt;br /&gt;The TODATETIMEOFFSET function converts a datetime type value into a DATETIMEOFFSET type with the offset specified    &lt;br /&gt;    &lt;br /&gt;ISDATE()    &lt;br /&gt;    &lt;br /&gt;Another useful function for datetime is the ISDATE() function, which validates that the specified value in the parameter is a valid date time value. There are several different scenarios to use it but in general for something as below    &lt;br /&gt;    &lt;br /&gt;&lt;span style="color: #000099"&gt;SELECT ISDATE(NULL); --returns 0     &lt;br /&gt;      &lt;br /&gt;      &lt;br /&gt;USE AdventureWorks;      &lt;br /&gt;GO      &lt;br /&gt;SELECT ISDATE(s.OrderDate) FROM Sales.SalesOrderHeader s;      &lt;br /&gt;GO      &lt;br /&gt;--Returns ones&lt;/span&gt;    &lt;br /&gt;    &lt;br /&gt;    &lt;br /&gt;All the information above is based on the November CTP for Katmai. Looking at all the above it does show good prospects for handling date and times for developers. &lt;/span&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4003504748921453462-7522331935294842656?l=www.agiledrivendevelopment.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.agiledrivendevelopment.net/feeds/7522331935294842656/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4003504748921453462&amp;postID=7522331935294842656' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/7522331935294842656'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/7522331935294842656'/><link rel='alternate' type='text/html' href='http://www.agiledrivendevelopment.net/2008/02/building-time-zone-awareness-date-time.html' title='Building Time Zone awareness - Date Time types'/><author><name>Log4Agile</name><uri>http://www.blogger.com/profile/04640347817726894882</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4003504748921453462.post-2249761283892640201</id><published>2008-02-12T00:21:00.000Z</published><updated>2008-05-15T22:57:59.657+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server 2008 - Katmai'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server'/><category scheme='http://www.blogger.com/atom/ns#' term='Katmai'/><title type='text'>Change Data Capture (CDC) - I</title><content type='html'>&lt;a href="http://tsqldotnet.com/images/cdc_schema.JPG"&gt;&lt;/a&gt;  &lt;div&gt;&amp;#160;&lt;/div&gt;  &lt;br /&gt;  &lt;div&gt;   &lt;br /&gt;&lt;span style="font-family: verdana"&gt;&lt;span style="font-size: 85%"&gt;Oracle 9i has this feature since 2003 as I can recollect, but being a SQL Server developer I am quite pleased its available in Katmai. To give a bit of background as to why CDC is a crucial feature , we will try to understand ETL in Data warehousing. A crucial function of data warehousing is extracting data on a regular basis applying some kind of transform if necessary to the data and storing it in the warehouse. So if i have a database replication setup I would run DTS packages which replicate and transform all data between the transactional database and the warehouse database. If you are a DBA or a developer involved in a data integration project that involves the regular extraction and transportation of a large amount of data from one system to another system or systems, you could consider CDC to help reduce your ETL time. The point is its more efficient than our previous replication methodologies for sure and it is particularly effective as we scale up on the database size.       &lt;br /&gt;In SQL Server 2000, 2005 you would have written triggers to update data into another table where the metadata on the change is stored and then further right more plumbing code to put it all together ... I work on a product which has a similar concept.. Believe me it&amp;#8217;s not a easy on 2000 and 2005. We where able to track data even though it was complicated but now in Katmai we will be able to capture the details of the event which caused data change on the relevant database table.        &lt;br /&gt;        &lt;br /&gt;In Katmai, when we use Change Data Capture feature on a database table, a mirror of the tracked table schema is created with additional columns that include metadata. The metadata holds all the information about the change.        &lt;br /&gt;        &lt;br /&gt;To know if CDC is enabled for a database, we could run the following query        &lt;br /&gt;        &lt;br /&gt;SELECT * FROM sys.databases WHERE is_cdc_enabled = 1        &lt;br /&gt;        &lt;br /&gt;&lt;strong&gt;Enabling the database for CDC&lt;/strong&gt;        &lt;br /&gt;        &lt;br /&gt;        &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 85%"&gt;&lt;span style="color: #000099"&gt;USE AdventureWorks         &lt;br /&gt;          &lt;br /&gt;GO          &lt;br /&gt;          &lt;br /&gt;EXEC sys.sp_cdc_enable_db_change_data_capture          &lt;br /&gt;          &lt;br /&gt;GO&lt;/span&gt;        &lt;br /&gt;        &lt;br /&gt;When you execute this command five tables in a schema called cdc are created. In addition to this there are two table valued functions added on to the cdc schema of the database. These functions behave like stubs for table based CDC functions        &lt;br /&gt;        &lt;br /&gt;The five tables created are as below        &lt;br /&gt;        &lt;br /&gt;        &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 85%"&gt;&lt;span style="color: #000099"&gt;cdc.captured_columns         &lt;br /&gt;          &lt;br /&gt;cdc.ddl_history          &lt;br /&gt;          &lt;br /&gt;cdc.index_columns          &lt;br /&gt;          &lt;br /&gt;cdc.lsn_time_mapping          &lt;br /&gt;          &lt;br /&gt;cdc.change_tables&lt;/span&gt;        &lt;br /&gt;        &lt;br /&gt;In Katmai, when we use Change Data Capture feature on a database table, a mirror of the tracked table schema is created with additional columns that include metadata. The metadata holds all the information about the change.        &lt;br /&gt;        &lt;br /&gt;In addition to this you will notice there are two Jobs one for Capture and one for cleanup added under the SQL Server Agent jobs for the database CDC functionality        &lt;br /&gt;        &lt;br /&gt;CDC Schema        &lt;br /&gt;        &lt;br /&gt;&lt;img height="400" src="http://tsqldotnet.com/images/cdc_schema.JPG" width="300" /&gt;        &lt;br /&gt;        &lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;  &lt;div&gt;&lt;span style="font-family: verdana"&gt;&lt;span style="font-size: 85%"&gt;&lt;a href="http://tsqldotnet.com/images/cdc_schema.JPG"&gt;&lt;/a&gt;        &lt;br /&gt;&lt;strong&gt;Enabling the table for CDC&lt;/strong&gt; &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;  &lt;br /&gt;  &lt;div&gt;&lt;span style="font-family: verdana"&gt;     &lt;br /&gt;&lt;span style="font-size: 85%"&gt;On the AdventureWorks database to enable CDC on HumanResources.Employee table, we should use the following functions       &lt;br /&gt;        &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 85%"&gt;&lt;span style="color: #000099"&gt;USE Adventureworks         &lt;br /&gt;          &lt;br /&gt;GO          &lt;br /&gt;          &lt;br /&gt;EXEC sys.sp_cdc_enable_table_change_data_capture          &lt;br /&gt;          &lt;br /&gt;@source_schema = 'HumanResources',          &lt;br /&gt;          &lt;br /&gt;@source_name = 'Employee',          &lt;br /&gt;          &lt;br /&gt;@role_name = 'cdc_AdventureWorks',          &lt;br /&gt;          &lt;br /&gt;@capture_instance='HumanResources_Employee_CT'          &lt;br /&gt;          &lt;br /&gt;GO &lt;/span&gt;        &lt;br /&gt;        &lt;br /&gt;When we execute this command a new capture instance is created a table with this name of the capture instance is created with the schema as shown in the diagram        &lt;br /&gt;        &lt;br /&gt;        &lt;br /&gt;        &lt;br /&gt;Note that columns as in the Employee table are created, In addition to which there are five extra columns which store metadata about the data.        &lt;br /&gt;        &lt;br /&gt;Now we update a row on the HumanResources.Employee table as below        &lt;br /&gt;        &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 85%"&gt;&lt;span style="color: #000099"&gt;UPDATE HumanResources.Employee         &lt;br /&gt;          &lt;br /&gt;SET LoginID = 'adventureworks\guy2'          &lt;br /&gt;          &lt;br /&gt;WHERE employeeid = 1          &lt;br /&gt;&lt;/span&gt;        &lt;br /&gt;Now select the data in the HumanResources_Employee_CT, we will find two rows inserted in this table, One representing the data before the update and the other after the data was inserted        &lt;br /&gt;        &lt;br /&gt;&lt;strong&gt;Disabling CDC on a table/capture instance&lt;/strong&gt;        &lt;br /&gt;        &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 85%"&gt;&lt;span style="color: #000099"&gt;USE Adventureworks         &lt;br /&gt;          &lt;br /&gt;GO          &lt;br /&gt;          &lt;br /&gt;EXEC sys.sp_cdc_disable_table_change_data_capture          &lt;br /&gt;          &lt;br /&gt;@source_schema = 'HumanResources',          &lt;br /&gt;          &lt;br /&gt;@source_name = 'Employee',          &lt;br /&gt;          &lt;br /&gt;@capture_instance = 'HumanResources_Employee_CT'          &lt;br /&gt;          &lt;br /&gt;GO          &lt;br /&gt;&lt;/span&gt;        &lt;br /&gt;I guess I will pause here and continue on the rest in my next blog&amp;#8230;. There are several cdc related system functions which could be used for different purposes, I will detail each of these in my next blog.. and i will also detail the schema a bit when i get my head around it hopefully        &lt;br /&gt;        &lt;br /&gt;&lt;/span&gt;&lt;a href="http://tsqldotnet.com/documents/change_data_capture.zip"&gt;&lt;span style="font-size: 85%"&gt;Download - Scripts CDC&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size: 85%"&gt;       &lt;br /&gt;        &lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4003504748921453462-2249761283892640201?l=www.agiledrivendevelopment.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.agiledrivendevelopment.net/feeds/2249761283892640201/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4003504748921453462&amp;postID=2249761283892640201' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/2249761283892640201'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/2249761283892640201'/><link rel='alternate' type='text/html' href='http://www.agiledrivendevelopment.net/2008/02/change-data-capture-cdc-i-oracle-9i-has.html' title='Change Data Capture (CDC) - I'/><author><name>Log4Agile</name><uri>http://www.blogger.com/profile/04640347817726894882</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4003504748921453462.post-8184702295082624470</id><published>2008-02-11T21:13:00.000Z</published><updated>2008-05-15T22:56:58.593+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server 2008 - Katmai'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server'/><category scheme='http://www.blogger.com/atom/ns#' term='Katmai'/><title type='text'>Resource Governor</title><content type='html'>&lt;span style="font-size: 85%"&gt;&lt;span style="font-family: verdana"&gt;Before we understand the Resource Governor let us consider an example where we have hosted two databases App1 and App2 on a single SQL Server 2005 with a query execution time out of 600 seconds. Lets say App1 database should not allow queries to execute for more than 5 minutes which is 300 seconds and App2 should allow 600 seconds. This was not easy to achieve on SQL 2005. (We may argue that we could specify connection timeout on the client connection string in ADO.Net, but that&amp;#8217;s just a work around), Alright, what if I want to give connections of App1 database more priority than App2 database connections when server resources are limited?&lt;/span&gt;    &lt;br /&gt;    &lt;br /&gt;&lt;span style="font-family: verdana"&gt;One of the new features in SQL 2008 (Katmai) is the Resource Governer. It is a component that allows administrators to configure pools of resources. Consider this an analogy to the Application Pool in IIS 6. &lt;/span&gt;    &lt;br /&gt;    &lt;br /&gt;&lt;span style="font-family: verdana"&gt;The 2 main components in the Resource Governer that matter are the Resource Pool and the Workload Group.&lt;/span&gt;    &lt;br /&gt;&lt;strong&gt;&lt;span style="font-family: verdana"&gt;&lt;/span&gt;&lt;/strong&gt;&lt;/span&gt;  &lt;br /&gt;  &lt;br /&gt;  &lt;br /&gt;&lt;span style="font-size: 85%"&gt;&lt;strong&gt;&lt;span style="font-family: verdana"&gt;Resource Pool&lt;/span&gt;&lt;/strong&gt;    &lt;br /&gt;    &lt;br /&gt;&lt;span style="font-family: verdana"&gt;The Resource Pool allows you set server (as in the physical server on which SQL server is installed) level resource usage such as &lt;/span&gt;    &lt;br /&gt;    &lt;br /&gt;&lt;span style="font-family: verdana"&gt;MAX_CPU_PERCENT, MIN_CPU_PERCENT and &lt;/span&gt;&lt;span style="font-family: verdana"&gt;MAX_MEMORY_PERCENT, MIN_MEMORY_PERCENT&lt;/span&gt;    &lt;br /&gt;    &lt;br /&gt;&lt;span style="font-family: verdana"&gt;&lt;strong&gt;Using TSQL&lt;/strong&gt;&lt;/span&gt;    &lt;br /&gt;&lt;span style="font-family: verdana"&gt;&lt;/span&gt;    &lt;br /&gt;&lt;span style="color: #000099; font-family: verdana"&gt;CREATE RESOURCE POOL poolNorthwind&lt;/span&gt;    &lt;br /&gt;&lt;span style="color: #000099; font-family: verdana"&gt;WITH&lt;/span&gt;    &lt;br /&gt;&lt;span style="color: #000099; font-family: verdana"&gt;( &lt;/span&gt;    &lt;br /&gt;&lt;span style="color: #000099; font-family: verdana"&gt;MAX_CPU_PERCENT = 30, &lt;/span&gt;    &lt;br /&gt;&lt;span style="color: #000099; font-family: verdana"&gt;MAX_MEMORY_PERCENT = 50&lt;/span&gt;    &lt;br /&gt;&lt;span style="color: #000099; font-family: verdana"&gt;);&lt;/span&gt;    &lt;br /&gt;    &lt;br /&gt;&lt;strong&gt;&lt;span style="font-family: verdana"&gt;Workload Group.&lt;/span&gt;&lt;/strong&gt;    &lt;br /&gt;    &lt;br /&gt;&lt;span style="font-family: verdana"&gt;The Workload Group allows you to control some specific SQL Server related conditions, as well as apply Resource Pools. It allows you to control settings such as the connection priority, query time out, max parallel requests and other parameters as mentioned below&lt;/span&gt;    &lt;br /&gt;    &lt;br /&gt;&lt;span style="font-family: verdana"&gt;IMPORTANCE = MEDIUM , REQUEST_MAX_MEMORY_GRANT_PERCENT, REQUEST_MAX_CPU_TIME_SEC , REQUEST_MEMORY_GRANT_TIMEOUT_SEC , MAX_DOP , GROUP_MAX_REQUESTS&lt;/span&gt;    &lt;br /&gt;    &lt;br /&gt;&lt;span style="font-family: verdana"&gt;&lt;strong&gt;Using TSQL&lt;/strong&gt; &lt;/span&gt;    &lt;br /&gt;    &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 85%"&gt;&lt;span style="color: #000099; font-family: verdana"&gt;CREATE WORKLOAD GROUP workGroupNorthwind     &lt;br /&gt;WITH      &lt;br /&gt;(      &lt;br /&gt;IMPORTANCE = MEDIUM , -- default is medium, its like OS thread priority &lt;/span&gt;&lt;span style="color: #000099; font-family: verdana"&gt;REQUEST_MEMORY_GRANT_TIMEOUT_SEC = 300,-- max query timeout to 5 min &lt;/span&gt;    &lt;br /&gt;&lt;span style="color: #000099; font-family: verdana"&gt;MAX_DOP = 8, -- maximum degree of parallelism to 8 &lt;/span&gt;    &lt;br /&gt;&lt;span style="color: #000099; font-family: verdana"&gt;GROUP_MAX_REQUESTS = 30 &lt;/span&gt;    &lt;br /&gt;&lt;span style="color: #000099; font-family: verdana"&gt;)&lt;/span&gt;    &lt;br /&gt;&lt;span style="color: #000099; font-family: verdana"&gt;USING poolNorthwind;&lt;/span&gt;    &lt;br /&gt;    &lt;br /&gt;&lt;span style="font-family: verdana"&gt;In order for SQL Server to be able to use the Workload Groups that you've created, you need to classify each connection to determine which group that specific connections falls into. This is done through the use of a Classifier Function. Classifier functions are new in SQL Server 2008 and execute each time a new connection is made to the server. Classifier functions are scalar user-defined functions and are basically used to return the name of the target Workload Group for each user connection.&lt;/span&gt;    &lt;br /&gt;    &lt;br /&gt;&lt;span style="font-family: verdana"&gt;&lt;strong&gt;Code Example&lt;/strong&gt;&lt;/span&gt;    &lt;br /&gt;&lt;span style="font-family: verdana"&gt;&lt;/span&gt;    &lt;br /&gt;&lt;span style="color: #000099; font-family: verdana"&gt;CREATE FUNCTION ufnNorthwindRsGovMgr() &lt;/span&gt;    &lt;br /&gt;&lt;span style="color: #000099; font-family: verdana"&gt;RETURNS SYSNAME WITH SCHEMABINDING&lt;/span&gt;    &lt;br /&gt;&lt;span style="color: #000099; font-family: verdana"&gt;AS&lt;/span&gt;    &lt;br /&gt;&lt;span style="color: #000099; font-family: verdana"&gt;BEGIN &lt;/span&gt;    &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 85%"&gt;&lt;span style="font-family: verdana"&gt;&lt;span style="color: #000099"&gt;DECLARE @grpName SYSNAME &lt;/span&gt;      &lt;br /&gt;&lt;/span&gt;    &lt;br /&gt;&lt;span style="color: #000099; font-family: verdana"&gt;IF (APP_NAME() = 'Microsoft SQL Server Management Studio') &lt;/span&gt;    &lt;br /&gt;&lt;span style="color: #000099; font-family: verdana"&gt;SET @grpName = 'workGroupNorthwind' &lt;/span&gt;    &lt;br /&gt;&lt;span style="color: #000099; font-family: verdana"&gt;ELSE &lt;/span&gt;    &lt;br /&gt;&lt;span style="color: #000099; font-family: verdana"&gt;SET @grpName = 'default' &lt;/span&gt;    &lt;br /&gt;&lt;span style="color: #000099; font-family: verdana"&gt;RETURN @grpNameEND;&lt;/span&gt;    &lt;br /&gt;    &lt;br /&gt;&lt;span style="color: #000099"&gt;&lt;span style="font-family: verdana"&gt;&lt;span style="color: #000000"&gt;The final step in the configuration of the Resource Governor is to assign the classifier function and activate the configuration.&lt;/span&gt; &lt;/span&gt;&lt;/span&gt;    &lt;br /&gt;    &lt;br /&gt;&lt;span style="color: #000099; font-family: verdana"&gt;ALTER RESOURCE GOVERNOR &lt;/span&gt;    &lt;br /&gt;&lt;span style="color: #000099; font-family: verdana"&gt;WITH &lt;/span&gt;    &lt;br /&gt;&lt;span style="color: #000099; font-family: verdana"&gt;( &lt;/span&gt;    &lt;br /&gt;&lt;span style="color: #000099; font-family: verdana"&gt;CLASSIFIER_FUNCTION=dbo.ufnNorthwindRsGovMgr&lt;/span&gt;    &lt;br /&gt;&lt;span style="color: #000099; font-family: verdana"&gt;);&lt;/span&gt;    &lt;br /&gt;    &lt;br /&gt;&lt;span style="color: #000099; font-family: verdana"&gt;ALTER RESOURCE GOVERNOR RECONFIGURE;&lt;/span&gt;    &lt;br /&gt;&lt;span style="font-family: verdana"&gt;&lt;/span&gt;    &lt;br /&gt;&lt;strong&gt;&lt;span style="font-family: verdana"&gt;Using the Management Studio&lt;/span&gt;&lt;/strong&gt;    &lt;br /&gt;    &lt;br /&gt;&lt;span style="font-family: verdana"&gt;If we use the Management Studio which comes with the Developer versrion of SQL 2008 CTP allows you to create the Resource Pool using the Resource Governor properties dialog, shown in the picture on this entry &lt;/span&gt;    &lt;br /&gt;    &lt;br /&gt;&lt;img height="200" src="http://tsqldotnet.com/images/resourcegovernor.jpg" width="400" /&gt;    &lt;br /&gt;    &lt;br /&gt;I have created a solution with the above code . &lt;/span&gt;&lt;a style="font-family: verdana" href="http://temp.tsqldotnetcom.officelive.com/Documents/RESOURCE_GOVERNER.zip" target="_blank"&gt;&lt;/a&gt;&lt;a href="http://temp.tsqldotnetcom.officelive.com/Documents/RESOURCE_GOVERNER.zip" target="_blank"&gt;&lt;span style="font-size: 85%"&gt;Download&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size: 85%"&gt;   &lt;br /&gt;&lt;span style="font-family: verdana"&gt;&lt;/span&gt;    &lt;br /&gt;    &lt;br /&gt;&lt;/span&gt;  &lt;br /&gt;&lt;a href="http://byfiles.storage.live.com/y1pSELFPqQgaRxrSUduAll_ABUxc6sNR14KyRzltG7s5MnVy9U9fI6-11tLMF7JRnhCP61iGt70sbg" target="_blank"&gt;&lt;span style="font-family: verdana"&gt;&lt;/span&gt;&lt;/a&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4003504748921453462-8184702295082624470?l=www.agiledrivendevelopment.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.agiledrivendevelopment.net/feeds/8184702295082624470/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4003504748921453462&amp;postID=8184702295082624470' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/8184702295082624470'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/8184702295082624470'/><link rel='alternate' type='text/html' href='http://www.agiledrivendevelopment.net/2008/02/resource-governor.html' title='Resource Governor'/><author><name>Log4Agile</name><uri>http://www.blogger.com/profile/04640347817726894882</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4003504748921453462.post-2416552330839075408</id><published>2008-02-11T20:00:00.000Z</published><updated>2008-05-20T13:50:33.079+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server 2008 - Katmai'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server'/><category scheme='http://www.blogger.com/atom/ns#' term='Katmai'/><title type='text'>Features on SQL Server 2008 - Katmai</title><content type='html'>&lt;p&gt;&lt;span style="font-size: 85%; font-family: verdana"&gt;For the last three weeks i have been playing around with SQL Server 2008 (Katmai) CTP. I managed to install it on Windows 2003 server without any problems. Although i would advise people not to install alongside SQL Server 2005. If you want to use management studio of SQL 2008 CTP be sure to use the developer edition CTP, the expression edition only comes with some client tools. Since its a CTP and you only are trying to get your head around new features it is useful to have management studio installedAs with any CTP i didnt know where to start and i found that Chad Boyd ihas listed the new features for Katmai quite extensively on his &lt;/span&gt;&lt;a style="font-family: verdana" href="http://blogs.mssqltips.com/blogs/chadboyd/archive/2007/10/15/katmai-sql-2008-the-list-of-new-features.aspx" target="_blank"&gt;&lt;span style="font-size: 85%; font-family: verdana"&gt;blog&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size: 85%; font-family: verdana"&gt;. Since I am just a developer and i filtered the list of features that may be more useful for a developer to look at.. I m planning to plough through one feature at a time and put up some information on this site for people who are interested.&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="font-size: 85%; font-family: verdana"&gt;     &lt;br /&gt;&lt;strong&gt;Performance&lt;/strong&gt; &lt;/span&gt;&lt;/p&gt; &lt;span style="font-size: 85%; font-family: verdana"&gt;   &lt;ul&gt;     &lt;li&gt;Data compression (easy to enable/disable online, more efficient data. &lt;/li&gt;      &lt;li&gt;Backup stream compression (server level control or backup statement control, all backup types). &lt;/li&gt;      &lt;li&gt;&lt;a href="http://tsqldotnet.blogspot.com/2008/02/resource-governor.html" target="_blank"&gt;Resource Governor (create pools and groups to govern, define classifications based on built-in functions, segment resource utilization among groups).&lt;/a&gt; &lt;/li&gt;   &lt;/ul&gt;    &lt;p&gt;&lt;strong&gt;Management&lt;/strong&gt; &lt;/p&gt;    &lt;ul&gt;     &lt;li&gt;Policy based management framework (manage via policies vs. scripts, enterprise wide support, automated monitoring/enforcement, etc.). &lt;/li&gt;      &lt;li&gt;Integrate with Microsoft System Centre. &lt;/li&gt;      &lt;li&gt;Extended Events (high perf lightweight tracing infrastructure, NOT sql trace, integrated with ETW). &lt;/li&gt;   &lt;/ul&gt;    &lt;p&gt;&lt;strong&gt;Development Enhancements &lt;/strong&gt;&lt;/p&gt;    &lt;ul&gt;     &lt;li&gt;&lt;a href="http://tsqldotnet.blogspot.com/2008/02/building-time-zone-awareness-date-time.html" target="_blank"&gt;Improved datetime data types (100th nanosecond precision (7 digits past second), time zone datetime offset, date only, time only).&lt;/a&gt; &lt;/li&gt;      &lt;li&gt;&lt;a href="http://tsqldotnet.blogspot.com/2008/05/storing-hierarchical-data-heirarchyid.html" target="_blank"&gt;HierarchyID datatype (hierarchical aware data type, ORDPath values, built-in functions, methods, etc.).&lt;/a&gt; &lt;/li&gt;      &lt;li&gt;Entity Data Model support (develop 'business entities' vs. tables, model complex relationships, retrieve entities vs. rows/columns). &lt;/li&gt;      &lt;li&gt;LINQ. &lt;/li&gt;      &lt;li&gt;&lt;a href="http://tsqldotnet.blogspot.com/2008/02/change-data-capture-cdc-i-oracle-9i-has.html" target="_blank"&gt;Sql Server Change Tracking (Change Data Capture, get 'diff' data changes WITHOUT a comparible value (i.e. datetime, timestamp, etc.)).&lt;/a&gt; &lt;/li&gt;      &lt;li&gt;&lt;a href="http://tsqldotnet.blogspot.com/2008/05/table-valued-parameters.html" target="_blank"&gt;Table Valued Parameters.&lt;/a&gt;&lt;/li&gt;      &lt;li&gt;MERGE statement ('upsert' data, also includes deletion functionality). &lt;/li&gt;      &lt;li&gt;Large UDT's (no more 8000 byte limit on CLR based UDTs, no more 8000 byte limit for UDA's). &lt;/li&gt;      &lt;li&gt;&lt;a href="http://tsqldotnet.blogspot.com/2008/05/spatial-data-delivering-location-based.html" target="_blank"&gt;Spatial data (GEOMETRY and GEOGRAPHY data types, built-in spatial function support, spatial indexes).&lt;/a&gt;&lt;/li&gt;      &lt;li&gt;XML enhancements (support for lax validation, office 12 support, xs:dateTime support, lists/union types, LET FLOWR support, etc.). &lt;/li&gt;      &lt;li&gt;Inline initialization and compound assignment &lt;/li&gt;   &lt;/ul&gt;    &lt;p&gt;&lt;strong&gt;Service Broker &lt;/strong&gt;&lt;/p&gt;    &lt;ul&gt;     &lt;li&gt;New UI and Tools for working with (add/drop/edit functionality within SSMS, Diag tools).        &lt;br /&gt;Conversation Priority (set message ordering, send/receive impact, 110 levels).         &lt;br /&gt;&lt;/li&gt;   &lt;/ul&gt;    &lt;p&gt;&lt;strong&gt;Data Storage &lt;/strong&gt;&lt;/p&gt;    &lt;ul&gt;     &lt;li&gt;Data compression (see above). &lt;/li&gt;      &lt;li&gt;FILESTREAM attribute (get the 'best of both' functionality from BLOBs in the DB vs. BLOBs on filesystem, no more &amp;quot;to blob or not to blob&amp;quot;). &lt;/li&gt;      &lt;li&gt;Integrated Full Text Search (FTS fully integrated into DB engine, no external storage, no external service, more efficient and reliable costing). &lt;/li&gt;      &lt;li&gt;Sparse columns (more efficient storage for 'wide' tables with many columns that repeat and don't contain data). &lt;/li&gt;      &lt;li&gt;New index types (spatial indexes, hierarchical indexes, FILTERED indexes (indexes on filtered values within columns), etc.). &lt;/li&gt;   &lt;/ul&gt;    &lt;li&gt;     &lt;p&gt;&lt;strong&gt;Reporting &lt;/strong&gt;&lt;/p&gt;      &lt;ul&gt;       &lt;li&gt;IIS Agnostic Reporting Services Deployment (no IIS required to run RS any longer).Richtext support. &lt;/li&gt;        &lt;li&gt;Enhanced visualiztion (graphing). &lt;/li&gt;        &lt;li&gt;New Word rendering (render reports to Microsoft Word). &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt; &lt;/span&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4003504748921453462-2416552330839075408?l=www.agiledrivendevelopment.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.agiledrivendevelopment.net/feeds/2416552330839075408/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4003504748921453462&amp;postID=2416552330839075408' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/2416552330839075408'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4003504748921453462/posts/default/2416552330839075408'/><link rel='alternate' type='text/html' href='http://www.agiledrivendevelopment.net/2008/02/features-on-sql-server-2008-katmai.html' title='Features on SQL Server 2008 - Katmai'/><author><name>Log4Agile</name><uri>http://www.blogger.com/profile/04640347817726894882</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry></feed>
