Creating multi-tier information systems using MIDAS
Natalia Elmanova
Note: The following paper was presented at the 1999 Inprise/Borland Conference in Philadelphia Pennsylvania. Click on the
source code link to download the examples used in this paper.
This session is devoted to creating multi-tier information
systems with Inprise MIDAS (Multi-tier Distributed Application
Service Suite). Using MIDAS is a very effective way to solve many
problems concerning data access maintenance in client/server
systems. Multi-tier systems with MIDAS are easy to configure,
maintain and update.
This technology and software are designed to maintain remote
COM and CORBA data access servers created with C++Builder or
Delphi. In most cases these servers provide their clients with an
access to SQL servers, but it is possible to use any DBMS as a
data source.
MIDAS Development Kit is a part of Delphi Client/Server Suite
and C++Builder Enterprise. You can use it to develop data access
servers (but not to deploy them).
The questions to be discussed are:
This section describes problems of data access support and
fail-over safety of information systems, as well as the ways of
solving these problems, including the use of multi-tiering.
The classic two-tier client/server information
system contains:
- A database server for managing a database which contains
tables, indices, triggers, and other objects for storing
data and business rules;
- One or more client applications which contains the user
interface (forms, etc.), the code for data processing and
data access, and, in most cases, data access libraries
(Fig. 1).

Fig. 1. Standard two-tier information system
In most cases, client applications use directly DBMS client
API calls (for example, by using Oracle Call Interface, etc.) or
by means of intermediate libraries, such as Borland Database
Engine (BDE). Therefore, the client application requires a DBMS
client software to be installed and configured. In addition, it
often requires BDE to be installed and configured too. It is
possible that the client application requires the use of ODBC
drivers. So, usually the system administrator or software
developer must take care of:
1) installing the DBMS client software and configuring it for
a successful database server access;
2) installing BDE and SQL Links, configuring database drivers,
creating and configuring aliases;
3) installing ODBC drivers and ODBC administrator, describing
ODBC Data sources;
4) and, finally, providing enough resources for data access.
ODBC driver, some libraries from BDE and SQL Links, DBMS client
software libraries must stay in memory while the client is
working with data; so they require some resources of client
workstation.
If we want to deploy our client application by creating
installation with InstallShield Express, we can solve correctly
only the second problem. In most cases, we cant include
DBMS client software into this installation, because we must buy
and use DBMS vendor installations and follow the license
agreements. In many cases, we must also install ODBC drivers
separately.
Let us assume that we have solved all these four problems.
What happens if the chief system administrator decides to change
DBMS server IP address after configuring all data access software
at thousand workstations?
The reality is that the more complicated the software
configuration is, the more often it is destroyed spontaneously.
Reconfiguring and supporting software spends your time (three
days or more per workstation during a year), and money.
It seems strange, but there is another problem connected with
a very high popularity of Delphi, C++Builder, and Borland C++
(opinion polls show that more than 60% of developers use these
tools in Russia). There is a lot of different commercial
software, which uses BDE (reference books, directories, guides,
etc) in the market now. In this case, there is not any guarantee
that the BDE version installed with this product is up-to-date or
at worst it is not older than the BDE version used in your
information system. There is also no guaranty of the correctness
of this installation. For example, it can replace all BDE
configuration files and registry entries. It is against the
rules, but, unfortunately, it happens very often
And, of
course, Your client applications may begin working improperly
(or, very likely, may become non-functional at all) after
installing such software over them.
I know many cases of producing such software. One of my
colleagues (he is a software developer from one of the European
countries) told me an "unsuccess story". In his country
a telephone directory written with Delphi 2 was released as CD.
Delphi 3 was released when this CD was being produced. So there
had been some information systems developed with Delphi 3 before
this telephone directory CD become available. Shortly after
releasing this CD, many of client applications of information
systems written with Delphi 3 began to work improperly. The
reason was that the users of these information systems have
installed the telephone directory from this CD, thus replacing
their BDE with its older version. Who do you suppose these users
claim the rights to? Please believe me, it was not a phone
directory developer
It was Delphi 3 programmers who
received much reclamation from their customers! The main argument
of reclamation was that this phone directory was on sale in all
shops, so it seemed to be a high-quality product. My colleague,
who told me this story, received such reclamation, because he
used the latest Delphi version.
What should be done for this problem not to arise at all? We
can, certainly, use Delphi 1 or Delphi 2, but it is not a good
way (and somebody can produce such "phone directory" by
Borland C++ 4.5 with BDE being older than in Delphi 1.0).
We have not yet discussed many other problems connected with
high network traffic due to a database growth. They can be
partially solved using SQL servers instead of desktop or network
file-oriented databases, but in some cases these problem cannot
be solved on the whole. Neither have we discussed the problems of
using some shared resources (for example, a high-speed
multiprocessor server that can process data more effectively than
client workstations). Neither have we considered the problems
linked to territory scattering of some enterprises (it is a
typical situation in gas and oil mining plants in Siberia), or to
low quality of flow lines (another typical situation for gas/oil
plants: the flow line was destroyed by landrover, it needs to be
repaired, but now it is a long polar night and blizzard - and
users do not know what to do with their cached updates
).
So, as a rule, software developers and system administrators
have a serious headache due to installing, configuring and
maintaining data access software, preventing the users from
"phone directories", and solving other problems
described above. How to get rid of this headache?
The guillotine can be a solution of a headache problem (it
seems to be too radical, but works for sure). In this case, it
means that we use guillotine to split our client application up
into two parts. These parts are appreciably different in their
interface and functionality.
The first part contains only the users interface (forms,
etc.). We can call it a thin client. It must be
installed on user workstations. It does not contain BDE (or BDE
replacements), ODBC, and DBMS client software.
The second part is a data access server. It has a minimal user
interface (or it has no user interface at all). But it is a real
client of SQL server, so it uses BDE, DBMS client software, and
possibly ODBC. It must not be installed on user workstations, and
it can exist on one or several computers in a local area network.
You can configure your network to prevent a direct user access to
the corresponding directories of these computers. This part can
also implement the functionality different from the data access
(for example, calculating something, generating repots, etc.). In
this case we can think of it as a functionality server. Data
access is, undoubtedly, one of the possible functions of such
servers.
There can be a lot of "thin" clients in the
information system. As for data access servers, there must be a
few of them (1,2,3
). They can be installed on computers,
which are under the system administrator control and are
inaccessible for other users.
"Thin" clients do not obtain data from the database
server directly by client API calls or using BDE. Instead of
obtaining data directly form the database server, they obtain
data from the data access server, which is a data source for
them. The data access server gets client queries and connects to
the database server with its own query, because it is a real
client of the database server. After obtaining the query result,
the data access server passes the requested data to the
"thin" client.
In this case, the client software of DBMS server, ODBC drivers
and BDE (or any BDE replacement) should not be installed at user
workstations. The thin client needs the only library
to support obtaining data from the data access server (in MIDAS
case it is dbclient.dll). The thin client must also
know, where the data access server is, and what its
name (or GUID Global Unique Identifier, or UUID
Universal Unique Identifier) is. Or, in a general case, it must
know where the directory service, which must find a computer with
server implementation, is.
Therefore, our information system becomes a 3-tier, and the
data access server is a middle-tier in it. We can say that it is
a middleware server implementing the middleware service(s) (Fig.
2).

