QDBM provides API for Java. This encapsulates the basic API, the extended API, and the advanced API of QDBM, and make them thread-safe. These APIs are implemented with the APIs for C called with Java Native Interface.
The basic API for Java realizes a hash 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 are available. Each methods throws an instance of the class `DepotException' if an error occurs.
The extended API for Java realizes a hash database with a directory and multiple files. Constructors of the class `Curia' open a database directory. 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 provided. Besides, most operations like ones of the extended API for C are available. Each methods throws an instance of the class `CuriaException' if an error occurs.
The advanced API for Java realizes a B+ tree database with a file. Constructors of the class `Villa' 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 advanced API for C are available. Each methods throws an instance of the class `VillaException' if an error occurs.
`Depot', `Curia', and `Villa' 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'. When you choose the one of four APIs, `Depot' is suggested if performance is weighted, `Curia' is suggested if scalability is weighted, `Villa' is suggested if ordering access is required, `ADBM' is suggested if elegance and maintenance are weighted. Besides, a database file is not compatible with each API.
Each class is packaged in `qdbm'. You can import the package in source files of application.
While APIs for C are thread-safe unless plural threads do not share a database handle, APIs for Java are thread-safe even if plural threads share a handle.
When `put' overwriting an existing record is cancelled or `get' retrieving a missing record, failure of the operation is noticed by exception. If you dislike such behavior, set the `silent' flag to be true. Then, failure of the operation is noticed by the return value.
For more information about the APIs, read documents in the sub directory `japidoc'.
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 sub directory named `java'.
cd java
Run the configuration script. If you use GCC for Java compilation, append the option `--with-gcj'.
./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'.
To uninstall them, execute the following command after `./configure'. This operation must be carried out by the root user.
make uninstall
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-win
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 `/usr/local/bin'.
In order to build QDBM using MinGW on Cygwin, you should perform `make mingw' instead of `make win'. With the UNIX emulation layer of Cygwin, generated programs depend on `cygwin1.dll'. This problem is solved by linking them to the Win32 native DLL with MinGW.
On Mac OS X (Darwin), you should follow the procedures below for installation.
Run the configuration script.
./configure
Build programs.
make mac
Perform self-diagnostic test.
make check-mac
Install programs. As well, perform `make uninstall-mac' to uninstall them.
make install-mac
On Mac OS X, `libjqdbm.dylib', `libqdbm.jnilib' and so on are created instead of `libjqdbm.so' and so on.
On HP-UX, you should follow the procedures below for installation.
Run the configuration script.
./configure
Build programs.
make hpux
Perform self-diagnostic test.
make check-hpux
Install programs. As well, perform `make uninstall-hpux' to uninstall them.
make install-hpux
On HP-UX, `libjqdbm.sl' is created instead of `libjqdbm.so' and so on.
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'. As well, this setting is not wanted on Windows, and Mac OS X uses the environment variable `DYLD_LIBRARY_PATH', and HP-UX uses the environment variable `SHLIB_PATH'.
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib export LD_LIBRARY_PATH
The following example stores and retrieves a phone number, using the name as the key.
import qdbm.*; public class Sample { static final String NAME = "mikio"; static final String NUMBER = "000-1234-5678"; static final 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 final String NAME = "mikio"; static final String NUMBER = "000-1234-5678"; static final 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.store(NAME.getBytes(), NUMBER.getBytes(), true); // retrieve the record byte[] res = dbm.fetch(NAME.getBytes()); System.out.println("Name: " + NAME); System.out.println("Number: " + new String(res)); } catch(DBMException e){ e.printStackTrace(); } finally { // close the database if(dbm != null){ try { dbm.close(); } catch(DBMException e){ e.printStackTrace(); } } } } }
The following example performs forward matching search for strings, using the class `Villa'.
import qdbm.*; public class Sample { static final String DBNAME = "words"; static final String PREFIX = "apple"; public static void main(String[] args){ Villa villa = null; try { // open the database villa = new Villa(DBNAME, Villa.OWRITER | Villa.OCREAT, Villa.CMPOBJ); // store records villa.putobj("applet", "little application", Villa.DDUP); villa.putobj("aurora", "polar wonderwork", Villa.DDUP); villa.putobj("apple", "delicious fruit", Villa.DDUP); villa.putobj("amigo", "good friend", Villa.DDUP); villa.putobj("apple", "big city", Villa.DDUP); try { // set the cursor at the top of candidates villa.curjumpobj(PREFIX, Villa.JFORWARD); // scan with the cursor for(;;){ String key = (String)villa.curkeyobj(); if(!key.startsWith(PREFIX)) break; String val = (String)villa.curvalobj(); System.out.println(key + ": " + val); villa.curnext(); } } catch(VillaException e){ if(e.ecode != Villa.ENOITEM) throw e; } } catch(VillaException e){ e.printStackTrace(); } finally { // close the database if(villa != null){ try { villa.close(); } catch(VillaException 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
QDBM has 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 methodology to store a serialized object is useful, object serialization is inefficient in time and space. So, if there is a method to get the byte array from an object, you should store the byte arrays. Besides, comparing keys in hash database is performed to serialized data even if they were objects. That is, if two objects are not according completely in serialized condition, even if the value of `equals' is true, they are not qualified as corresponding keys. This problem is not for B+ tree database, because the comparing function can be assigned appropriately.