.::=How-to=::.

Custom database broker

To retrive references to databases, Butler uses a DatabaseBroker. Normally the default implementation (DefaultDatabaseBroker) is used. This implementation will retrieve jdbc url:s etc from an xml file specified by the system property "butler.config.file". But if you want to configure your application in another way, you can make a custom implementation of DatabaseBroker. To register this implementation, you have to call DatabaseBroker.setInstance method in the start-up phase of your application.

Custom datatypes

Butler has built-in support for the datatypes that normally exists in a database like strings, numbers, dates and blobs. If you use other custom datatypes like telephone number, e-mail adress, etc, you can make a custom implementation of the Datatype (in package butler.sql.metadata) interface. This should be done by extending DefaultDatatype.

If you want to transform the data before and after reading and writing to the database, you should override db2obj-, obj2db- and xml2obj methods. If you want the data to be formatted (in GUI or xmlization), you should override getFormat method. If you need to validation, you should override validate method.

After creating your implementation of Datatype, you should associate the datatype to the column(s). This can be done in the generated table class. In the contructor for these classes, you will find a createColumn-call for each column in the table. Add an instance of your datatype as an extra parameter in this call.

Virtual foreign keys

In some databases, foreign keys are not defined due to performance reason or some other reason. But logically there may be a relation between two tables. If you use generated table classes, the foreign keys can be defined in the constructor of these classes.

First, you need to define the foreign key in the foreign key table (many table). You should create a ForeignKey instance that takes two Table instances and one string (foreign key name) as argument. After that you need to add the columns to the ForeignKey instance using the add method. Here you should supply columns from the foreign key table (not the primary key table). The columns need to be added in the same orders as they occur in the primary key.

Second, you nedd to define the foreign key in the primary key table (one table). You should create a ForeignKey instance that takes one Table, two strings (foreign key table name and foreign key name) as argument. In this case you don't need to add the foreign key columns. Finally the the foreign key has to be added to the table.

Enabling 3-tier infrastructure

When you are using data-aware components in default configuration, the client application will make JDBC-calls to a remote database server directly. In some environments remote JDBC calls might not be possible. In this case a Butler service can be published on an application server. The client application will make RMI calls to the service which will make JDBC calls to the database. Another advantage with this configuration is that trigger execution will be done on the application server. The Butler service will be protected by a security mechanism that is more advanced than most mechanism in databases.

To start a Butler service on the application server, you need to run the main method in butler.sql.driver.SQLServiceImpl. If you want another port than the default port, 7123, you should pass the arguments "-port xxx".

On the client side you need to tell the DefaultDatabaseBroker to use butler.sql.driver.ClientDriver by calling the method setDriver. If you are using a customer database broker, this broker has to implement the method getDriver, returning the corrent driver.