Fig. 2. A three-tier
information system
This section describes different ways to create a
distributed data processing system. It also describes the
conditions under which the use of OLE Automation for creating
data access servers is reliable.
How to realize this technology in practice? There are many
ways to do it.
All these ways are based on the old idea of RPC and
marshalling. Marshalling is a data packet exchange between an
object inside the client application (it is called a client stub
or a proxy) and another object inside the server process (it is
called a skeleton or a server stub). The particular terminology
depends on the technology implementing the distributed computing.
The server stub is created inside the server process when the
server receives a client call. It represents the client in the
server process, so the server thinks that it works
with its local object. There can be one or many such stubs. Their
quantity depends on the number of clients, share rules, etc.
Client stub is created in the client process. It represents the
server in the client process, so the client also
thinks that it works with its local object. It
usually has the same list of methods as the corresponding server
stub, but it never contains their real implementation. Instead of
real implementation it may contain a special proxy code, for
example, with API calls to libraries responsible for creating
data packets, marshalling them to the client by any possible way
(for example, writing to sockets, etc.) and unmarshalling other
packets with the results of requests and queries, which are
received from the server stub (Fig. 3).

Fig. 3. Remote procedure calls
In particular, distributed computing can be based on DCE
(Distributed Computing Environment), CORBA (Common Object Request
Broker Architecture), etc., and in these cases we can choose a
non-Windows platform for server and client.
But if it is desirable to make Windows distributed
applications without spending a lot of money, we can use COM, and
remote Automation in particular (of course, it is based on the
same idea of RPC and marshalling). Automation allows us to
operate some applications (they are known as Automation servers)
by other applications (they are known as Automation controllers).
Automation servers must expose some methods for such operation.
In this case, we can create our data access server as a remote
Automation server. This Automation server can create remote COM
objects inside its address space, and these COM objects must
contain data access components and interfaces to reach them. In
this case, we can use Windows for both a client and a server
application.
This section contains a detailed example of building data
access server with a Remote Datamodule containing several tables.
To create a data access server, we must have any DBMS with
some tables. Our example uses Oracle Workgroup Server 8.0.4 for
Windows NT, but it does not matter what DBMS is used (you can
even use dBase or Paradox tables of DBDEMOS database).
To illustrate this, we must create a new database user (if we
use Oracle, we must grant roles CONNECT and RESOURCE for it),
login to the server as a new user, and copy CLIENTS.DBF and
HOLDINGS.DBF tables from DBDEMOS database to Oracle by means of
the Data Migration Wizard. Now we are ready to create our data
access server.
Let us create an ordinary form, which must be an indicator of
a server being running. So it must not be large, and it is better
to place it on the screen corner and set its FormStyle property
to fsStayOnTop (Fig. 4).

Fig. 4. The main form of the data access
server
It should be mentioned that it is not necessary to create the
main form at all, because most of such servers do not have any
user interface. However, we have already created the main form.
So let us place the TLabel component on it and set its Caption
property to "0" . This label will be used later as a
client counter. Let us also place the TDatabase component on this
form and set its properties, as shown in Fig.5:

Fig. 5. TDatabase
properties of the main form
It is necessary to uncheck the Login Prompt checkbox and to
enter the password value into the Parameters list. Why is it so
important? Because the user access dialog must appear in a
database client application. It means that it must appear in a
data access server, but not in a "thin" client
application, which is actually controlled by the user. However,
in a general case a client application and a data access server
can be executed on different computers (and, possibly, in
different countries!). Therefore, we must prevent the appearance
of this dialog by all means.
It does not mean, of course, that the user access to the
database with the user name and password is impossible in a
3-tier system. We shall discuss this task later.
Then let us open the Object Repository of Delphi or C++Builder
and choose the Remote Data Module icon (Fig.6).

Fig. 6. Choosing Remote Data Module from
Object Repository
Remote Data Module is a COM object, and it can provide
interfaces, which are used by its clients.
After choosing the Remote Datamodule icon from the Object
Repository, the Remote Data Module Wizard must show us its
dialog. We are to type the Class Name for storing information
about this server in the Registry. All COM servers are to be
registered in the Windows Registry, because COM uses it as an
implementation repository and an interface repository.
We must also select how many instances of Remote Data Module
our server can create. The Multiple Instance option (it is
the default option) means that the server can create many
instances of Remote Data Module. The Single Instance
option means that the server can create only one instance of
Remote Data Module, so it is necessary to run a separate server
instance for any client. The Internal option is not
interesting for this case. It means that we must create a DLL,
and it would be difficult to make the server to be remote in this
case (some possibilities of creating such remote servers will be
discussed later).
Then we can place two TTable components to our Remote Data
Module. Let us bind them to the TDatabase component placed on the
main form earlier, and set their TableName properties to CLIENTS
(Table1) and HOLDINGS (Table2). Let us also place the TDataSourse
component and bind it to the Table1 component (Fig.7).

Fig. 7. Components in Remote Data Module
The next step is to create a Master-Detail relationship
between these tables (the ACCT_NBR field is a common one for both
tables).
Now our project contains the following parts (Fig. 8):

Fig. 8. Data access server project
Thereafter, we can right-click on the Table1 component and
select an Export Table1 from data module option from
the pop-up menu.
Now the properties and methods for the data access are
available to clients in the COM object interface. You can open
the Type Library editor and find them. Type Libraries store an
interface definitions for COM objects, and they are often used in
COM servers (and, sometimes, in COM clients, Fig. 9):

