<property name="hsqldb.base" value="${basedir}/build/hsqldb"/>
<property name="hsqldb.version" value="1_7_1"/>
<property name="hsqldb.dist" value="http://belnet.dl.sourceforge.net/sourceforge/hsqldb/hsqldb_${hsqldb.version}.zip"/>
<!--+
| Download the Hsqldb binary.
+-->
<target name="hsqldb.dist.fetch" depends="">
<mkdir dir="${hsqldb.base}"/>
<get verbose="true" usetimestamp="true"
src="${hsqldb.dist}"
dest="${hsqldb.base}/hsqldb-${hsqldb.version}.zip"
/>
</target>
This results in the Hsqldb distribution downloaded to our project directory :
policy
+-- build.xml
\-- build
\-- hsqldb
\-- *hsqldb-1_7_1.zip*
The binary distribution is packed as a standard zip file, containing the compiled Java code and some documentation.
The following Ant task unpacks the zip into our project build directory :
<property name="hsqldb.base" value="${basedir}/build/hsqldb"/>
<property name="hsqldb.version" value="1_7_1"/>
<!--+
| Unzip the Hsqldb binary.
+-->
<target name="hsqldb.dist.unzip" depends="">
<unzip src="${hsqldb.base}/hsqldb-${hsqldb.version}.zip"
dest="${hsqldb.base}"
/>
</target>
This results in the following files installed in our project directory, most important of which is the binary jar file in the lib directory :
policy
+-- build.xml
\-- build
\-- hsqldb
+-- hsqldb-1_7_1.zip
\-- hsqldb
|
+-- bin
+-- build
+-- demo
+-- doc
+-- src
+-- lib
\-- hsqldb.jar
With the Hsqldb jar file in place, we can define an Ant path to reference the jar file.
We can use this later in other Ant tasks without having to explicitly add the full location of the Hsqldb jar each time.
<!--+
| The Hsqldb library classpath.
+-->
<path id="hsqldb.classpath">
<pathelement location="${hsqldb.home}/lib/hsqldb.jar"/>
</path>
<property name="hsqldb.data" value="${basedir}/build/hsqldb/data"/>
<property name="hsqldb.host" value="localhost"/>
<property name="hsqldb.port" value="9001"/>
<property name="hsqldb.database" value="policy"/>
<!--+
| Start the Hsqldb database server.
+-->
<target name="hsqldb.start" depends="">
<!-- Create the data directory -->
<mkdir dir="${hsqldb.data}"/>
<!-- Start the database server -->
<echo message=""/>
<echo message="Starting Hqsldb ...."/>
<java taskname="hsqldb" classname="org.hsqldb.Server" fork="true" dir="${hsqldb.data}">
<!-- Use the Hsqldb classpath -->
<classpath refid="hsqldb.classpath"/>
<!-- Args for the Hsqldb server -->
<arg value="-database"/>
<arg value="${hsqldb.database}"/>
<arg value="-port"/>
<arg value="${hsqldb.port}"/>
</java>
</target>
This is equivalent to typing the following command line in Linux.
mkdir build/hsqldb/data cd build/hsqldb/data java -classpath build/hsqldb/hsqldb/lib/hsqldb.jar org.hsqldb.Server -database policy -port 9001Once we have started our database server, we need to be able to shut it down. If the database server has been started from the command line, then typing
ctrl^C should shutdown the server.
However, it would be useful to be able to shut it down automatically, using the same tools we used to start it.
The following Ant task connects to a Hsqldb server on local host and asks it to shutdown.
<property name="hsqldb.host" value="localhost"/>
<property name="hsqldb.port" value="9001"/>
<property name="hsqldb.database" value="policy"/>
<property name="hsqldb.user" value="sa"/>
<property name="hsqldb.pass" value="veritas"/>
<property name="hsqldb.url" value="jdbc:hsqldb:hsql://${hsqldb.host}:${hsqldb.port}"/>
<!--+
| Stop the Hsqldb database server.
+-->
<target name="hsqldb.stop" depends="">
<echo message=""/>
<echo message="Stopping Hqsldb ...."/>
<java taskname="hsqldb" classname="org.hsqldb.util.ShutdownServer" fork="true" dir="${hsqldb.data}">
<!-- Use the Hsqldb classpath -->
<classpath refid="hsqldb.classpath"/>
<!-- Args for the Hsqldb server -->
<arg value="-url"/>
<arg value="${hsqldb.url}"/>
<arg value="-user"/>
<arg value="${hsqldb.user}"/>
<arg value="-password"/>
<arg value="${hsqldb.pass}"/>
</java>
</target>
This is equivalent to typing the following command line in Linux.
cd build/hsqldb/data java -classpath build/hsqldb/hsqldb/lib/hsqldb.jar org.hsqldb.Server -url jdbc:hsqldb:hsql://localhost:9001 -user sa -password veritas
<property name="hsqldb.host" value="localhost"/>
<property name="hsqldb.port" value="9001"/>
<property name="hsqldb.database" value="policy"/>
<property name="hsqldb.user" value="sa"/>
<property name="hsqldb.pass" value="veritas"/>
<property name="hsqldb.url" value="jdbc:hsqldb:hsql://${hsqldb.host}:${hsqldb.port}"/>
<!--+
| Initialise the Hsqldb database.
| This only needs to run once, when a new database is created.
+-->
<target name="hsqldb.init" depends="">
<echo message=""/>
<echo message="Initialising Hqsldb ...."/>
<sql driver="org.hsqldb.jdbcDriver"
url="${hsqldb.url}"
classpathref="hsqldb.classpath"
userid="sa"
password=""
print="true"
>
<![CDATA[
set password "${hsqldb.pass}" ;
]]>
</sql>
</target>
--
-- Drop the Accounts table
DROP TABLE accounts IF EXISTS ;
--
-- Create the Accounts table
CREATE TABLE accounts
(
name VARCHAR NOT NULL,
community VARCHAR NOT NULL,
description VARCHAR NULL,
PRIMARY KEY ( name, community )
) ;
Database experts will probably question the use of two text fields as the primary key in the accounts table.
I know this is definitely not the best way of indexing a table.
However, this fits with some of our current thoughts on how we want to refer to accounts in the CommunityPolicy? service.
Using the account name and community together in a similar way to email addresses, name[at]community, as the unique identifier for an account.
At this stage, I've left this in to see if it is possible to handle multi-value primary keys in the Castor JDO toolkit.
In practice, when it comes to implementing the real CommunityPolicy? database we will probably use an integer primary key internally within the database.
The following Ant task connects to our database and runs the script to create the database table.
<!--+
| Create the Hsqldb database tables.
+-->
<target name="hsqldb.create" depends="">
<echo message=""/>
<echo message="Creating Hqsldb tables ...."/>
<sql driver="org.hsqldb.jdbcDriver"
url="${hsqldb.url}"
classpathref="hsqldb.classpath"
userid="${hsqldb.user}"
password="${hsqldb.pass}"
print="true"
>
<transaction src="src/sql/hsqldb/create.sql"/>
</sql>
</target>
<!--+
| Insert some rows into the accounts table.
+-->
<target name="hsqldb.accounts.insert" depends="">
<sql driver="org.hsqldb.jdbcDriver"
url="${hsqldb.url}"
classpathref="hsqldb.classpath"
userid="${hsqldb.user}"
password="${hsqldb.pass}"
print="true"
>
<![CDATA[
INSERT INTO accounts (name, community, description) VALUES ('guy', 'cambridge', 'Guy Rixon') ;
INSERT INTO accounts (name, community, description) VALUES ('dave', 'cambridge', 'Dave Morris') ;
INSERT INTO accounts (name, community, description) VALUES ('richard', 'cambridge', 'Richard McMahon') ;
INSERT INTO accounts (name, community, description) VALUES ('nicholas', 'cambridge', 'Nicholas Walton') ;
INSERT INTO accounts (name, community, description) VALUES ('brian', 'rutherford', 'Brian McIlwrath') ;
INSERT INTO accounts (name, community, description) VALUES ('kevin', 'mullard', 'Kevin Benson') ;
INSERT INTO accounts (name, community, description) VALUES ('paul', 'joderell', 'Paul Harrison') ;
]]>
</sql>
</target>
<!--+
| Select all rows from the accounts table.
+-->
<target name="hsqldb.accounts.select" depends="">
<sql driver="org.hsqldb.jdbcDriver"
url="${hsqldb.url}"
classpathref="hsqldb.classpath"
userid="${hsqldb.user}"
password="${hsqldb.pass}"
print="true"
>
<![CDATA[
SELECT * FROM accounts ;
]]>
</sql>
</target>
<!--+
| Delete all rows from the accounts table.
+-->
<target name="hsqldb.accounts.delete" depends="">
<sql driver="org.hsqldb.jdbcDriver"
url="${hsqldb.url}"
classpathref="hsqldb.classpath"
userid="${hsqldb.user}"
password="${hsqldb.pass}"
print="true"
>
<![CDATA[
DELETE FROM accounts ;
]]>
</sql>
</target>
<!--+
| Delete the Hsqldb data files.
+-->
<target name="hsqldb.data.delete" depends="">
<delete dir="${hsqldb.data}" failonerror="false"/>
</target>
Next, a task to wait for the database server to respond.
This uses the waitfor Ant task to try to open a socket connection to the database server.
<property name="hsqldb.host" value="methionine.codon.demon.co.uk"/>
<property name="hsqldb.port" value="9001"/>
<property name="hsqldb.timeout" value="60"/>
<!--+
| Wait for the Hsqldb database to start.
+-->
<target name="hsqldb.wait" depends="">
<echo message=""/>
<echo message="Waiting for Hqsldb ...."/>
<waitfor maxwait="${hsqldb.timeout}" maxwaitunit="second" checkevery="500">
<socket server="${hsqldb.host}" port="${hsqldb.port}"/>
</waitfor>
</target>
We can now begin to group the individual Ant tasks together into more useable components.
First, a task to download and install the Hsqldb distribution.
<!--+
| Prepare the Hsqldb toolkit.
+-->
<target name="hsqldb.PREPARE" depends="">
<antcall target="hsqldb.dist.fetch"/>
<antcall target="hsqldb.dist.unzip"/>
</target>
Next, a task to build the database tables.
This waits for the server to respond, initialises the admin password, creates the accounts table and adds the initial test data into it.
<!--+
| Build our Hsqldb database.
+-->
<target name="hsqldb.BUILD" depends="">
<antcall target="hsqldb.wait"/>
<antcall target="hsqldb.init"/>
<antcall target="hsqldb.create"/>
<antcall target="hsqldb.accounts.insert"/>
<antcall target="hsqldb.accounts.select"/>
</target>
And finally, we can create a top level task to start the database server and build the database tables.
This task starts by deleting any existing data files, and then runs two threads in parallel; one to start the database server, and the second to build the database tables once the server is running.
The second starts with the hsqldb.wait step, which means that the second thread will wait until the database server is up and running before trying to create the database tables.
<!--+
| Rebuild our Hsqldb database.
+-->
<target name="hsqldb.REBUILD" depends="">
<antcall target="hsqldb.data.delete"/>
<parallel>
<sequential>
<antcall target="hsqldb.start"/>
</sequential>
<sequential>
<antcall target="hsqldb.BUILD"/>
</sequential>
</parallel>
</target>
So, with this in place, all we need to do is run the hsqldb.PREPARE task once to download and install the Hsqldb libraries.
We can then run the hsqldb.REBUILD task as often as required, re-building the entire database from scratch each time.
This gives a repeatable and testable platform to use while developing the Castor JDO components.
-- DaveMorris - 17 Aug 2003![]() |
Click here for the AstroGrid Service Web |
This is the AstroGrid Development Wiki |
|