I spent the day today figuring out how to use Torque a stand alone
(non-turbine) application.  It was not hard once I figured out
where all the config files were and how to initialize torque without
using turbine.  I was documenting it for myself so I wouldn't forget
and decided to expand my notes a little bit and put it out to the
mailing list in the hopes that other new users might find it helpful.  

Let me preface by saying I am not real experienced in using databases 
or torque so I am sure there are better ways to do things or things 
I might have left out. But I tried to be detailed in all my steps and
this test worked for me.  If anyone wants to use this as a starting
point and expand on it or xdoc it, feel free. I did this under Redhat 
Linux 7.1 using the bash shell.  Windows users adjust the commands 
accordingly.

Almost everything in here assumes that you have the ant and cvs 
commands in your PATH enviroment variable.


Step 1) Build torque
---------------------
Download torque source. I do all my downloads under a directory called
projects.

> cd  ~/projects
> cvs -d :pserver:[EMAIL PROTECTED]:/home/cvspublic login 
> CVS password: anoncvs
> cvs -d :pserver:[EMAIL PROTECTED]:/home/cvspublic checkout
jakarta-turbine-torque  

Under the jakarta-turbine-torque directory there is a README.txt that
says
you must rename the build.properties.sample file to build.properties.
There 
is no build.properties.sample file but there is a default.properties
file. 
I made the assumption that this is the file intended and copied
default.properties 
to build.properties.

Inside build.properties you need to define 

  velocity.jar
  xerces.jar
  village.jar
  log4j.jar
  jdbc.jar
  junit.jar
  commons-collections.jar
  commons-util.jar

to point to the appropriate jar files.  I am still not sure why the jars
are 
not available under the lib directory of the jakarta-turbine-torque cvs
tree. 
You could take the time to download all the source for these jars and
build 
them. I started down this road but that required me to find all the jars
or 
source for the jars that these jars are dependent on... and so on.
Instead 
I looked around and was able to get all but the last 2 jars from the 
jakarta-turbine-2 cvs repository. Use the following cvs command to just 
checkout the lib directory from jakarta-turbine-2 project.

> cvs -d :pserver:[EMAIL PROTECTED]:/home/cvspublic checkout
jakarta-turbine-2/lib/

For the commons jars I had to get the project source from cvs and build
the jars

> cd ~/projects
> cvs -d :pserver:[EMAIL PROTECTED]:/home/cvspublic checkout
jakarta-commons 
> cd jakarta-commons/collections
> ant dist

NOTE: must have a xerces jar in your classpath for compile to work.
These 
steps generate the commons-collections.jar under the 
jakarta-commons/collections/dist directory.
This also assumes that you are still logged into the cvs server. If not,
then
relogin.

> cd ~/projects
> cvs -d :pserver:[EMAIL PROTECTED]:/home/cvspublic checkout
jakarta-commons-sandbox
> cd jakarta-commons-sandbox/util
> ant

NOTE: must have a xerces jar in your classpath for compile to work.
These steps 
generate the commons-util-0.1-dev.jar under the
jakarta-commons-sandbox/util 
directory.

I copied all the jars to a common lib directory and defined lib.repo to
be this
directory inside the ~projects/jakarta-turbine-torque/build.properties
file.

My final ~projects/jakarta-turbine-torque/build.properties file was as
follows:

#####################################################################
#---------------- Start File ----------------------------------------
#####################################################################
# -------------------------------------------------------------------
# B U I L D  P R O P E R T I E S
# -------------------------------------------------------------------
# These properties are used by the Torque build, you may override
# any of these default values by placing property values in
# your ${user.home}/build.properties file.
# -------------------------------------------------------------------

name = Torque
project = torque
version = 1.0
package = org.apache.${project}
final.name = ${project}-${version}

build.dir = ./bin
build.src = ${build.dir}/src
build.dest = ${build.dir}/classes
build.test = ${build.dir}/test
src.dir = ./src
test.dir = ${src.dir}/test

docs.src = ./xdocs
docs.dest = ./docs
javadoc.destdir = ./docs/api
jakarta.site2 = ../jakarta-site2

year = 1999-2001
debug = on
optimize = off
deprecation = off