Fig. 9. The Type Library of the Remote Data
Module
In a general case, it is reliable to store the GUID (Global
Unique Identifier) of MyRDM CoClass in a text file somewhere in a
shared network disk, because we shall use it later.
Then we must refer to the main form in the RemoteDatamodule
unit. Now let us create two event handlers of the Remote Data
Module to update the client counter placed on the main form.
C++Builder code for these handlers is:
void __fastcall TMyRDM::MyRDMCreate(TObject *Sender)
{
Form1->Label1->Caption =
IntToStr(StrToInt(Form1->Label1->Caption)+1);
}
//------------------------------------------------------------
void __fastcall TMyRDM::MyRDMDestroy(TObject *Sender)
{
Form1->Label1->Caption =
IntToStr(StrToInt(Form1->Label1->Caption)-1);
}
The corresponding Delphi code is:
procedure TMyRDM.MyRDMCreate(Sender: TObject);
begin
Form1.Label1.Caption := IntToStr(StrToInt(Form1.Label1.Caption)+1);
end;
procedure TMyRDM.MyRDMDestroy(Sender: TObject);
begin
Form1.Label1.Caption:= IntToStr(StrToInt(Form1.Label1.Caption)-1);
end;
(We have used bold characters for parts of these event
handlers, which must be typed manually).
Now we can save, compile and run the server. As a result, it
must have been automatically registered in the Windows Registry
(You can use Regedit utility to check it). Now it is ready for
use.
What is the main part of this data access server
functionality? SQL queries are. Our server uses the Borland
Database Engine to generate them. In a general case, such servers
can use other ways to generate SQL queries.
It was mentioned above that the main form is not an essential
part of the data access server. Such servers can be made as a
console application or as a Windows NT service. In a general case
such servers can be created for non-Windows platforms. It is
clear that in these cases GUI may be unavailable at all.
This section contains a detailed example of creating a
"thin" non-configurable client with TCP/IP access in
the form of a Windows application. This example must contain a
TClientDataSet component with a "nested" table
emulation for representing a master-detail relationship.
Let us make a client application. For example, let it use the
TCP/IP protocol to reach the server.
First, we must run Borland Socket Server (scktsrvr.exe) in
Delphi 4Bin or CBuilder4Bin (it is also available as a service,
if necessary) at the PC, where our data access server must be
running. Later we shall discuss the role played by such services,
and why we must use them.
Second, let us create a new project. It is possible to do it
using both the server computer and any other computer. Of course,
the client PC and server PC must be able to reach each other via
the TCP/IP protocol.
Third, we must place the TSocketConnection component on the
main form and set its Address property to IP address of the
server PC. Instead, you can also use the Host property of this
component. Please note that we can face some troubles in a
network with DHCP servers. These troubles will be discussed
later.
Then let us open the saved file with the server GUID and copy
a string with a saved GUID to the ServerGUID property. If you use
the server PC, ServerName must be automatically filled. If you
use another computer, the ServerName property may remain empty.
In a general case, such client can connect to the data access
server through the Internet, and the server must not be
registered in the client computer Registry. So the client PC may
"know" nothing about the server name and its GUID.
The next step is to try to set the Connected property to True.
It must lead to an automatic server startup. The Delphi or
C++Builder IDE is now a client of the data access server. Now our
connection counter must be equal to one.
Fourth, we must place the TClientDataSet component on the
client main form and set its RemoteServer property to
SocketConnection1. Then we must place the TDataSource component
on a form and bind it to the TClientDataSet component.
TClientDataSet is used to cache data obtained from the data
access server. It is a TDataSet object, so it has all methods for
navigating and editing data. Moreover, this component has also
the SaveToFile and LoadFromFile methods to store this cache in a
file. Therefore, it can implement a "briefcase model".
It means that the thin client can edit data in the
off-line mode and occasionally connects to the server to upload
the edited data or to download the new data.
Now we can choose the ProviderName property of the
TClientDataSet component from the list of available values (in
our case it contains the only Table1 value). Then let us
set the Active property of the TClientDataSet component to True.
Fifth, we can place the necessary DataControls components on
the client form (Fig.10).

Fig. 10. The main form of the client
application
It should be pointed out that the TClientDataSet component
could contain a cached data of two or more tables, which are
linked in a master-detail relationship. In this example, CLIENTS
table and HOLDINGS table are linked in a master-detail
relationship established in our data access server. This results
in the TClientDataSet component in the client application
containing all fields corresponding to the real CLIENTS table
fields, and, in addition, a new TDataSetField corresponding to
the related detail records in the HOLDINGS table. In other words,
TClientDataSet emulates nested tables, which in other
cases are available only in object-oriented databases, such as
Oracle 8.
Client datasets store both the original uploaded data in their
Data property and the change log in their Delta property. To
initiate uploading the edited data from the change log the
ApplyUpdates method of the TClientDataSet component must be used.
This method takes the changes in the change log and sends them to
the data access server. This method has an integer parameter,
which indicates the error tolerance to permit before canceling
the update process.
Why are the potential server errors foreseen? Because
generally the client application cannot have a complete
information about the server constraints and other business
rules; for example, it can know nothing about the new primary key
values, which appeared in the time period between downloading the
original data and uploading the changes. Therefore, only an
attempt of uploading edited data can show that some business
rules were violated.
Therefore, we must create two event handlers for buttons
placed on the client form. The C++Builder code for these handlers
is:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
ClientDataSet1->ApplyUpdates(-1);
}
//------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
ClientDataSet1->CancelUpdates();
}
The corresponding Delphi code is:
procedure TForm1.Button1Click(Sender: TObject);
begin
ClientDataSet1.ApplyUpdates(-1);
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
ClientDataSet1.CancelUpdates;
end;
Now we can start our application. Please look at the server
main form: connection counter must be equal to two. The first
client is the IDE; the second client is our running application
(Fig. 11).

Fig. 11. The "thin" client at
runtime
Let us click on the Table2 column. We can see that the
secondary form with the corresponding detail records appears.
These records can also be edited and uploaded by the ApplyUpdates
method.
Please note that we can use the SQL Monitor utility to trace
SQL queries produced by the data access server. SQL Monitor must
be running at the server PC.
If you want to deploy your client application to another PC,
you must also deploy dbclient.dll to this PC. It must be placed
to the WindowsSystem directory or to the client executable
directory. Borland Database Engine, ODBC and DBMS client software
must not be deployed to the client PC at all, because the
thin client does not use them. So workstations with
such "thin" clients are very easy to configure, and
they require less resources than workstations with standard
client applications using BDE, ODBC and DBMS client software.
This section contains an example of creating a
"thin" non-configurable client as an Active Form, and
using it as a part of a Web page.
Another type of thin clients is an Active Form
client. In many cases, it is very convenient to use and deploy.
It was mentioned above that thin clients are easy
to configure. So it is possible to deploy them both by means of
creating installation and through the Intranet (or Internet). The
web server can be a source of new client application versions,
and the web browser (MS Internet Explorer 3.0, 4.0, or Netscape
Communicator equipped by the necessary plugins) can be a tool for
installing and executing them.
If we want to deploy such thin clients, we must be
able to upload files to any Web server, for example, to the
Internet Information Server for Windows NT. It is also possible
to use any other Web server, operated by any operation system,
because it is used only as a file supplier. In a general case, it
is possible to place the thin client, the data access
server and the Web server in three different countries.
How to make such ActiveX client? First, we can select all
controls of our client application, and select the Component/Create
Component Template option from the IDE main menu (Fig.12):

Fig. 12. Creating component template from
the client components
Let us accept the default values of all parameters. Therefore,
we have created a new component template -
TSocketConnectionTemplate. Now we can close the client
application project.
Second, let us open the Object Repository and choose the
ActiveForm icon from the ActiveX page (Fig. 13):

Fig. 13. Choosing the ActiveForm icon from
the Object Repository
In the ActiveForm Wizard dialog, we must type the COM class
name for our ActiveX object and the project name for an ActiveX
library (Fig. 14).

Fig. 14. ActiveForm Wizard
It is better to check the Include Version Information
checkbox. Then we can press OK. Now we have obtained an empty
"form" of our new "thin" client. And, at
last, let us place our TSocketConnectionTemplate on this
"form".
Such active forms allow placing on almost all components from
the component palette, except the TMainMenu component. But if you
categorically insist on using it, you can, of course, use many
labels and pop-up menus instead.
Once the Active Form has been designed, we must set the web
deployment options for it. So we must select the Project /Web
Deployment Options... from the IDE main menu, and fill the
dialog appeared. Target Dir is the name of the directory
for our ActiveX library from the point of view of Web server
administrator (for example, it can be a local directory or a
shared LAN directory). Target URL is the name of the same
directory, but from the point of view of a "guest" of
the Web server. HTML dir is a directory where HTML file
with the reference to the ActiveX library must be placed. The Use
CAB file compression option is used when we want to decrease
the load time of our ActiveX library through the Internet (Fig.
15).

