Advantage Database Server
Advantage Database Server
June 1, 2006
Abstract
The Advantage Database Server engine works client/server and in embedded form.
In this article, it’s use as an embedded database server is examined, both under Delphi
(Windows) and Lazarus (Linux). As in the previous articles in this series, the pupil
tracker database will be used to measure it’s performance.
1 Introduction
The Advantage Database Server (currently at version 8) is a complete database server tech-
nology, available for Windows and Linux, usable in Client/Server or in local configurations.
Advantage Database server is a full-featured database server: It understands SQL, provides
transaction management, has a stored procedure language, features triggers. It also has
backup facilities, features replication, comes with a graphical management console. It’s
use is not limited to Delphi: there is an ODBC driver and a OLE DB driver, which should
make it available to just about any programming language for Windows out there, a .NET
provider and also a PHP module, making it available for web development under Linux
and Windows.
Advantage Database Server is a commercial solution, but the local engine, which is dis-
tributed with the Delphi source code of the Advantage TDataset component, can be re-
destributed for free. It can be downloaded from the website of extended systems:
http://www.extendedsystems.de/
The Advantage TDataset component for Delphi 7 and for Kylix are the downloads that
were used to write the code for this article. For Windows, the Advantage Data Architect
is a useful download, it contains a GUI tool to execute queries, create databases and some
other management tasks.
Although written for Delphi, the code compiled under Lazarus with virtually no changes: a
couple of extra conditional defines were introduced, and that is all. A patch for the code is
supplied with the rest of the source code of this article. The patch has also been submitted
to the people at Extended systems, so maybe a next release of Advantage Database Server
will come with support for Lazarus out of the box.
The product can be installed simply, it’s a normal windows install program. On linux, the
installation is meant for Kylix, but the needed files are in subdirectories of the directory
setup.files:
source the source code for the TDataset components. The files can be copies to wherever
they are needed to compile your projects.
1
redistribute these are the libraries and support files which should be redistributed with
your application.
ace The client interface library for the Advantage Database Engine. (ace32.dll on win-
dows, libace.so.8.00.1 on Linux)
adslocal The local database engine itself. (adsloc32.dll on Windows, libadsloc.so.8.00.1
on linux)
If support for character sets other than the default character set is needed, the files ansi.chr
and extend.chr should also be distributed.
Under Windows, these files should be located next to the program. No other changes are
necessary.
Under Linux, this can also be done, but 2 additional actions are needed:
1. Symbolic links must be made to the library files that omit the minor number from
the library name, so a link called libace.so.8.00 and a link calledlibadsloc.so.8.00.
2. The dynamical loader must be told to look for the files next to the program library.
This can be done by setting the LD_LIBRARY_PATH environment variable:
export LD_LIBRARY_PATH=/path/to/your/application
Name This is the name of the database. A data dictionary file with this name will be
created. (for the pupil tracking database, ’Tracker’ will be used)
2
Figure 1: Creating a Data Dictionary
3
Server type This is the type of the server. For an embedded database, this should of course
be ’Local server’
Database This is the directory where the database should be created.
More options can be set, but this is the minimally required information to be able to create a
database. If the database contains sensitive data, it’s a good idea also to supply a password
for the default administrator user (’AdsSys’). The database itself and communication (in
the case of a remote database) can be encrypted if stronger security is needed.
To populate the database with tables and fill the tables with data, the scripts which were
used to create and populate the other embedded databases in this series of articles, had to be
modified. The modified version of the database creation script is provided with this article.
The tracker database consists of 2 tables: a table with pupils, and a table with track data:
the track data could come for example from some biometric device such as a fingerprint
scanner or identity card reader, installed at the school gate.
The SQL statement which was used till now to create the PUPILS Table, was the following:
The Advantage Database SQL dialect deviates from the SQL standard in 2 ways:
1. VARCHAR is not recognized. It is accepted, but creates a BLOB (or memo) column.
Instead, the CICHAR (Case Insensitive CHAR) keyword can be used to create a
variable length string.
2. The NOT NULL constraint (indeed, any field-level constraint) must be preceded by
the CONSTRAINT keyword.
The table which contains the track data was previously created with the following query:
4
Figure 2: Creating a foreign key in the Data Architect
Needs an extra change: The Advantage Database SQL does not understand the FOREIGN
KEY construct.
The foreign key can be created, however, using the "RI Objects" item in the Database
Architect program. It shows the figure 2 on page 5 dialog. The information to be entered
there is obviously the same as the information needed by the FOREIGN KEY constraint
statement in SQL.
The data architect can even generate a SQL statement which creates the foreign key in
SQL, using a stored procedure:
EXECUTE PROCEDURE
sp_CreateReferentialIntegrity (
5
’R_PUPILTRACK_PUPIL’,
’PUPIL’,
’PUPILTRACK’,
’PT_PUPIL_FK’,
2, 2, NULL, ’’, ’’);
Execution of this statement failed, however. The "RI links" form did create the referential
integrity constraint.
After this, the indexes on the tables could be created using the same SQL statements as for
the other
Filling the database with data can be done with the Database Architect program, but is not
recommended. Loading the script in the SQL window is possible: the SQL window can
contain multiple SQL statements But the 610.000 SQL statements take a very long time
to load: about as long as it takes to actually execute them. It also has a drastic impact on
memory usage of the program, which went far over 512Mb.
Since the SQL window defaults to loading the last used SQL script when it is started, this
means the script will be reloaded on the next startup, causing the architect to apparently
’hang’. Not a problem, but one should be prepared for this.
So, the SQL statements will be executed in the SQL executor program introduced in the
previous articles in this series.
TAdsConnection This component represents the connection to the database. All other
components are connected to such a connection. It’s equivalent to TDatabase in
the BDE, or a TRemoteServer for Midas applications.
TADSTable a TDataset descendent representing a table in the Advantage database. It’s
equivalent to TTable in the BDE. Using a single property, it offers access to any
table in the database. Additional properties exist to select and maintain indexes, and
to filter the data
TADSQuery A TDataset descendent which allows to execute any query on the database.
In fact, multiple (non-select) SQL statements can be executed at once. It’s therefore
more powerful than it’s BDE pendant, TQuery. It also offers support for parameters,
and for master-detail relationships.
6
TADSStoredProc is a TDataset descendent offering access to stored procedures.
TAdsDictionary offers access to the Data Dictionary of a database. It can be used to
control every aspect of the database, and to create new databases.
TAdsSettings can be used to control various settings of the ADS connection.
TAdsBatchMove can be used to migrate data from one table to another.
To create the browser program and the SQL executor program, the only objects that are
needed are the TAdsQuery and TAdsConnection components.
The TAdsConnection component (call it ACExecutor) needs 4 properties:
ConnectPath This should point to the data dictionary file, created with the database.
AdsServerTypes The server types that should be supported by this connection. For an
embedded database, this should be set to [stADS_LOCAL]
Username the username to be used for the connection. If a password was set for the
database, the password property should also be set.
IsConnected is a boolean which can be set to True to connect to the database.
procedure TMainForm.StartDatabase;
begin
ACExecutor.Isconnected:=True;
ACExecutor.BeginTransaction;
end;
procedure TMainForm.StopDatabase;
begin
ACExecutor.Commit;
ACExecutor.Isconnected:=False;
end;
begin
7
Try
QExecutor.SQL.Text:=SQL;
QExecutor.ExecSQL;
Except
On E: Exception do
begin
MLog.Lines.add(’Error executing statement: ’+E.Message);
If Not IgnoreError then
Raise;
end;
end;
end;
procedure TMainForm.CloseDatabase;
begin
QTrackData.Close;
QPupils.Close;
ACBrowser.IsConnected:=False;
end;
procedure TMainForm.OpenDatabase;
begin
ACBrowser.IsConnected:=True;
8
Figure 3: The Browser, compiled on Linux with Lazarus
QPupils.Open;
QTrackData.Open;
end;
The result can be seen in figure 3 on page 9. For the simple case of a data browser, it would
have been possible to use TAdsTable components: they can also be used to establish
master-detail relationships, in case both master and detail fields
6 Performance
The performance of the Advantage Database server has been compared with the perfor-
mance of the other databases. 4 tests were run:
SELECT
PU_ID,COUNT(PT_ID)
from
pupil
left join pupiltrack on (PU_ID=PT_PUPIL_FK);
9
3. Number of tracking entries on 6 september 2005, before 8:28 AM.
SELECT
COUNT(PT_ID)
FROM
PUPILTRACK
WHERE
(PT_DATE=’2005-09-06’)
AND (PT_CODE=’I’)
AND (PT_TIME<=’08:28:00’);
4. Number of different pupils entering school on 6 september 2005, before 8:28 AM.
SELECT
COUNT(PU_ID)
FROM
PUPIL LEFT JOIN PUPILTRACK ON (PT_PUPIL_FK=PU_ID)
WHERE
(PT_DATE=’2005-09-06’)
AND (PT_CODE=’I’)
AND (PT_TIME<=’08:28:00’);
1. If the database population script is run twice on the same database, the second run
has very poor performance: All records are deleted from the tables before they are
filled. But to achieve maximum performance, it is necessary to compact the table
after the records have been deleted. This can be done using the AdsPackTable
API call, but cannot be done in SQL.
2. The last test can be speeded up significantly by changing the query to:
SELECT
COUNT(PU_ID)
FROM
PUPIL, PUPILTRACK
WHERE
(PT_PUPIL_FK=PU_ID)
AND (PT_DATE=’2005-09-06’)
AND (PT_CODE=’I’)
AND (PT_TIME<=’08:28:00’);
Doing this reduces the execution time to 0.76 seconds, which suggests that the query
optimizer may need some help by tuning some queries by hand.
10
7 Conclusion
The Local Advantage Database server is definitely worth a look if an embedded database
is needed for an application. It offers performance, low memory footprint (provided some
elementary precautions are taken), a rich feature set, it can be connected to from various
environments (including Lazarus) and is scalable to full client-server network connectivity
- although a price must be paid for that: it is not (yet) open source. If this is not an issue:
Advantage Database Server is definitely a good bet.
The author wishes to thank Joachim Dürr, for the kind assistance he offered to solve some
set-up problems.
11