# You must set these values here, or in your
# ${user.home}/build.properties file in order
# to build Torque:

lib.repo = /usr/local/java/lib
velocity.jar = ${lib.repo}/velocity-1.2-dev.jar
xerces.jar = ${lib.repo}/xerces-1.3.0.jar
village.jar = ${lib.repo}/village-1.5.3-dev.jar
log4j.jar = ${lib.repo}/log4j-1.1.jar
commons-collections.jar = ${lib.repo}/commons-collections.jar
commons-util.jar = ${lib.repo}/commons-util-0.1-dev.jar
jdbc.jar = ${lib.repo}/jdbc2_0-stdext.jar
junit.jar = ${lib.repo}/junit-3.2.jar
#####################################################################
#---------------- End File ----------------------------------------
#####################################################################


Now that we have all the needed jars that torque depends on,
go into jakarta-turbine-torque directory and build torque

> cd ~/projects/jakarta-turbine-torque
> ant dist

This creates ~/projects/jakarta-turbine-torque/bin directory
which contains all the parts need to use torque. It also includes
torque-1.0.zip which has everything you need nicely bundled up
to allow your to relocate it where ever you want.


Step 2) Deploy torque
----------------------
Unpack torque-1.0.zip where you want to develop your app. For me
once again it was under my projects directory

> cd ~/projects
> unzip ./jakarta-turbine-torque/bin/torque-1.0.zip

This will build a ~/projects/torque directory. Inside this directory
is the build.properties and build.xml files. For some reason the 
permissions were all screwed up in this unpacked torque directory. 
I had to fix these permissions to allow me read/write/execute access 
to the subdirectories.


Step 3) Create your project configuration files.
----------------------------------------------------------------------
Edit ~/projects/torque/build.properties.  I changed the project name 
to be "my-test".  My database was mysql which is the default so I 
did not change that.  I changed the targetPackage to be my java package 
name "com.digitalevergreen.mytest.om". I set databaseUser and
databasePassword 
to be my mysql admin user id and password. I changed the databaseUrl 
to create a table called MY_TEST_DB. Instead of listing out the whole 
file, I will only list the lines I changed in build.properties.

   project=my-test
   targetPackage=com.digitalevergreen.mytest.om
   databaseUrl = jdbc:mysql://127.0.0.1/MY_TEST_DB
   databaseUser = adminuser
   databasePassword = adminpassword


Because I changed my project name to my-test I have to create a
file called my-test-schema.xml under the ~/projects/torque/schema
directory. This will contain the xml definition of our objects 
and database. 

For my example test case I chose a book catalog. My schema contains 
three tables. I have a table that contains author information (first, 
middle and last name), a table that contains publisher information
(name), 
and the last table contains book information (Title, copyright info, and

ISBN). The author id, and publisher id will be foreign keys in the 
book table. My schema xml is shown below

<?xml version="1.0" encoding="ISO-8859-1" standalone="no" ?>
<!DOCTYPE app-data SYSTEM
"http://jakarta.apache.org/turbine/dtd/database.dtd";>
<!-- =============================================================== -->
<!-- ====================  START SCHEMA ============================ -->
<!-- =============================================================== -->
<app-data>
                
<database>
  <table name="BOOK">
    <column name="BOOK_ID" required="true" autoIncrement="true"
            primaryKey="true" type="INTEGER" javaName="Id"/>
    <column name="TITLE" required="true" type="VARCHAR" size="255"/>
    <column name="COPYRIGHT" type="VARCHAR" size="255"/>
    <column name="ISBN" type="VARCHAR" size="24" javaName="ISBN"/>
    <column name="PUBLISHER_ID" type="INTEGER"/>
    <column name="AUTHOR_ID" type="INTEGER"/>
 
    <foreign-key foreignTable="PUBLISHER">
        <reference local="PUBLISHER_ID" foreign="PUBLISHER_ID"/>
    </foreign-key>
 
    <foreign-key foreignTable="AUTHOR">
        <reference local="AUTHOR_ID" foreign="AUTHOR_ID"/>
    </foreign-key>
  </table>
 
  <table name="PUBLISHER">
    <column name="PUBLISHER_ID" required="true" primaryKey="true"
            type="INTEGER" autoIncrement="true" javaName="Id"/>
    <column name="NAME" type="VARCHAR" size="128" />
  </table>
 
  <table name="AUTHOR">
    <column name="AUTHOR_ID" required="true" primaryKey="true"
            type="INTEGER" autoIncrement="true" javaName="Id"/>
    <column name="FIRST_NAME" type="VARCHAR" size="128" />
    <column name="MIDDLE_NAME" type="VARCHAR" size="128" />
    <column name="LAST_NAME" type="VARCHAR" size="128" />
  </table>
 