Fig. 15. ActiveX Web Deployment Options
We must also include dbclient.dll into our deployment. If we
have used the Build with Run-time packages project option,
we must also include these packages into the deployment. They
must be added using the Additional Files tab and the Additional
Packages tab.
The Include File Version Number option is good to
select, if we want our library to be automatically upgraded in a
user PC, when the user visits the page referring to this library,
and its Versioninfo resource is not the same as in its previous
downloaded version.
To deploy this library, we must select the Project /Web
Deploy option from the IDE menu. The deployment files must be
created and transferred to the Web server. This deployment
includes an HTML page with a reference to our ActiveX (by
<OBJECT> tag). It is generated by IDE and its name is the
same as the library project name. It can, of course, be edited to
satisfy your needs.
Now we can open this page in MS Internet Explorer using any PC
connected to the Web server, and test it (Fig.16).

Fig. 16. An Active Form in MS Internet
Explorer 4
Please note that the Internet Explorer properties must differ
from the default values, because its user must permit this
ActiveX to be executed. It is desirable that this ActiveX library
be code-signed. We shall discuss these details later.
This section describes a possibility of using MIDAS client
for Java.
Another way to create a "thin" client is to write it
using Java. It allows us to use non-Windows operation systems at
workstations.
For example, we can use JBuilder 2 Client/Server and the MIDAS
Client for Java (JMIDAS) components, which are the set of Java
Beans. This set includes the CorbaConnection component and the
ClientDataSet component.
Our server project created before is accessible via DCOM or
sockets. However, Java clients must be cross-platform
applications. So it would be better for them not to use COM,
because COM is a Windows-specific technology for distributed
computing. We can use CORBA instead of COM. CORBA is a
cross-platform technology for distributed computing, and Delphi 4
or C++ Builder 4 allows us to create CORBA MIDAS servers.
So before creating a Java "thin" client let us make
a copy of the MIDAS server project and then modify it. The first,
we can turn the COM server created with Delphi into a CORBA
server using the appropriate option of the pop-up menu of the
Code Editor containing the Remote Data Module implementation
unit. Some lines of code will be added automatically to this unit
in its initialization section:
TCorbaVclComponentFactory.Create('rdmd4Factory', 'rdmd4',
'IDL:pmid/rdmd4Factory:1.0', Irdmd4, Trdmd4, iMultiInstance,
tmSingleThread);
Now we have a server object, which is accessible via COM and
CORBA.
Second, let us delete the DataSource1 component from the
Remote Data Module. The ClientDataSet component of the current
version of JMidas does not support the nested table emulation.
Therefore it is better to create a master/detail link between
tables at a client application. So we must also export the detail
table from the Remote DataModule. Now we can save and compile our
server application and close the IDE.
Before creating a Java client, we must make our server
accessible. At first, we must start the VisiBroker Smart Agent at
the server PC. It is a special CORBA service, which provides
access to CORBA servers. Thereafter, we can run our CORBA server.
It allows us to use the application server interface while the
client application is being built.
Now let us run JBuilder with the JMidas installed and begin to
create a Java client. First of all, we must connect to the MIDAS
server. Let us create a new application in JBuilder (by using File/New/Application
option from the JBuilder main menu) and accept all defaults. Then
we must click the Frame1 item from the AppBrowser and choose the Design
tab.
Now we must drop the CorbaConnection component from the MIDAS
page of the Component palette into the Component Tree. Then let
us click on a button near the connectionDescriptor property and
answer the questions of the appropriate dialog.
The Repository ID value can be copied from the code generated
in the Implementation unit of the CORBA server. In our case it is
'IDL:pmid/MyRDMFactory:1.0'. The Object Name is the name of our
COM/CORBA object, and the Host Name is the name of PC where our
CORBA server is running.
Then we can try to connect to our server. If the test is
successful, we can see that our connection counter increases and
decreases immediately (Fig.17).

Fig. 17. Testing connection with CORBA
server
Now we must drop two ClientDataSet components into the
Component Tree. Then we must click on a button near the
clientDataSetDescriptor property of theClientDataSet1 and
ClientDataSet2 components and answer the questions of the
appropriate dialog (Fig.18).

Fig. 18. Setting ClientDataSet properties
Then we must click a button near the masterLink property of
the ClientDataSet2 component and fill the appropriate dialog. We
must select the ClientDataSet1 component as the Master Dataset
(Fig.19).

Fig. 19. Setting Master-Detail link between
ClientDataSets
Now we can test the link.
If the test proves to be successful, we can create the user
interface of our Java client. For example, we can place two
NavigatorControl components and two GridControl components to our
frame and bind them with the corresponding ClientDataSet
components. The result is shown in Fig.20.

Fig. 20. A Java thin client at
runtime
This section describes how to organize editing data in the
off-line mode with the deferred uploading to the database server.
It also describes some ways of using client datasets in 1-tier
and 2-tier systems.
The TClientDataSet component is an intellectual cache
manager. It can store the metadata associated with
the cached tables. It also stores all history of editing data in
the cache.
In addition, the TClientDataSet component has the SaveToFile
and LoadFromFile methods for saving to and retrieving from files
the cached data downloaded from the database server through the
data access server. These methods can be used by different ways.
For example, a user can connect to the data access server,
download some data, save it to a file, take his notebook home (or
to a business trip, etc.) and begin to edit this data separately.
He can periodically save edited data to a file, and retrieve them
to continue editing. He can also return to his office, connect to
the data access server and try to upload his data retrieved from
a file. This way of processing data is known as a briefcase
model.
The next idea of using the TClientDataSet component is to
download data to a ClientDataSet cache, save them to a file, and
then forget about the database server and the data access server
at all. We can, for example, make a "phone directory"
or another reference book by this way. We must only write our
client executable, dbclient.dll, and the "briefcase
file" with a stored cache to a CD, and this reference book
does not require BDE to be installed!
It is also good to use the ClientDataSet component in two-tier
systems. In this case, we can emulate nested tables using the
server tables linked by a master-detail relationship. We must
only place the TClientDataSet and TDataSetProvider components on
a form or on a Datamodule and bind them to each other.
Another way to use client datasets is to store locally lookup
tables, which are updated rarely. It reduces the network traffic
and allows the client application to work faster. It is also
possible to create calculated fields in such datasets.
The TClientDataSet component has also the AddIndex and
DeleteIndex methods. It allows re-sorting data in the cache
without sending additional queries to the database server.
This section describes how to handle the OnReconcileError
event to correctly resolve possible collisions caused by
simultaneous editing the same data by several users.
Let us discuss a typical case of simultaneous editing the same
record by two users. In 1-tier and 2-tier systems, we can use
locking records or pages. In these cases, the first user can edit
a record, and the second user must wait until the first user
releases this record.
In a 3-tier system, it is impossible to use locking. If the
briefcase model is used, the possible time delay between
downloading record for editing and uploading the edited record
back to the database can be very long. Therefore, the multi-user
data processing in 3-tier systems differs from the traditional
one.
During uploading the edited data to the database server, the
actual version of the uploaded record stored in the database is
compared with its previously downloaded version stored in the
client dataset cache. If these versions are different, the
OnReconcileError event of the TClientDataSet component occurs.
Why can these versions be different? Because two or more users
may create their own locals copies of the same record and edit
them separately and differently. Let us suppose that two users
have edited the same record and then try to upload their edited
versions of it. The first user can do it without any problem.
However, the second user must be notified that somebody has
already changed this record.
To provide this notification, we must handle OnReconcileError
event of the TClientDataSet component. This event occurs when
another user changes an uploaded record during the time period
between downloading it, and uploading its edited version from the
cache back to the database. The simplest way to handle it is to
use the ReconcileError Dialog from the Object Repository.
Let us open our previous project created in the part 4. Then
let us open the Object Repository and choose the Reconcile Error
Dialog icon from the Dialogs page. A new form will be added to
our client application (Fig. 21).

