Download as pdf or txt
Download as pdf or txt
You are on page 1of 9

English

Technical topics Evaluation software Community Events


Create Distributed DB2 and Delphi Web Apps with
DataSnap
Bob Swart (drbob@chello.nl), Author, Trainer, Consultant and Webmaster, Bob Swart Training and Consultancy
Summary: This article shows you how to create distributed applications with thin clients and a database serer
tier using Borland !elphi"#yli$"C%% Builder and !B&.
Date: '( !ec &))&
Level: *ntroductory
Activity: +,-, iews
Comments: ) (.iew / Add comment 0 Sign in)
Aerage rating (12 otes)
3ate this article
*ntroduction
*n the past 4ew articles, * hae written db5$press applications in !elphi
T6
to access data 4rom the !B&7 SA6895
database . * hae also shown how to migrate this application to 9inu$ (recompiling with #yli$
T6
) and een how to
use WebSnap
T6
to produce a Web serer application. This time, you:ll enter the world o4 distributed applications,
where you:ll split the original Windows application in two di44erent tiers; a thin client and a database serer tier. *:ll
4ocus especially on the serer side, as well as the communication between the (thin) client and the middleware
serer.
<nderstanding !ataSnap multitier applications
Borland7 !elphi and C%%Builder
T6
contain special wi=ards and components (collectiely >nown as !ataSnap
T6
)
to help deelopers build multi0tier applications. A !ataSnap serer is an application that runs on a (serer)
machine, and is connected to the !B6S0the !B& SA6895 database, in this case. ?or one !ataSnap serer, you
can hae multiple !ataSnap clients that connect only to the !ataSnap serer and not to the !B6S itsel4. *n 4act,
the !ataSnap client doesn:t een hae to >now which !B6S it connects to (ia the !ataSnap serer). This
approach turns the !ataSnap client into a so0called thin0client, since no database0speci4ic driers are re@uired on
the client machines. And the !ataSnap serer can een migrate 4rom one !B6S to another without haing to
change the clients at all.
Start by building a !ataSnap serer in !elphi A. Bou can use a number o4 components 4rom the preious Windows
application, but in di44erent places. Coweer, it can be insight4ul to compare the two di44erent approaches, and see
where you split the application in two (right between the T!ataSet8roider and TClient!ataSet components,
placing a special connection component in between).
To build a !ataSnap serer in !elphi 5nterprise,
1. Do File > New Application to start a new project. The main form will only identify that the DataSnap server
is running, so you may want to resize it and add a label to it in order to easily identify it (once its running!.
Save the main form in DataSnap"orm.pas and the project in DataSnapServer.dpr.
#. $ DataSnap server re%uires a data module that can communicate with e&ternal client applications. Such a
data module is called a 'emote Data (odule, and you can create one using the wizard found in the )bject
'epository* do File > New > Other, go to the (ultitier tab, and double+clic, on the 'emote Data (odule
icon. This results in the 'emote Data (odule -izard, where you only have to specify the .o.lass /ame of
your DataSnap server (see "igure 1!.
Figure 1.Remote Data Module Wizard
0. The options for 1nstancing and Threading (odel are already set to the most common values (see the online
help for more details about the alternative choices!, so leave them set. .lic,ing on )2 generates a new
'emote Data (odule for you. Save this unit in file RDataMod.pas.
$dding the remote data module
3ou want to mimic the application youve built before, but this time as a DataSnap server, which means you must
4stop4 after the TDataSet5rovider (and continue inside the DataSnap client with a connection component and
T.lientDataSet!.
6ecause you want to use db7&press
T(
again, first drop a TS89.onnection component on the 'emote Data
(odule. Set its .onnection/ame property, chec, the connection parameters (see if :ser;/ame and 5assword have
a value!, and finally ma,e sure that the 9ogin5rompt property is set to "alse. 1f you can set the $ctive property to
True without problems, you ,now for sure that you can ma,e a connection to the D6# S$(597 database (see the
previous articles or this articles source code for more details!.
3ou now need to drop four TS89DataSet components, one for each of the four D6# tables that you want to use in
this application again (7(59)377, 7(5;$.T, 7(5;5<)T), and 7(5;'7S:(7!. <ere are the steps to
configure the components*
1. Drop a TS89DataSet component from the db7&press tab onto the 'emote Data (odule, call it S89ds7(5,
point its .onnection property to S89.onnection1, and set its .ommandType property to ctTable and its
.ommandTe&t property to 7(59)377.
#. Drop a TDataSet5rovider component from the Data $ccess tab, call it dsp7(59)377, and point its
DataSet property to S89ds7(5.
0. Do the same thing for 7(5;$.T, 7(5;5<)T), and 7(5;'7S:(7, but this time use TS89Table
components (so you do not have to set the .ommandType and .ommandTe&t, but can directly select a
Table/ame!. The 'emote Data (odule should now loo, li,e this (see "igure #!*
Figure 2. DataSnap Remote Data Module
4. Save your project, recompile the DataSnap server application, and run it once to register it on the server
machine.
Compared to the dbExpress application you built earlier, the difference is that you can use the DataSetProvider
components not only to connect to a local ClientDataSet !residing in the same tier", but also to connect to a
remote ClientDataSet#in a remote client application, as you$ll no% build.
Create the DataSnap client
& DataSnap client application can be any 'ind of application#from regular ()* to +eb server. Since the ,emote
Data -odule inside the DataSnap server is a C.- server, you are limited to +indo%s clients, ho%ever !although
it$s possible to create DataSnap servers and clients using S.&P as communication protocol#transforming the server
into a +eb service and the client into a consumer of the +eb service#but that$s a story for another day".he steps to
building a basic DataSnap client are/
0. 1uild a regular application again#the DataSnap client#using File > New Application. Save the main form in
ClientForm.pas, and the application project in DataSnapClient.dpr.
2. -a'e a connection from the DataSnap client to the DataSnap server, using one of the available connection
components from the DataSnap tab of the Component Palette. &vailable choices are/ DC.-Connection,
Soc'etConnection, and +ebConnection. he first uses DC.- as the communication protocol3 the
second, CP4*P soc'ets3 and the last one, 5P. 6ote that the second and third solutions re7uire additional
soft%are !at the DataSnap server machine"/ the 1orland Soc'et Server is re7uired for the CP4*P soc'et
connection, %hile a +eb server !li'e **S" and the httpsrvr.dll *S&P* D88 are re7uired to allo% the +eb
connection to %or'. 9or no%, use the DC.-Connection component !and refer to the online help for details
about using the other communication protocols".
:. Drop a DC.-Connection component on the DataSnap client form, and open the drop#do%n combobox for
the Server6ame property. his should sho% a list of all registered DataSnap servers %ith their ,emote Data
-odules that are available on your machine !%hich may be only one/
DataSnapServer.,emoteData-oduleD12". Select DataSnapServer.,emoteData-oduleD12, and set the
Connected property to rue to verify that you can start the DataSnap server from the DataSnap client
application. Set Connected bac' to 9alse. 6ote that for a connection to a remote DataSnap server, you also
need to specify the Computer6ame property of the DC.-Connection component !%ithout this specified,
you$ll be tal'ing to localhost itself".
4. 9or each of the four S;8DataSet components on the DataSnap server side, drop a ClientDataSet
component here on the client side. Call them cdsE-P, cdsE-P<&C, cdsE-P<P5.., and
cdsE-P<,ES)-E. Connect their ,emoteServer properties to DC.-Connection0 !the connection
component that forms the gate%ay to the DataSnap server". 6ext, open up the drop#do%n combobox for their
Provider6ame properties, and select dspE-P8.=EE, dspE-P<&C, dspE-P<P5.., and
dspE-P<,ES)-E, respectively. +hen you activate the ClientDataSet components, they %ill use the
DC.-Connection component to connect to the DataSnap server, and re7uest !and receive" their data from
the corresponding DataSetProvider component. >ery convenient.
&nd again, this time you$re using DC.-, but you can also use CP4*P soc'ets or 5P as the
communication protocol bet%een the DataSnap clients and the DataSnap server.
?. 9inish the DataSnap client application by dropping four DataSource components on the form, name them
dsE-P, dsE-P<&C, dsE-P<P5.., and dsE-P<,ES)-E, and connect each of them to one of the
ClientDataSet components !%ith a corresponding name, of course".
Establish master#detail relationships
1efore you can drop data#a%are controls and build a similar ()* to %hat you$ve done before !%ith the plain
dbExpress components", you must first add the master#detail relationships bet%een the E-P8.=EE !master" table
and the other three !detail" tables. =ou can build the master#detail relationship in one of t%o %ays/ at the server or
at the client. Since you already retrieved four individual datasets from the server, it$s easier no% to build the master
#detail relationships on the client using the existing ClientDataSet components. o build this/
0. *n the cdsE-P master table, you must loo' at cdsE-P<&C, cdsE-P<P5.., and cdsE-P<,ES)-E
and point their -asterSource properties to dsE-P !the DataSource connected to the cdsE-P master table".
2. .nce the connection exists, specify the -aster9ields property for each of the three detail tables, and connect
the E-P6. fields from both the master and the detail table!s" using the 9ield 8in' Designer dialog.
:. Drop a D16avigator !connect its DataSource to dsE-P", t%o D1(rids !connected to dsE-P and
dsE-P<&C", a D1-emo !connected to dsE-P<,ES)-E and the ,ES)-E field", and finally a
D1*mage component !connected to dsE-P<P5.. and the P*C),E field". his results in the follo%ing
client form for me !see 9igure :"/
Figure 3. DataSnap Client Form at design time
+hile 9igure : may loo' nice, and may loo' similar to the single#tier dbExpress application you %rote earlier !as
%ell as the +ebSnap +eb server application you %rote later", you$ll have some problems if you actually %ant to
use this application to save changes and update the !remote" database again.
Applying updates to DB2
Just like the single-tier dbExpress application, you have to use a call to ApplyUpdates (a ethod !ro the
"#lientData$et coponent% to apply any updates-inserts, edits, and deletes-back to the Data$nap server so it can
generate a $&' Update stateent that (ill be sent to the DB2 $A)*'E database+ ,o(ever, having !our
"#lientData$et coponents eans that you have to be care!ul in (hich order you can apply the updates+ -hen
deleting an eployee, !or exaple, you ust !irst delete all detail records, and hence call ApplyUpdates on the
detail "#lientData$et coponents be!ore you can call ApplyUpdates on the aster "#lientData$et coponent+
,o(ever, (hen adding a ne( eployee, including activities, resue, and photo, you should !irst call
ApplyUpdates on the aster be!ore trying to call ApplyUpdates on the details (other(ise there (on.t be a
corresponding eployee !or (hich you enter activities, a photo, and resue%+ And i! that doesn.t get coplex
enough, consider the case (here an error occurs and you (ant to roll back soe changes+ -ith !our separate
"#lientData$et coponents, you ay !ind this a burden that you don.t (ant to deal (ith+
And the good thing is that you don.t have to deal (ith it, because you can /package/ all !our tables in one atoic
entity, and call a single ApplyUpdates action instead o! !our separate ones+ "he techni0ue to do this involves
de!ining the aster-detail relationship at the Data$nap server (instead o! at the client%, and thereby receiving and
unpacking a so-called nested table at the Data$nap client+
1+ $tart (ith the aster-detail relationships at the server side, so return to the Data$nap server pro2ect+ 3irst o!
all, reove all Data$et*rovider coponents except the one that points to the $&'dsE)* aster table+
2+ 4ext, you need one "Data$ource coponent, pointed to $&'sdE)*+ And no( all three "$&'"able
coponents ust point their )aster$ource properties to the Data$ource coponent (this is actually the
reason (hy 5 used "$&'"able coponents !or the three detail tables, since a "$&'Data$et has no
)aster$ource property%+
6+ #lick on the )aster3ields property o! the three detail $&'"ables and speci!y the E)*47 !ields to de!ine
the aster-details relationship again+ "he odi!ied 8eote Data )odule should look like this no( (see
3igure 9%:
Figure 4. Modified DataSnap Remote Data Module
4ote that you have only one Data$et*rovider coponent le!t: connected to the Eployee table+ But together
(ith the Eployee data, the other three tables (ill be packaged along, as you.ll see in a oent+
9+ Be!ore you can return to the Data$nap client, recopile the Data$nap server application again+
;+ Back at the Data$nap client, you should clear the 8eote*rovider properties o! the cdsE)*<A#",
cdsE)*<*,7"7, and cdsE)*<8E$U)E "#lientData$et coponents, because the three re!erring
"Data$et*rovider coponents have been reoved !ro the Data$nap server (soething that (ill not result
in a copiler error, but only an error essage at runtie, by the (ay%+
=+ Besides clearing the )aster$ource property, you ust also clear the )aster$ource and )aster3ields
properties+
>+ Double-click on the cdsE)* coponent to start the 3ields Editor+ 8ight-click inside the 3ields Editor and do
/Add All 3ields/+ As a result, you not only see all !ields !ro the Eployee table, but also three special
!ields called $&'tblE)*<8E$U)E, $&'tblE)*<*,7"7, and $&'tblE)*<A#"+ "hese three !ields are
o! type "Data$et3ield, and are in !act /nested datasets,/ since they contain the detail records (!or 8E$U)E,
*,7"7, and A#"% that belong to the current aster eployee record+ "hey.re inside that sae record,
packaged into one entity-aking it convenient to receive, and use to apply updates ((hich you.ll do in a
oent again%+
8. Once you have added the persistent fields (in the Fields Editor), select the cdsEMP_AC and set its
!ata"etField property to cdsEMP"#$t%lEMP_AC. &e't, set the !ata"etField property of
cdsEMP_P(OO to cdsEMP"#$t%lEMP_P(OO, and the !ata"etField of cdsEMP_)E"*ME to
cdsEMP"#$t%lEMP_)E"*ME. his +ill ,a-e sure that the three detail Client!ata"ets are connected.via
the ,aster cdsEMP dataset.
/ou don0t have to chan1e anythin1 in the !ata"nap client application2 3ust reco,pile and run it. he data +ill sho+
3ust as in Fi1ure 4 %efore. Only this ti,e, you can add a %utton that can send all updates (inserts, edits, deletes) in a
sin1le Apply*pdates call instead of four separate calls. "o, drop a 5utton co,ponent, call it %tnApply*pdates,
set its Caption property to Apply *pdates, and +rite this sin1le line of code in the OnClic- event handler6
procedure TForm3.btnApplyUpdatesClick(Sender: TObject)
be!in
cds"#$.ApplyUpdates(%)
end
"ee the online help for ,ore details on the Ma'Errors ar1u,ent as +ell as the a%ility to respond to so.called
)econcile Errors +hen other users have ,odified the sa,e records and applied their updates %efore you.
Apart fro, the sin1le call to Apply*pdates, you should also +rite so,e code for the OnCreate and On!estroy
event handlers of the !ata"nap client0s for,, to e'plicitly open the cdsEMP Client!ata"et co,ponent (+hen the
application starts), and to chec- if any chan1es have %een ,ade to ,a-e sure Apply*pdates is called (+hen the
application is shut do+n a1ain). /ou ,ay +ant to as- your end.user for confir,ation, %ut 7 leave that as an
e'ercise for the reader.
procedure TForm3.FormCreate(Sender: TObject)
be!in
cds"#$.Acti&e :' True
end
procedure TForm3.Form(estroy(Sender: TObject)
be!in
i) cds"#$.C*an!eCount + % t*en
cds"#$.ApplyUpdates(%) ,, )orce any pendin! updates-
end
After this code has %een +ritten, you can set the Connected property of the !COMConnection co,ponent to
False (at desi1n ti,e), as +ell as the Active property of the four Client!ata"et co,ponents. his is i,portant
%ecause +hen you load the !ata"nap client pro3ect and either the !COMConnection or the Client!ata"et
co,ponents are 8active8 at desi1n ti,e, then !elphi +ill try to esta%lish a connection +ith the !ata"nap server.
his +ill +or- 3ust fine on ,y develop,ent ,achine (+here the !ata"nap server has %een co,piled and
re1istered), %ut it ,ay not +or- on your ,achine +here the !ata"nap server is pro%a%ly un-no+n (until you
co,pile the pro3ect and run the e'ecuta%le). his +ill cause desi1n.ti,e delays and errors.deactivatin1 the
offendin1 connection co,ponent or datasets %efore you can continue.
!eployin1 the !ata"nap server
Finally, in order to deploy the !ata"nap server, you need a ,achine fro, +here it can access the !59 "AMP$E
data%ase, of course, as +ell as the d%E'press !59 driver and the #.(AS.(//. For a !ata"nap client, you have to do
less +or-6 all it needs is the client e'ecuta%le and the #.(AS.(// (and if you co,pile your pro3ect +ith the
Midas$i% unit, you +on0t even need to deploy the #.(AS.(//, resultin1 in a standalone e'ecuta%le as !ata"nap
client).
There used to be a deployment license with runtime fees associated with DataSnap, but as of Delphi 7, anyone with
a developer license of Delphi 7 Enterprise or later (the version required to build DataSnap servers and clients in the
first place) can freely deploy DataSnap applications-both servers and clients !or Delphi " or #$$%uilder "
Enterprise, there&s still a runtime fee required of about '()* (+SD) per DataSnap server machine See the %orland
,eb site for details
#onclusion
-f you are interested in DataSnap server applications, to ma.e the tables and data from a D%( D%/S available to
DataSnap thin clients, then wait until you see the ne0t article, which combines DataSnap with S123 This
combination results in a cross-platform technique that you can use with 4yli0 (Delphi and #$$ editions) on 5inu0
as well as Delphi and #$$%uilder on ,indows, where either the DataSnap server or client (or both) can run on
5inu0 instead of ,indows 6ou can even mi0 clients-havin7 one set runnin7 on ,indows and another on 5inu0,
with DataSnap servers that can run on both ,indows and 5inu0 (only a simple recompile is needed to mi7rate
them)
Download
Description Name Size Download method
Sample code source8ip 9(4% :TT3
-nformation about download methods
2bout the author
%ob Swart (a.a Dr%ob - wwwdrbob;(com) is an author, trainer, consultant and ,ebmaster wor.in7 for his own
company called %ob Swart Trainin7 < #onsultancy (e%ob;() in :elmond, The =etherlands %ob, who writes his
own Delphi trainin7 material, has spo.en at Delphi and %orland Developer #onferences since 9))> %ob has
written hundreds of articles, and is co-author of the ?evolutionary @uide to Delphi (, Delphi ; +nleashed,
#$$%uilder ; +nleashed, #$$%uilder * Developer&s @uide, 4yli0 Developer&s @uide, Delphi " Developer&s @uide,
and the upcomin7 #$$%uilder " Developer&s @uide
#lose A0B
developerWorks: Sign in
-%/ -DC
=eed an -%/ -DD
!or7ot your -%/ -DD
3asswordC
!or7ot your passwordD
#han7e your password
4eep me si7ned in
%y clic.in7 Submit, you a7ree to the developer,or.s terms of use
Submit Cancel
The first time you sign into developerWorks, a profile is created for you. Select information in your
developerWorks profile is displayed to the public, but you may edit the information at any time. Your first
name, last name (unless you choose to hide them), and display name will accompany the content that you post.
All information submitted is secure.
lose !"#
Choose your display name
The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name.
Your display name accompanies the content you post on developerWorks.
Please choose a display name between 3-31 characters. Your display name must be uni$ue in the
developerWorks community and should not be your email address for privacy reasons.
%isplay name& ('ust be between ( ) (* characters.)
+y clicking Submit, you agree to the developerWorks terms of use.
Submit Cancel
All information submitted is secure.
Average rating ((, votes)
* star * star
- stars - stars
( stars ( stars
, stars , stars
. stars . stars
Submit
Add comment
/ign in or register to leave a comment.
0ote& 1T'2 elements are not supported within comments.
0otify me when a comment is added*333 characters left
Post Post
+e the first to add a comment
Print this page Share this page Follow developerWorks
About
Help
Contact us
Submit content
Feeds and apps
Newsletters
Report abuse
Terms of use
IBM privacy
IBM accessibility
Faculty
Students
Business artners

You might also like