</database>
 
</app-data>     
<!-- =============================================================== -->
<!-- ====================  END SCHEMA ============================== -->
<!-- =============================================================== -->


Step 4) Run Torque to build your source files
------------------------------------------------------
Run torque to build the object model and map source files.

> cd ~/projects/torque
> ant

Hopefully you will then see output similar to 


> Searching for build.xml ...
> Buildfile: /home/sdavis/projects/torque/build.xml
> 
> main:
> 
> init-tasks:
> 
> project-sql:
> +------------------------------------------+
> |                                          |
> | Generating SQL for YOUR Turbine project! |
> | Woo hoo!                                 |
> |                                          |
> +------------------------------------------+
> /home/sdavis/projects/torque/src/sql/report.my-test.sql.generation
> Resolver: used database.dtd
> 
> init-tasks:
> 
> project-om:
> +------------------------------------------+
> |                                          |
> | Generating Peer-based Object Model for   |
> | YOUR Turbine project! Woo hoo!           |
> |                                          |
> +------------------------------------------+
> /home/sdavis/projects/torque/src/java/report.my-test.om.generation
> Resolver: used database.dtd
> Resolver: used database.dtd
>  
> BUILD SUCCESSFUL
>  
> Total time: 9 seconds 

If you did see this then you should have java source files under 
~projects/torque/src/java/com/digitalevergreen/mytest/om/ 
directory that are similar to the following:

-rw-r--r--    1 sdavis   users         509 Sep 24 23:27 Author.java
-rw-r--r--    1 sdavis   users         629 Sep 24 23:27 AuthorPeer.java
-rw-r--r--    1 sdavis   users       15331 Sep 24 23:27 BaseAuthor.java
-rw-r--r--    1 sdavis   users       14828 Sep 24 23:27
BaseAuthorPeer.java
-rw-r--r--    1 sdavis   users       15731 Sep 24 23:27 BaseBook.java
-rw-r--r--    1 sdavis   users       19104 Sep 24 23:27
BaseBookPeer.java
-rw-r--r--    1 sdavis   users       13240 Sep 24 23:27
BasePublisher.java
-rw-r--r--    1 sdavis   users       13994 Sep 24 23:27
BasePublisherPeer.java
-rw-r--r--    1 sdavis   users         505 Sep 24 23:27 Book.java
-rw-r--r--    1 sdavis   users         625 Sep 24 23:27 BookPeer.java
drwxr-xr-x    2 sdavis   users        4096 Sep 24 23:27 map
-rw-r--r--    1 sdavis   users         515 Sep 24 23:27 Publisher.java
-rw-r--r--    1 sdavis   users         635 Sep 24 23:27
PublisherPeer.java

Step 5) Create the database and tables
--------------------------------------------------------------
I thought there was a way to have torque automatically create the 
database but I could not figure out how to make it do that. I manually 
created the database and then used the torque generated sql statements 
to set up the tables.

> cd ~/projects/torque/src/sql
> mysql -u <user id> -p<password> mysql
mysql> create database MY_TEST_DB;
mysql> quit
> mysql -u <user_id> -p<password> MY_TEST_DB < my-test-schema.sql 


Step 6) Make it all usable in a stand alone program
--------------------------------------------------------------
Ok, all that was great. We have a bunch of java source files and a
database to go with them.  How do we use it?  It actually turned out
to be pretty easy once I tracked down the initialization requirements
in the Torque code.  Torque only requires you to initialize the 
database info... but you will get system out errors from log4j if you
don't initialize it also. I created the following properties file in 
~/projects/torque/mytest.properties.