Fig. 21. Reconcile Error Dialog from Object
Repository
Then we must refer to the new form from in the main form unit
of our project. We must also move our ReconcileError Dialog to
the Available Forms list in the Project options
dialog. Otherwise, it would appear immediately on a client
startup.
Then we must create the OnReconcileError event handler of the
ClientDataSet1 component. The C++Builder code for this handler
is:
void __fastcall TForm1::ClientDataSet1ReconcileError(
TclientDataSet *DataSet, EReconcileError *E, TUpdateKind UpdateKind, TReconcileAction &Action)
{
Action = HandleReconcileError(Owner, DataSet, UpdateKind, E);
}
The corresponding Delphi code is:
procedure TForm1.ClientDataSet1ReconcileError(DataSet: TClientDataSet;
E: EReconcileError; UpdateKind: TUpdateKind; var Action: TReconcileAction);
begin
Action := HandleReconcileError(DataSet, UpdateKind, E);
end;
HandleReconcileError is the method of the Reconcile Error
Dialog.
Let us compile and save our client application. Then let us
run it twice. In both instances of our client, we can change the
same record in different ways. Then let us try to apply updates
from both instances of the client application. The first attempt
will be successful. The second one will lead to the appearance of
the Reconcile Error Dialog (Fig. 22):

Fig. 22. Reconcile Error Dialog at runtime.
The grid in this dialog contains the values, which have
initiated the collision. They are the old value and the value to
be uploaded. The second user can decide what to do with this
record (to edit, to upload though a collision, etc).
We must note that the detail records in "nested"
client datasets can also be processed by the same event handler
if such collision occurs.
Of course, you can change the Reconcile Error Dialog and its
unit to satisfy your needs.
This section describes how to make a user registration in a
"thin" client and to transfer the user name and
password to the SQL server through the data access server by
creating new methods of Remote Datamodules.
Remote Data Modules are COM objects. Therefore, we can create
additional methods for them using the Type Library Editor. Let us
create a method for the user access verification when connecting
to the database server.
It is obvious that we must now place the TDatabase component
on the Remote Data Module, because now all its instances must use
their own database connections instead of the only connection
they share. The user name and password are the properties of this
TDatabase component.
We must also place the TSession component on the Remote Data
Module and set its AutoSessionName property to True. Then we must
select the SessionName property of the TDatabase component for it
to be the same as that of the TSession component. It prevents
possible collisions of different database connections (Fig. 23):

Fig. 23. Modified Remote Data Module with
non-shared database connection
Now we can set the TDatabase component properties. We must
leave the User Name and Password blank (Fig. 24):

Fig. 24. Database properties for Remote
DataModule with Login method
Now we must set the DatabaseName properties of TTable
components to the TDatabase component name. Thereafter, we can
delete the old TDatabase component from the main form, because we
do not need it now.
Finally, we can create the Login method of the Remote Data
Module. Let us open its type library and create a new method of
our COM object (using the New/Method option of the pop-up
menu of its interface).
The parameters of this method are the user name and password.
We must choose the Parameters tab, press the Add button twice,
and rename the parameters created. Their type must be WideString
in the case of Delphi and BSTR in the case of C++Builder (Fig.
25):

Fig. 25. Describing the Login method in the
Type Library
After pressing the Refresh button we can open the
implementation unit of the Remote Datamodule and add the
implementation code of the Login method. The C++Builder code of
this implementation is:
STDMETHODIMP TMyRDMImpl::Login(BSTR username, BSTR password)
{
try
{
m_DataModule->Database1->Connected=false;
m_DataModule->Database1->Params->Values["Password"]=password;
m_DataModule->Database1->Params->Values["User Name"]=username;
m_DataModule->Database1->Connected=true;
m_DataModule->Table1->Open();
m_DataModule->Table2->Open();
}
catch(Exception &e)
{
return Error(e.Message.c_str(), IID_IMyRDM);
}
return S_OK;
};
The corresponding Delphi code is:
procedure TMyRDM.Login(username, password: WideString);
begin
Database1.Connected:=false;
Database1.params.Values['Password']:=password;
Database1.params.Values['User Name']:=username;
Database1.Connected:=true;
Table1.Open;
Table2.Open;
end;
Now we can compile and save our server.
Let us change our client application. We can create a new
form, which must be the user access verification dialog (Fig.
26):

