[delete] Deleting 1 files.
[dbIntegrate] ALTER-etomic.sharetransformer-integrate-1.0.4.0.sql
[exec] 1> 2> 3> 4> 5> 6> 7> 1> 2> 1> 2> 1> 2> 1> 2> 1> 2> 1> 2> 1> 2> 1> 2> 
3> 4> 5> 6> The database update succeeded
[exec] 1> 2> 1> 
configure:
[attrib] Setting file attributes for 1 files to Normal.
[xmlpoke] Found '1' nodes matching XPath expression 
'/configuration/appSettings/add[@key = 'DbConnectionString']/@value'.
[attrib] Setting file attributes for 1 files to ReadOnly.
We can see that two executions of the databaseincrementtarget occur, moving the old ver-
sion (1.0.2.0) through 1.0.3.0 to version 1.0.4.0. Superb.
Note
You have probably already realized that this script can be used to perform a “clean”build by simply
applying all migration scripts from the very first build.
Adding the old version of the database at the command line is effective but might be seen
as a bit kludgy. My suggestion for alternative solutions is to use <xmlpoke>and<xmlpeek>to
maintain a state or version file, or try to use the <version>task to do the same. I spent a little
time messing around with this idea, and found it satisfactory. 
At this point, we are now able to analyze, integrate, and deploy a system with a database
as we wish. Now for something completely different...
Considering DTS Packages
DTS (Data Transformation Services) packages are a very useful feature of SQL Server, and I
have seen heavy use of DTS features for handling a variety of scheduled tasks. Unfortunately,
they can be a pain to deploy effectively because they are prone to poor standards for configu-
ration and also because it can be awkward to ensure quality.
The DTS Compare tool from the SQL Bundle does an excellent job of analyzing differ-
ences between server instances, which means the physical porting of a DTS package from
server to server is less painful than manual inspections. However, there is another problem.
Usually a DTS package will need to be configured differently from server to server—different
FTP server information, for example. The only real option is to access the package on the pro-
duction server and make changes to variables throughout the tasks within the package. This
ispossible, but in my experience leads to heated debates between developers and operations
personnel as to who forgot to set the variables or who set them incorrectly. This reduces the
confidence in DTS package deployment and can affect the success of a project.
The effort and risk can be reduced to some extent through the introduction of some stan-
dard tasks in DTS packages and, as usual, a bit of organization.
CHAPTER 8 DATABASE INTEGRATION
273
Convert pdf file to jpg on - Convert PDF to JPEG images in C#.net, ASP.NET MVC, WinForms, WPF project
How to convert PDF to JPEG using C#.NET PDF to JPEG conversion / converter library control SDK
convert pdf to jpg converter; change pdf to jpg on
Convert pdf file to jpg on - VB.NET PDF Convert to Jpeg SDK: Convert PDF to JPEG images in vb.net, ASP.NET MVC, WinForms, WPF project
Online Tutorial for PDF to JPEG (JPG) Conversion in VB.NET Image Application
bulk pdf to jpg converter; convert pdf into jpg
Note
DTS is of course a little bit obscure and archaic.The code that follows works with a minimum of
effort but could be accomplished,probably to a higher quality,with a specific custom task implemented in
VB 6.0,or C# if you are daring.I hope that the next version of SQL Server has improved configuration and
deployment capabilities for DTS packages.
Figure 8-18 shows a package with two steps at the beginning: Load XML File and Set Vari-
ables. The first is a VBScript task, and the second is a Dynamic Properties task. We will use
these to simplify package configuration.
Figure 8-18.Standard DTS package configuration
Organization
Generally speaking, DTS packages have a tendency to generate artifacts since they are used
topush around data feeds in various formats. These artifacts can be organized sensibly,
servertoserver, by maintaining standard shares in the same way on each server in the form
\\<server name>\<dts share name>\<project name>. The artifacts for DTS packages can then
be maintained neatly and cleaned up from this area. 
Additionally, we will use this space to maintain an XML file containing the configuration
for the DTS package.
CHAPTER 8 ■ DATABASE INTEGRATION
274
Online Convert Jpeg to PDF file. Best free online export Jpg image
Convert a JPG to PDF. You can drag and drop your JPG file in the box, and then start immediately to sort the files, try out some settings and then create the
convert pdf to jpg for; best pdf to jpg converter online
Online Convert PDF to Jpeg images. Best free online PDF JPEG
Online PDF to JPEG Converter. Download Free Trial. Convert a PDF File to JPG. Drag and drop your PDF in the box above and we'll convert the files for you.
batch pdf to jpg converter; .net convert pdf to jpg
Load XML File Task
The XML files to be stored in the project folder have the following trivial format:
<?xml version="1.0" encoding="UTF-8"?>
<parameters>
<parameter name="ConnectionString">My connection string</parameter>
<parameter name="Another Name">Another Value</parameter>
</parameters>
The Load XML File task should then contain the following (VBScript) code:
Function Main()
Dim oXML
Set oXML = CreateObject("Microsoft.XMLDOM")
oXML.Async = False
oXML.ValidateOnParse = False
oXML.Load(DTSGlobalVariables("xmlPath").value)
If oXML.XML = "" Then
Main = DTSTaskExecResult_Failure
Else
Set oRootElement = oXML.documentElement
for i = 0 to oRootElement.childNodes.length -1
strName = oRootElement.childNodes.item(i).getAttribute("name")
strValue = oRootElement.childNodes.item(i).text
DTSGlobalVariables(CStr(strName)).value = strValue
next
Main = DTSTaskExecResult_Success
End If
End Function
Note
Ugh! At least you only have to type it once; you can copy and paste from that point forward.
Love VBScript or hate it, this task loads up the simple XML file and sets global variables
for the package according to all of the entries in the XML file. In order for the task to work,
there needs to be one preexisting global variable, which should be called xmlPathand which
should point to the XML configuration file, as shown in Figure 8-19.
CHAPTER 8 DATABASE INTEGRATION
275
C# Image Convert: How to Convert Adobe PDF to Jpeg, Png, Bmp, &
C# sample code for PDF to jpg image conversion. This demo code convert PDF file all pages to jpg images. // Define input and output files path.
convert pdf into jpg format; changing file from pdf to jpg
C# Image Convert: How to Convert Dicom Image File to Raster Images
RasterEdge.XDoc.Office.Inner.Office03.dll. RasterEdge.XDoc.PDF.dll. This demo code convert dicom file all pages to jpg images.
reader pdf to jpeg; batch pdf to jpg online
Figure 8-19.Initial global variables settings
After this step is executed successfully, the new global variables will also be present, as
can be seen in Figure 8-20.
Figure 8-20.Global variables after Load XML File task
CHAPTER 8 ■ DATABASE INTEGRATION
276
C# Create PDF from images Library to convert Jpeg, png images to
C# Create PDF from Raster Images, .NET Graphics and REImage File with XDoc Batch convert PDF documents from multiple image formats, including Jpg, Png, Bmp
.pdf to jpg converter online; convert pdf photo to jpg
VB.NET PDF Convert to Images SDK: Convert PDF to png, gif images
Convert PDF documents to multiple image formats, including Jpg, Png, Bmp, Gif, Tiff, Bitmap, .NET Graphics, and REImage. Turn multipage PDF file into image
convert pdf pictures to jpg; bulk pdf to jpg converter online
Set Variables Task
With all of the settings available as global variables, the Dynamic Properties task Set Variables
can be used to push the variables into the settings of the other tasks for the package, as shown
in Figure 8-21.
Figure 8-21.Configuring a Dynamic Properties task
Generally speaking, global variables can be used to set just about any aspect of a DTS
package, including properties that are exposed on custom tasks that you may use. You may
find that these standards work well as they are.
The result of this work for each DTS package is that when a package is deployed to another
environment, the only configuration change that needs to occur is the correct setting of the
xmlPathglobal variable—a minimum of manual effort and risk.
Note
There are other options as well.You could use a SOAP call or similar approach to dynamically load
the settings instead.
Summary
There has been a lot to learn in this chapter, but I hope you will agree that the results in terms
of describing the beginnings of a database integration framework are satisfactory. The work
highlights the fragility and lack of utility for such processes at this time, but with a toolset like
SQL Bundle and NAnt and a little thought and creativity, these processes can work. Discipline
CHAPTER 8 DATABASE INTEGRATION
277
C# WPF PDF Viewer SDK to convert and export PDF document to other
Convert PDF to image file formats with high quality, support converting PDF to PNG, JPG, BMP and GIF. C#.NET WPF PDF Viewer Tool: Convert and Export PDF.
change from pdf to jpg on; c# convert pdf to jpg
C# TIFF: C#.NET Code to Convert JPEG Images to TIFF
demo1.jpg", @"C:\demo2.jpg", @"C:\demo3.jpg" }; // Construct List in imagePaths) { Bitmap tmpBmp = new Bitmap(file); if (null Use C# Code to Convert Png to Tiff.
pdf to jpeg converter; convert pdf to jpg file
CHAPTER 8 ■ DATABASE INTEGRATION
278
is required to actually carry through these concepts to a production scenario, and if you
review the processes, you will identify risks that cannot easily be covered—such as “How do I
roll back in the event of a failure?” The scripts provide an easy means to handle such issues,
but they do not avoid the original problem. On the other hand, we suffer these problems daily
in any case.
In the next chapter, we will look at generating further efficiency to the delivery process
and the scripts through the use of code-generation techniques.
Further Reading
There are several Internet papers on the subject of agile database management and develop-
ment (as opposed to straightforward integration). These two are very worthwhile:
Evolutionary Database Design (http://martinfowler.com/articles/evodb.html)
XP and Databases (www.extremeprogramming.org/stories/testdb.html)
This book contains a great deal of techniques and suggestions on the same subject:
AgileDatabase Techniques:Effective Strategies for the Agile Software Developerby Scott Ambler
(Wiley, 2003).
Code Generation
T
he end of our exploration of automated builds and continuous integration (CI) approaches
rapidly. In the last couple of chapters we have looked at complicated techniques that could be
examined in even further detail. All of the configuration and script files we have used consist
of XML, and so the opportunities for the transformation of this information naturally present
themselves. This chapter explores these transformation and generation techniques, identify-
ing some suitable areas for consideration. Then, we wrap up by considering what has been
achieved through the Design to Deliver work.
Note
“Code generation”may be too grandiose a term for the transformation and production work in this
chapter,as of course the generation is of XML configuration and script files rather than code for compilation.
However,the term is a common and obvious one to use.
Why Use Code Generation?
When we began tackling automated builds and CI, we found that we could apply simple, but
strict, standards to ensure the compliance of relevant applications to remove the overhead in
maintaining differing build solutions for every system—the risk being that in fact we would
end up with a myriad of differing processes, too, which would not necessarily improve confi-
dence in the delivery phase of a project. Of course, the trivial examples of a book can only
touch upon the actual complexity inherent in the delivery of a software system, though we
have seen examples of additional complexity. In particular, our exploration of database inte-
gration has added significant additional infrastructure, process possibilities, and configuration
requirements to the mix. We are left with three core issues at this juncture:
Separation of concerns.Increasingly, the configuration information is becoming entwined
with the process descriptions: in NAnt-speak, more and more properties are required for
the build scripts. Although I have not paid as much attention to ensuring this is minimized
in the previous chapter, it would still be the case that information would be repeated and/or
included inappropriately as first-class information for a build script.
“Specific”system steps.We have spent some time factoring out the common aspects
ofbuild scripts and moving these to common locations. Some areas have not been
addressed adequately, such as the very specific documentation steps. Annoyingly, the
279
CHAPTER 9
■ ■ ■
CHAPTER 9 ■ CODE GENERATION
280
documentation step only differs according to the inputs rather than the process: the set-
tings for the <ndoc>task are the same in every case but the assemblies to be documented
differ.Additionally, some steps may differ because the process will vary slightly from sys-
tem to system. For instance, database integration could be handled in a few different
ways, as we discussed. These steps might differ from system to system.
Administration overhead.The two previous issues currently mean that there is a poten-
tial administration overhead to the maintenance of the delivery process. This comes from
a couple of directions. First, changes to process may mean multiple changes across multi-
ple systems where steps have been approximately the same. This means greater effort and
risk of change, and could therefore mean additional rigidity. Second, storing data such as
environmental information inside the build scripts means that it is likely this is repeated
information. Managing the knowledge of the development environment/network also
means managing the build scripts. So while we have gained efficiencies by using NAnt in
the first place, to protect this advantage we also need to take care of the effort involved
inusing NAnt, too.
To alleviate these problems, we can put more significant effort into common scripts and
common processes. As we have seen in previous chapters, this is an effective and recommended
practice, and it will work particularly well against a set of similar systems such as web/database
systems. We should remember that this is one of the core problems we originally set out to solve.
We could also put some effort into more advanced NAnt techniques—additional scripting
tasks and functions can perform more detailed analysis of source code and enhance the build
scripts. Again, a stated aim was to attempt to avoid too much “clever” decision making by
encapsulating logic in the build scripts, but some areas could be considered. One such poten-
tial solution is to perform more analysis of the solution file to glean further build information.
However, this approach is not effective in obtaining information such as deployment
environments, since such information is simply not held within the source code. 
A final problem is that some information is held in the CCNet configuration file and other
related (or even identical) information is held in the companion NAnt scripts. We could perhaps
use the <xmlpeek>task to read from the CCNet configuration file for some of the information,
but again, CCNet does not hold allof the required information.
The generation of the files through some automated mechanism is a possibility, because
it can solve all three of the issues rather than just one or two. In principle, we could take a
master file of data and process information and generate the CCNet, build, and deploy files
from this master. The drawback is that we need to provide an additional framework for the
process once more, but the advantages are that we tackle the issues in the following way:
Separation of concerns.Data will be held outside of the CCNet, build, and deploy scripts
in one common location. This data could therefore be fed by another system. All data is
held in the same location and so the impact of environmental changes on the delivery
process can be assessed and performed in the same location, using specific analytical
transforms of the same information.
“Specific”system steps.We can address specific system steps by having a catalog of
available differing steps to be generated according to flags in the master file. As already
mentioned, we cannot get away from the need to have specific steps, but with good refac-
toring efforts combined with generation techniques we can build up an options library to
cover many of the possibilities.
Administration overhead.Having the files for delivery automatically generated clearly
removes administration overhead from the scripts themselves. Administration is then tar-
geted solely at the master settings file. This minimizes the need to understand the entire
build process for the administration user and opens the door for automatic production of
this master file from some “systems catalog” or control center, which in turn could mean
a friendly UI for the management of delivery scripts.
So there is some virtue in investigating code generation techniques to further aid the
delivery effort. At this point, we will move on from the argument itself, and investigate the
useof code generation to provide build scripts.
Tools for the Task
There are a couple of major options for code generation in this instance: the use of XSLT, or
the use of some other code-generation harness.
Basic File Manipulation
By basic file manipulationI mean the use of file manipulation techniques such as AWK or
even NAnt’s own filterchainfunctionality (see Chapter 3) to perform token replacement of
varying degrees of sophistication. For example, regular expressions can perform some clever
token replacement beyond that of “Search and Replace.”
XSLT
XSLT is the natural choice for the transformation of XML into some other XML (or indeed
another file type). However, in this instance we will be taking a single XML source file and pro-
ducing multiple new XML files. This means that the process is not simply a case of producing
the XSLT required for transformation. There needs to be other constructs and a framework to
ensure the production of the required files. 
This in itself is not such a serious problem. It is something of a cop-out because I am not
very good at XSLT. If, like me, you find using XSLT a bit confusing, you might want to consider
the next option.
CodeSmith
Actually, CodeSmith is not the only option—several tools of the same ilk are available.
CodeSmith (www.ericjsmith.net/codesmith) is a code-generation application. It allows the
production of template files, which are compiled and executed against supplied parameters
allowing the generation of all manner of code files. Generally, these tools are seen as a useful
way to provide such services as data access layers for applications (though if you are inter-
ested in this, I might suggest LLBLGen Pro [www.llblgen.com] or other similar tools built
specifically for that task), but in fact code generation can be used in many places to enhance
productivity.
CodeSmith comes in two flavors: the first is the free download that can be used to com-
pile and run the template files (.cst); the second is the CodeSmith Studio application that
offers an environment for the production of the template files, and improved feedback on
CHAPTER 9 ■ CODE GENERATION
281
template generation. It costs a little, but if you become “code generation infected,” then it is
well worth the cost. I imagine that you will save the expense in no time at all once you put the
tool to use.
Tip
On the CodeSmith web site,many people contribute templates and the like for anything from data
access to design pattern implementations.It is a very useful resource.
What are the advantages and disadvantages of each approach? Table 9-1 shows the
differences.
Table 9-1.Comparing Code-Generation Techniques
Token 
Feature
Replacement
XSLT
CodeSmith
Easy to use
Platform portability
Harness/scaffolding present
Handles decision-making logic
Both XSLT and CodeSmith are likely to be the most useful for the process, thanks to the
power and flexibility they deliver. We will use both of these technologies to deliver code gener-
ation to our processes. We will look at the scaffolding to harness XSLT to deliver the files we
need and also see how CodeSmith can deliver the same. It is worth investigating a text on
XSLT (see “Further Reading”) since it is too large a subject to consider in depth here. There is
no other reference on CodeSmith, apart from the help files, so let us begin with it.
Investigating CodeSmith
Before we begin the actual work of providing code-generation capabilities for the delivery
process, we can investigate some features of CodeSmith to ensure that it can provide what we
need. Figure 9-1 shows the CodeSmith IDE. If you do not wish to purchase CodeSmith, you
can download a simple version that allows the execution of templates but does not offer the
added help of the IDE. Take a look at Appendix A for further information.
The IDE consists of three areas. To the left is the editing window, which lets you construct,
compile, and execute templates. To the right at the top is the available linked folders providing
rapid access to template files. To the right at the bottom are the properties relating to the cur-
rently open template file.
CHAPTER 9 ■ CODE GENERATION
282
Documents you may be interested
Documents you may be interested