# -------------------------------------------------------------------
# Begin mytest.properties
# -------------------------------------------------------------------
# -------------------------------------------------------------------
# 
#  D A T A B A S E  S E R V I C E
#
# -------------------------------------------------------------------
# These are your database settings.  Look in the
# org.apache.turbine.util.db.pool.* packages for more information.
# The default driver for Turbine is for MySQL.
#
# The parameters to connect to the default database.  You MUST
# configure these properly.
# -------------------------------------------------------------------

services.DatabaseService.database.default=default

services.DatabaseService.database.default.driver=org.gjt.mm.mysql.Driver
services.DatabaseService.database.default.url=jdbc:mysql://localhost:330
6/MY_TEST_DB
services.DatabaseService.database.default.username=adminuser
services.DatabaseService.database.default.password=adminpassword

# The number of database connections to cache per ConnectionPool
# instance (specified per database).

services.DatabaseService.database.default.maxConnections=3

# The amount of time (in milliseconds) that database connections will be
# cached (specified per database).
#
# Default: one hour = 60 * 60 * 1000

services.DatabaseService.database.default.expiryTime=3600000

# The amount of time (in milliseconds) a connection request will have to
wait
# before a time out occurs and an error is thrown.
#
# Default: ten seconds = 10 * 1000

services.DatabaseService.database.connectionWaitTimeout=10000

# The interval (in milliseconds) between which the PoolBrokerService
logs 
# the status of it's ConnectionPools.
#
# Default: No logging = 0 = 0 * 1000

services.DatabaseService.database.logInterval=0

# These are the supported JDBC drivers and their associated Turbine
# adapter.  These properties are used by the DBFactory.  You can add
# all the drivers you want here.

services.DatabaseService.database.adapter=DBMM
services.DatabaseService.database.adapter.DBMM=org.gjt.mm.mysql.Driver

# Determines if the quantity column of the IDBroker's id_table should
# be increased automatically if requests for ids reaches a high
# volume.

services.DatabaseService.database.idbroker.cleverquantity=true

# Determines if IDBroker should prefetch IDs or not.  If set to false
# this property has the effect of shutting off the housekeeping thread
# that attempts to prefetch the id's.  It also sets the # of id's
grabbed
# per request to 1 regardless of the settings in the database.
# Default: true

services.DatabaseService.database.idbroker.prefetch=true

services.DatabaseService.earlyInit = true


# -------------------------------------------------------------------
#
#  log4j
#
# -------------------------------------------------------------------
# Need to have log4j "appenders" for Torque or log4j will generate
# system out errors.
log4j.category.org.apache.torque = INFO, torque
log4j.appender.torque = org.apache.log4j.FileAppender
log4j.appender.torque.file = ./mytest.log
log4j.appender.torque.layout = org.apache.log4j.PatternLayout
log4j.appender.torque.layout.conversionPattern = %d [%t] %-5p %c - %m%n
log4j.appender.torque.append = false

# -------------------------------------------------------------------
# End mytest.properties
# -------------------------------------------------------------------


I then created the file
~/projects/torque/src/java/com/digitalevergreen/mytest/MyTest.java
which contains code to initialize torque and run a brief test of
my test objects. Here is my test source.

//////////////////////////////////////////////////////////////////
// Begin MyTest.java source 
//////////////////////////////////////////////////////////////////
package com.digitalevergreen.mytest;

import com.digitalevergreen.mytest.om.*;
import org.apache.torque.Torque;
import org.apache.torque.util.Criteria;

import java.util.Vector;