Fig. 26. User access verification dialog
The PasswordChar property of the Edit2 component is to be set
to *. We must also refer to the main form in this unit.
Let us create the OnClick event handler for the Connect
button. The C++Builder code for this handler is:
void __fastcall TForm2::Button1Click(TObject *Sender)
{
Form1->ClientDataSet1->Close();
Form1->ClientDataSet2->Close();
Variant svr=Form1->MIDASConnection1->AppServer;
svr.OleProcedure("Login",Edit1->Text,Edit2->Text);
Form1->ClientDataSet1->ProviderName="Table1";
Form1->ClientDataSet2->ProviderName="Table2";
Form1->ClientDataSet1->Open();
Form1->ClientDataSet2->Open();
}
The corresponding Delphi code is:
procedure Tform1.Button1Click(Sender: TObject);
begin
Form1.ClientDataSet1.Close;
Form1.MIDASConnection1.AppServer.Login(Edit1.Text,Edit2.Text);
Form1.ClientDataSet1.ProviderName:='Table1';
Form1.ClientDataSet2.ProviderName:='Table2';
Form1.ClientDataSet1.Open;
end;
Now let us change the main form of client application. We must
refer to our user access verification dialog. We can also place a
new button on our main form and set its Caption property to
"Login". Then we can create the OnClick event handler
for this button:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
Form2->ShowModal();
}
The corresponding Delphi code is:
procedure TForm1.Button3Click(Sender: TObject);
begin
Form2.ShowModal;
end;
This section describes how to use business rules in
"thin" clients.
In the case of using SQL servers, business rules and
referential integrity rules are implemented by indexes, triggers,
stored procedures, etc. This approach to data design allows us to
use these objects by all clients without writing any additional
client code.
In the case of classic 2-tier client-server system without
using cached updates, executing the Post method of a TTable or
TQuery component in a client application leads to an attempt to
save the edited record to the database. If this record is not
consistent with the referential integrity rules, the appropriate
transaction rolls back, and the client application is informed
about this rollback by the database server. If it happens
regularly, the network traffic increases.
For reducing traffic, we can contain some of business rules in
the client application by using TFields objects or by creating
data dictionaries. In this case, we must rewrite the client
application, if some of the business rules are changed.
Therefore, we need to reinstall and reconfigure them at all
workstations.
In 3-tier systems, we can obtain the metadata and businesses
rules from the database server, and store them in the data
dictionary, which is used by the data access server. It is easier
to reinstall or reconfigure one or several data access servers
than to do the same work with hundreds of workstations.
In 3-tier systems, we can also use the ConstraintBroker. It
allows us to deliver business rules, which are stored in a data
dictionary used by the data access server, to client
applications. They are stored in the TClientDataSet cache along
with the data. So it is possible to provide the data analysis
when executing the Post method inside the client application
without connecting to the data access server. Using business
rules in a client application reduces the network traffic and
increases the efficiency of server operation.
This section describes differences between using MS DCOM,
OLEnterprise and sockets. They are the rules of configuring, the
requirements of additional client software installation, a
possibility of providing the load balancing and the fail-over
safety. The advantages of using CORBA are also discussed.
How can we provide the remote access to the server? In all
cases, the remote client must interact with a special application
or a service running on the server PC. This special application
or service allows or forbids to run the server application or to
connect to it in accordance with the rules of giving permissions.
The necessity to interact with such services is due to the
safety. It would be not very good if any LAN or Internet user
could run any application inside the address space of your
computer
In the Microsoft documents such services are often called
Service Control Managers (SCM). DCOM Service Control Manager is a
Windows NT service, and, in a general case, it is already
installed and running on Windows NT PC.
We can use the different ways of access to the remote MIDAS
server, because it is an OLE Automation server. For example, we
can use Microsoft DCOM directly (it means using the
TDCOMConnection component, or the TMIDASConnection component, or
the TRemoteServer component in a client application). In this
case, Windows NT must operate the data access server. The client
application must be operated by Windows NT or by Windows 95/98,
equipped with DCOM95 or DCOM98 (they are the DCOM clients
accessible on the Microsoft Web site).
How to use DCOM? First, we must configure DCOM parameters on
the server PC. The first step is downloading the Windows NT user
list from the primary domain controller to the server PC. DCOM is
a Windows specific technology, and so it uses the Windows user
list as a list of persons or groups who can be granted the
permission to use or to configure the particular COM server. In
addition, DCOM uses the Windows Registry as a COM object
implementation repository. Therefore, your network must have the
primary domain controller; otherwise, using DCOM seems to be
impossible. You, of course, must also be granted a permission to
download this user list to server PC.
Having the NT user list, you can grant or revoke permissions
to users or user groups to run or to configure your DCOM server
by means of the DCOMCNFG utility. You must run it and choose our
data access server from the list of the registered COM servers.
Then you must describe the rules of using this server, i.e., who
can run it and who can configure it. Finally, you must point the
location where our data access server must be executed. In this
case it is necessary to select the "Run application on this
computer" option. The general rule of DCOM access to server
is: The access to this specific server is possible for
network users who have the DCOM client installed on their
computers and are granted a permission to launch this
server (Fig. 27):

Fig. 27. Describing rules of access to DCOM
server
Configuring a client PC is very simple. First, we must
register our DCOM server in the client computer Registry (for
example, by running it once on the client PC, or by exporting an
appropriate *.reg file into the client computer Registry).
Second, we must select the "Run application on the following
computer" option in the DCOMCNFG utility and enter the name
of the server PC in the appropriate field of this dialog (Fig.
28):

Fig. 28. Configuring DCOM on a client PC
On the one hand, if we use DCOM, any client is able to connect
to the only server computer, whose name is kept in its DCOM
configuration data. If this server fails, client cannot connect
to the other server containing the same server object
implementation without reconfiguring DCOM on a client computer.
On the other hand, using DCOM allows us to create data access
servers as Microsoft Transaction Server objects (they are DLLs
supporting the IObjectControl interface). In this case, client
connects to the MTS executable, and server objects are
instantiated in its address space. MTS can provide additional
services, for example, sharing database connections and object
pooling (i.e., creating a few server objects that can serve many
clients). MTS allows us to save the server resources. But in this
case we need to create a stateless code in the server
object instead of exporting tables, for example, similar to:
function TmyMTS.GetMyData: OleVariant;
begin
Result:=Provider1.Data;
SetComplete;
end;
Such code allows the MTS DataModules not to store the specific
client data, so several clients can share it.
MTS objects can instantiate other MTS objects, and it allows
us to manage distributed transactions. Different parts of a
distributed transaction can be implemented in different MTS
objects. For example, this part of code is an example of
initiating distributed transaction:
type
TmyMTS = class(TMtsDataModule, ImyMTS);
...
private
FPart1: IPart1;
FPart2: IPart2;
...
procedure Tpays.DoTrans(Param1: Integer; Param2: Double; const Param3, Param4: WideString);
begin
try
OleCheck(ObjectContext.CreateInstance(CLASS_Part1, IPart1, FPart1));
OleCheck(ObjectContext.CreateInstance(CLASS_Part2, IPart2, FPart2));
FPart1.Method1(Param1);
FPart2.Method2(Param1,Param2,Param3);
Method3(Param1,Param3,Param4);
except
DisableCommit;
raise;
end;
EnableCommit;
end;
Using DCOM directly is not the only way to create a
distributed system. For example, we can use OLEnterprise, which
is a good DCOM extension. It is a part of MIDAS, and it allows us
to create a load-balanced fail-over system.
In this case, the OLEnterprise Object Factory is an analog to
DCOM SCM. It must be running at the server PC. Client
applications must connect it for the remote COM server access.
Using OLEnterprise makes it possible to apply two different
ways to build an information system. The first one is similar to
using DCOM, i.e. any client application knows about the only
server implementation. But in this case, the access rules differ
from those of DCOM. The general access rule for the specific PC
is Any client, who has the OLEnterprise client installed on
his computer can access any published COM server on this
computer by means of OLEnterprise.
What does it mean? It means that we do not need the network
user list (and we do not need to have the primary domain
controller at all). In addition, OLEnterprise allows publishing
COM objects in Windows 95/98. So we can use these operation
systems to operate remote COM servers.
Publishing objects means making some registry changes by the
Object Explorer utility by choosing the Export option for
a specific object (Fig.29):

Fig. 29. Exporting a server object by the
OLEnterprise Object Explorer
After exporting an object, we can run the same utility on a
client computer and connect to the server Registry. Running the
Object Factory on the server PC makes it possible to read the
published part of the Registry by the another instance of the
Object Explorer running on a client computer, and to import the
remote server information to the client Registry (Fig. 30):

Fig. 30. Importing a server object
We can see that in this case we must not run the server
application on a client PC for registering it.
The second way to build an information system using
OLEnterprise differs from the previous one. It allows any client
to reach multiple servers implementing the same server object. To
make this possible, we must use the Business ObjectBroker, which,
in fact, is a directory service of a distributed system.
To use the Business ObjectBroker, we must reconfigure our
server computers. In particular, we must describe that the
Business ObjectBroker must find all server implementations, and
we must set its location (Fig. 31):

