Specification of QDBM for Java

Copyright (C) 2000-2003 Mikio Hirabayashi
Last Update: Fri, 04 Apr 2003 00:48:37 +0900
[API][Japanese] [Home]

Table of Contents

  1. Overview
  2. Installation
  3. Setting
  4. Examples
  5. Bugs

Overview

QDBM provides API for Java. This encapsulates the basic API and the extended API of QDBM, and make them thread-safe. This API is implemented with the APIs for C called with Java Native Interface.

The basic API for Java realizes a database with a file. Constructors of the class `Depot' open a database file. The method `close' is used in order to close the database. Although the finalizer also try to close the database, do not rely on it. The method `put' is used in order to store a record. The method `out' is used in order to delete a record. The method `get' is used in order to retrieve a record. Besides, most operations like ones of the basic API for C is available. Each methods throws an instance of the class `DepotException' if an error occures.

The extended API for Java realizes a database with a file. Constructors of the class `Curia' open a database file. The method `close' is used in order to close the database. Although the finalizer also try to close the database, do not rely on it. The method `put' is used in order to store a record. The method `out' is used in order to delete a record. The method `get' is used in order to retrieve a record. Operations for managing large objects are also privided. Besides, most operations like ones of the extended API for C is available. Each methods throws an instance of the class `CuriaException' if an error occures.

Both of the class `Depot' and the class `Curia' implement the interface `ADBM' which is abstraction of database managers compatible with DBM of UNIX standard. Each methods throws an instance of the class `DBMException'. In this framework, it is possible to store a serializable object in the database. This mechanism is useful for object persistence. When you choose the one of three API, `Depot' is suggested if performance is weighted, `Curia' is suggested if scalability is weighted, , `ADBM' is suggested if elegance and maintenance are weighted.

For more information about the APIs, read documents in the sub directory `japidoc' and each header file.


Installation

Make sure that JDK of 1.2 or later version is installed, the environment variable JAVA_HOME is set appropriately. And make sure that QDBM is installed under `/usr/local'.

Change the current working directory to the subdirectory named `java'.

cd java

Run the configuration script.

./configure

Build programs.

make

Perform self-diagnostic test.

make check

Install programs This operation must be carried out by the root user.

make install

When a series of work finishes, a Java archive `qdbm.jar' is installed under the `/usr/local/lib'. And, such native libraries as `libjqdbm.so' are installed under `/usr/local/lib'.

On Windows (Cygwin), you should follow the procedures below for installation.

Run the configuration script.

./configure

Build programs.

make win

Perform self-diagnostic test.

make check

Install programs. As well, perform `make uninstall-win' to uninstall them.

make install-win

On Windows, an import library `libjqdbm.dll.a' is created, and a dynamic linking library `jqdbm.dll' is created instead of such a shared libraries as `libjqdbm.so'. `jqdbm.dll' is installed into such a system directory as `C:\WINNT\SYSTEM32'.


Setting

To build and execute programs using QDBM, the following environment variable should be set.

Set the class path, which the environment variable CLASSPATH defines, to include the full path of `qdbm.jar'.

CLASSPATH=$CLASSPATH:/usr/local/lib/qdbm.jar
export CLASSPATH

Set the library path, which the environment variable LD_LIBRARY_PATH defines, to include `/usr/local/lib'.

LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib
export LD_LIBRARY_PATH

Examples

The following example stores and retrieves a phone number, using the name as the key.

import qdbm.*;

public class Sample {

  static String NAME = "mikio";
  static String NUMBER = "000-1234-5678";
  static String DBNAME = "book";

  public static void main(String[] args){
    Depot depot = null;
    try {

      // open the database
      depot = new Depot(DBNAME, Depot.OWRITER | Depot.OCREAT, -1);

      // store the record
      depot.put(NAME.getBytes(), NUMBER.getBytes());

      // retrieve the record
      byte[] res = depot.get(NAME.getBytes());
      System.out.println("Name: " + NAME);
      System.out.println("Number: " + new String(res));

    } catch(DepotException e){
      e.printStackTrace();
    } finally {

      // close the database
      if(depot != null){
        try {
          depot.close();
        } catch(DepotException e){
          e.printStackTrace();
        }
      }

    }
  }

}

The following example is a transcription of the one above, using the interface `ADBM'.

import qdbm.*;

public class Sample {

  static String NAME = "mikio";
  static String NUMBER = "000-1234-5678";
  static String DBNAME = "book";

  public static void main(String[] args){
    ADBM dbm = null;
    try {

      // open the database
      dbm = new Depot(DBNAME, Depot.OWRITER | Depot.OCREAT, -1);

      // store the record
      dbm.storeobj(NAME, NUMBER, true);

      // retrieve the record
      Object res = dbm.fetchobj(NAME);
      System.out.println("Name: " + NAME);
      System.out.println("Number: " + res);

    } catch(DBMException e){
      e.printStackTrace();
    } finally {

      // close the database
      if(dbm != null){
        try {
          dbm.close();
        } catch(DBMException e){
          e.printStackTrace();
        }
      }

    }
  }

}

For building a program using Java API of QDBM, set the environment variables and then perform `javac'. For example, the following command is executed to build `Sample.class' from `Sample.java'.

javac Sample.java

Bugs

Depot and Curia have restrictions that two or more handles of the same database file should not be used by a process at the same time. So, when a database is used by two or more threads, open the database in the main thread and pass the handle to each thread.

Although methods to store a serialized object is useful, object serialization is inefficient in time and space. So, if there is a method to get a byte array from an object, you should use APIs with byte arrays.