public class MyTest
{
    public static void main(String[] args)
    {
        try
        {
            // Initialze Torque
            Torque.init( "./mytest.properties" );
           
            // Create some Authors
            Author de = new Author();
            de.setFirstName( "David" );
            de.setLastName( "Eddings" );
            de.save();
           
            Author tg = new Author();
            tg.setFirstName( "Terry" );
            tg.setLastName( "Goodkind" );
            tg.save();

            // Create publishers
            Publisher b = new Publisher();
            b.setName( "Ballantine" );
            b.save();

            Publisher t = new Publisher();
            t.setName( "Tor" );
            t.save();


            // Ok. For some reason even though the BaseXPeer doInsert 
            // methods return the primary key it is not set in the
            // BaseX save method so we have to "retrieve" these objects
            // from the database or we will get null value exceptions
            // when we try to use them in the book objects and do a
save.
            Criteria crit = new Criteria();
            crit.add( AuthorPeer.LAST_NAME, "Eddings" );
            Vector v = AuthorPeer.doSelect( crit );
            if ( v != null && v.size() > 0 )
                de = (Author) v.elementAt(0);

            crit = new Criteria();
            crit.add( AuthorPeer.LAST_NAME, "Goodkind" );
            v = AuthorPeer.doSelect( crit );
            if ( v != null && v.size() > 0 )
                tg = (Author) v.elementAt(0);

            crit = new Criteria();
            crit.add( PublisherPeer.NAME, "Ballantine" );
            v = PublisherPeer.doSelect( crit );
            if ( v != null && v.size() > 0 )
                b = (Publisher) v.elementAt(0);

            crit = new Criteria();
            crit.add( PublisherPeer.NAME, "Tor" );
            v = PublisherPeer.doSelect( crit );
            if ( v != null && v.size() > 0 )
                t = (Publisher) v.elementAt(0);


            // Create books
            Book wfr = new Book();
            wfr.setTitle( "Wizards First Rule" );
            wfr.setCopyright( "1994" );
            wfr.setISBN( "0-812-54805-1" );
            wfr.setPublisher( t );
            wfr.setAuthor( tg );
            wfr.save();

            Book dof = new Book();
            dof.setTitle( "Domes of Fire" );
            dof.setCopyright( "1992" );
            dof.setISBN( "0-345-38327-3" );
            dof.setPublisher( b );
            dof.setAuthor( de );
            dof.save();


            // Get and print books from db
            crit = new Criteria();
            v = BookPeer.doSelect( crit );
            for ( int i = 0; i < v.size(); i++ )
            {
                Book book = (Book) v.elementAt(i);
                System.out.println("Title: " + book.getTitle() );
                System.out.println("Author: " +
book.getAuthor().getFirstName() 
                                   + " " +
book.getAuthor().getLastName() );
                System.out.println("Publisher: " +
book.getPublisher().getName() );
                System.out.println("\n\n");
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
}
//////////////////////////////////////////////////////////////////
// End MyTest.java source 
//////////////////////////////////////////////////////////////////

Step 7) Build the test app
----------------------------------------------------------
The ant configuration in torque should be set up to compile all the
source. This assumes that you put your MyTest.java in the 
~/projects/torque/src directory tree. To build just do an ant compile.

> cd ~/projects/torque
> ant compile

This will place all the compiled class files under 
~/projects/torque/bin/classes

Step 8) Run the test
----------------------------------------------------------
You need to have the torque/bin/classes directory in your classpath
along with all the jars in the torque/lib directory. You also
need to have the database driver in your classpath.  I set my
classpath as follows:

>
CLASSPATH=~/projects/torque/lib/torque-1.0.jar:~/projects/torque/lib/com
mons-util-0.1-dev.jar:~/projects/torque/lib/commons-collections.jar:~/pr
ojects/torque/lib/jdbc2_0-stdext.jar:~/projects/torque/lib/log4j-1.1.jar
:~/projects/torque/lib/velocity-1.2-dev.jar:~/projects/torque/lib/villag
e-1.5.3-dev.jar:~/projects/torque/lib/xerces-1.3.0.jar:~/projects/torque
/lib/mysql_uncomp.jar:./bin/classes/; export CLASSPATH

Once this is set then run the MyTest.java main.

> cd ~/projects/torque
> java com.digitalevergreen.mytest.MyTest

You should see the following output:

> Title: Wizards First Rule
> Author: Terry Goodkind
> Publisher: Tor
> 
> 
> 
> Title: Domes of Fire
> Author: David Eddings
> Publisher: Ballantine


Pretty simple, powerful, and cool once I figured it out.
Anyway thats how I got it to work. Anyone that has suggestions
for better ways to do it please let me know.

-- Steven F. Davis

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to