Fig. 31. Configuring server access through
Business ObjectBroker
Thereafter, we must run the Business ObjectBroker on the PC
specified in the configuration dialog, and export our COM servers
to the Business ObjectBroker. The client application must only
"know", where the broker is (we must refer to it in a
client application instead referring to the server PC name). The
client application can "know" nothing about all server
computers (how many of them are available now, and what their
names or addresses are). When the broker receives a client call,
it finds one of suitable server implementations, and informs the
client application about its location. If there are many servers
with the same server objects, the Business ObjectBroker must
provide a load balancing by choosing an implementation randomly.
This case is a good way to provide a fail-over safe system. If
we should write a client code, which makes the client to
periodically connect to and disconnect from the server (it is
better to write a "stateless" code, which allows the
server object not to store data of the specific client), the
client application will connect to different server
implementations randomly. If one of server computers fails, the
client should not know about this failure, because it will be
simply reconnected to another server implementation next time.
In the case of using OLEnterprise, we can write the client
application using the TOLEnterpriseConnection (or
TMIDASConnection, or TRemoteServer) component. Configuring them
depends on the chosen architecture (for example, whether we use
broker). You can find the details in the Delphi or C++Builder
documentation.
We must note that Delphi 4 and C++Builder 4 allow to create
load-balanced systems by placing the broker functionality into
the client application. This functionality is implemented by the
TSimpleObjectBroker component. This component contains a list of
computers with the same server object implementation installed
on, and provides a random choice of one of these computers in
attempt of connection to the server. It is not an equivalent to
using commercial directory services, but it can be useful in many
cases.
We have already created a client application using sockets. In
this case, the Borland socket server works as a Service Control
Manager and, in addition, as a data transport tool. In this case,
we can achieve the load balance only by using the
TSimpleObjectBroker component. However, using sockets allows us
to make a non-configurable client, which does not need any client
parts of DCOM, OLEnterprise or any other communication software
(of course, the TCP/IP support is necessary). Therefore, using
sockets is the best way to provide an Internet deployment of
client applications, because such deployment is only available
when we do not need any specific client software to be installed
and configured on a client computer.
We have already created a CORBA MIDAS server and a Java
client. Of course, we can create a Delphi or C++Builder client
too. In this case, we must use the directory service (the
VisiBroker Smart Agent), which also provides a load balance.
CORBA is a multi-platform specification. Therefore, it must
not use Windows specific tools and objects, such as the Registry.
If we need to instantiate the CORBA server automatically by
client request, we must register it in CORBA specific databases,
which are the interface repository and the implementation
repository.
A great advantage of CORBA is that it is possible to create a
CORBA server portable to other platforms. C++Builder 4 allows us
to do it by choosing the appropriate project options.
This section describes what is necessary to deploy MIDAS
data access servers and what kind of software must be used and
licensed.
It was mentioned above that the thin client
deployment is a very simple process. It demands dbclient.dll to
be installed in the WindowsSystem directory or in a client
executable directory. If our thin client is an
ActiveX library, we must only choose dbclient.dll in the Additional
files tab of the Web deployment options dialog. If we
want to create an InstallShield Express installation (or to use
another tool for creating installations), we must not include BDE
and SQL Links. We must include only dbclient.dll and the other
necessary files (packages, data files, etc.).
It should be mentioned, however, that possibly we must include
some libraries from the WindowsSystem directory, which must be
the replacements for outdated libraries of the earliest version
of Windows 95. Nevertheless, it is a general problem of creating
installations.
If we want to deploy an ActiveX thin client
through the Internet, it is better to choose the Use CAB file
compression option to reduce the download time.
It can also be mentioned that we can create Web installations
of executable thin clients, for example, by using the
InstallWeb software of InstallShield Corporation.
Data access servers need BDE and some libraries to be
installed. They are IDPROV32.DLL (it must be at the same
directory, where the BDE is located), DBCLIENT.DLL and
STDVCL40.DLL (they must be placed in the WindowsSystem
directory, and they must be registered).
It should be mentioned that Delphi 3,4 Client/Server Suite,
C++Builder 3 Client/Server Suite, and C++Builder 4 Enterprise
contain only the MIDAS Development Kit, which is used for
developing data access servers and thin clients. But
it is not allowed to use the MIDAS Development Kit for deploying
them. Using and deploying such servers requires one of the
possible MIDAS licenses, for example, the unlimited client MIDAS
license or the Limited MIDAS Server Deployment License.
This section describes possible troubles, which may occur
while connecting to server, showing an ActiveX "thin"
client in a browser, deploying "thin" clients divided
into packages, working in unreliable networks, etc., and how to
solve these problems.
Using MIDAS we can face some problems. Here are the short
descriptions of some of them and ways to solve them.
1. The problem, which occurs very often, is that an ActiveX
thin client is not properly represented in a browser.
The possible reasons for such problems are:
- MS Internet Explorer 2.0 or Netscape Communicator is used
instead of MS Internet Explorer 3.0 or 4.0;
- The browser settings do not allow execution of ActiveX
controls downloaded from this Web site.
- The user does not have a permission to modify his
Registry.
To show and execute ActiveX controls correctly, a user must
choose the View/Internet Options/Security option and allow
execution of ActiveX controls downloaded from all Web servers or
from the specific one. If your control is unsigned, your users
may choose appropriate option, but a browser must inform them
about possible troubles during execution of the unsigned code.
If you want to use the Netscape Communicator to show and
execute ActiveX controls, you must equip this browser with an
appropriate plug-in. Netscape is a multi-platform browser, so it
must not execute ActiveX controls by itself, because ActiveX
controls are Windows-specific objects.
2. ActiveX is not properly represented in a browser in spite
of the permission to execute it.
This may be due to the fact that this ActiveX was divided into
packages, and they were not deployed along with *.ocx file. In
this case, it is expedient to check the project options and, if
necessary, add the run-time packages to Web Deployment Options.
3. In an attempt to open the TClientDataSet, the error message
about loading library problems occurs.
The reason must be the absence of dbclient.dll at the client
PC, or the absence of the MIDAS server libraries on the server
PC.
4. If we use an unreliable network, a client application can
lose its connection with the server. In this case, the best way
to maintain the client application functionality is to provide
the client application with a possibility to save cached data to
a file. It prevents the possible loss of the edited data and
allows the user to upload it later.
5. In some networks (usually containing both Windows NT DHCP
servers and UNIX servers) we can confront with some troubles.
They are due to the fact that in such networks any workstation
can have two IP addresses and two names. The first one is for the
Microsoft network, and the second one is for the UNIX network and
Internet. It should be pointed out that you must use the
Microsoft address and name for the DCOM type of connection and
the UNIX address and name for the socket type of connection. To
obtain the UNIX/Internet address and name, it is possible to use
IPCONFIG and NSLOOKUP utilities.
This section contains some examples of multi-tier
information system architectures recommended by us to some of our
customers in Russia, the Ukraine, Moldavia and Latvia (oil plants
with remote oil-rigs, trade companies with remote stocks,
regional electricity supply services, banks, etc.)
There are many different ways to make a distributed system.
Its architecture depends on the current and planned number of
users, the degree of territorial distribution of an enterprise,
the need for centralized data storage, the frequency of upgrading
client applications, etc.
The first case is a compact enterprise with LAN. In this case,
all enterprise data are often stored in the only database.
Three-tier architecture in this case is used to reduce expenses
for configuring and maintaining workstations (installing and
configuring DBMS client software, configuring BDE, upgrading
client applications, etc.), to reduce the network traffic, and to
increase the reliability of the information system. In this case,
it is desirable to use several computers with the same data
access servers installed, and a directory service to provide the
fail-over safety and load balancing. This architecture can be
based on both OLEnterprise with Business ObjectBroker and
VisiBroker with CORBA directory services (Fig. 32):

Fig. 32. The example of an information
system architecture for a compact enterprise with LAN
The use of CORBA may be recommended in the case of a
perspective of replacing the data access server PCs by computers
with non-Windows platforms (for example, by Unix servers). In
this case, such upgrading will be easier, because it will not
require replacing the client applications (and, possibly, it will
not require rewriting the server code, if JBuilder or C++Builder
4 Enterprise is used for creating the platform independent CORBA
server code).
It is also good to use Entera data access servers, because
Entera exists for different platforms too.
The second case is an enterprise with a wide territory
scattering. It is a typical situation for many gas and oil plants
in Russia and for many trade companies. These enterprises often
use many local information systems, so they have a lot of
problems concerned with data replication, data actualization
support, joining the data from a few information systems for
statistical analysis and report generation.
In this case, a 3-tier architecture can solve these problems.
This architecture makes it possible to centralize storing and
processing the data and to obtain the actual data, even if a
workstation is very far from the database server and the data
access server and cannot be connected to the data access server
by LAN. In this case, it is possible to use a direct modem
connection by a telephone line, or through the Internet. Such
connection must not be very reliable: client applications can use
caching data, saving them to files and restoring them from files.
Using the ConstraintBroker makes it possible to check the
relevance of data to the server business rules inside a client
application.
In this case, the three-tier architecture is used to reduce
expenses for configuring software and to centralize data storage.
It is good to place the database server and the data access
server at the central office of such company, and the data access
server must be equipped with MIDAS and must be accessible through
the Internet. As for workstations, they must be equipped with the
Internet Explorer 3.0 or higher. Both developers and users must
have an access to the same Web server (it does not matter where
it is and what operation system it is operated by, because it is
only used for uploading and downloading "thin"
clients). If client applications use sockets for access to the
server, they are non-configurable, because they require the
Internet Explorer 3.0 to be installed, and nothing else. Of
course, we can use Inprise Entera instead of MIDAS (Fig. 33):

Fig. 33 The example of information system
architecture for enterprises with scattered subsidiaries
Such architecture is used or is planned to use in many Russian
and Latvian banks, telecommunication and trading companies,
because many of them have remote subsidiaries with Internet
access.
If the Internet is not accessible, it is possible to use
modems and telephone lines with TCP/IP protocol (some engineering
supervision services in Russia use or plan to use such
technology). In the case of unreliable connection, it is
recommended to provide a possibility to save cached data using
the SaveToFile and LoadFromFile method of the TClientDataSet
component.
Another variant of the information system architecture for
"scattered" companies can be implemented as a 4-tier
system with an "ultra-thin" client. In this case a
"thin" client application is a CGI script or an ISAPI
DLL, and workstations are equipped with any operation system and
any Web browser. This is better than to use "fat"
clients as Web server applications, because Web server
applications usually serve simultaneously an unpredictable number
of their clients; so it would be better for them to use less
resources. In this case, unlike the previous one, the Web server
must be operated by Windows NT/95/98, because it is not only a
file supplier, but also a host for executing the data access
server code written with Delphi or C++Builder (Fig. 34):

Fig. 34 The example of an information system
architecture for enterprises with scattered subsidiaries
It should be mentioned that Delphi 5 provides an additional
support to this architecture. The features of implementing such
MIDAS client in the form of Web server application will be
discussed in the last section of this paper.
It is possible to combine these architectures, using, for
example, TCP/IP access and directory services together. Inprise
tools can provide us with many possibilities to build reliable
information systems, which are easy to configure, maintain, and
upgrade, and we can use our fantasy to create our own variants of
their architectures.
Note: this part of article is written with a pre-release
copy of Delphi 5.
One of the new features of Delphi 5 and MIDAS 3 is the
possibility to create Web MIDAS client applications. The
InternetExpress components allow to create a Web server a
pplication, which is a "thin" MIDAS client. In this
case, users can interact with it by working with a Web browser
only.
To illustrate this possibility, let us create the MIDAS 3
server. The process of creating this server is not significantly
different from described in part 3. The main difference is the
fact that during creating a server we must place the
TDataSetProvider on the Remote DataModule, bind it with the
master TTable component and set its Exported property to True
(and, of course, we can use the new graphic DataModule
Editor to define a Master-Detail relationship between tables,
Fig.35).

Fig. 35. The MIDAS server created in Delphi
5
To build a Web MIDAS client, we must create a Web
server application by choosing an appropriate icon from the
Object Repository of Delphi 5. After that, we must place a
connection component (for example, TDCOMConnection,
TSocketConnection, etc.) on the WebModule and set its ServerName
property. Next, we must place a TXMLBroker component on the
WebModule and set its RemoteServer property to the name of our
connection component.
Next, let us place TMidasPageProducer component
on our WebModule. It must generate an HTML content for
representing in a browser.
Now we must set the IncludePathURL property of
this component. It is a path, where our Web application can find
JavaScript and HTML files, which are used to produce the HTML
content. The *.js and *.html files must be copied from
Delphi5SourceWebmidas directory to this URL.
It should be pointed out that the InetpubScripts
directory, which is the default script directory of Microsoft
Internet Information Server, and a potential place to store Web
MIDAS client, is not a good place for these files. The reason is
the fact, that by default any file of this directory can be
executed, but cannot be read. So it is necessary to change the
default settings for this directory or to use another URL to
store these files.
Now we must right click on the TMidasPageProducer
component and choose the Web Page Editor option from the pop-up
menu. In this editor, we can click the New button and create user
interface objects, such as DataForms, containing DataGrids and
DataNavigators (Fig. 36).

Fig. 36. Designing user interface with Web
page editor
After that, we must set appropriate properties
for these elements. For example, to create a detail grid, we must
set XMLDataSetField property of the DataGrid2 to Table2. Now we
have a WebModule similar to Fig. 37.

Fig. 37. The WebModule of Web MIDAS client
At last, we must create a WebActionItem and set
its Producer property to MidasPageProducer1, and its Default
property to True. Then we can compile our Web
application, upload it into script directory of the Web server
and try to run it from a Web browser (Fig. 38).

Fig. 38. The browser front-end produced by
Web MIDAS client
Thus, Delphi 5 allows us to create Web MIDAS clients which
allow to use a Web browser as a front-end to MIDAS data access
servers, and that simplifies creating 4-tier information systems.
I wish to thank Charlie Calvert for his support and
assistance. I am also grateful to all staff of the Moscow Inprise
office for their aid during last 3 years.
Natalia Elmanova is a Ph.D., free-lance Delphi/C++Builder trainer and consultant, and technical writer. She has more than 15 years experience in database programming. She also is an author of three popular books about C++Builder, Delphi, COM, and database programming and more than twenty articles about Inprise technologies in Russian computer magazines.
1011.g23@relcom.ru
|