# Specifications of QDBM for Perl

Copyright (C) 2000-2006 Mikio Hirabayashi
Last Update: Thu, 26 Oct 2006 15:00:20 +0900
[API] [Japanese]

## Table of Contents

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

## Overview

QDBM provides API for Perl. This encapsulates the basic API, the extended API and the advanced API of QDBM. These APIs are implemented with the APIs for C called with XS language. There are two kinds of interfaces to handle a database: using methods directly and using tying functions with a hash.

In case of using methods, you call the constructor `new' of the class `Depot', `Curia' or `Villa' to open a database file or directory and get the handle. The method `close' is used in order to close the database. If the instance is destroyed without closing the database explicitly, the destructor closes the database. 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 APIs for C are available.

In case of using tying functions, you call the `tie' function whose parameters are the same as ones of the constructor. After tying, operations with the tied hash perform as operations to the binded database. You use the `untie' function to close the database.

Although keys and values of storing records are treated as strings, binary data can be stored as they are. `Depot' realizes a hash database with a file. `Curia' realizes a hash database with a directory and multiple files. `Villa' realizes a B+ tree database with a file. `Depot' is fastest. `Curia' is most scalable. `Villa' provides cursor supporting ordering access.

For more information about the APIs, read documents in the sub directory `plapidoc'.

## Installation

Make sure that Perl 5.6.0 or later version is installed and make sure that QDBM is installed under `/usr/local'.

Change the current working directory to the sub directory named `perl'.

    cd perl

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, `Depot.so', `Depot.pm', `Curia.so', `Curia.pm', `Villa.so', `Villa.pm', and so on are installed under an appropriate directory according to the install directory of Perl. Executable commands `pldptest', `plcrtest', and `plvltest' will be installed in `/usr/local/bin'.

To uninstall them, execute the following command after `./configure'. This operation must be carried out by the root user.

    make uninstall

## Examples

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

    use Depot;

    use constant NAME => "mikio";
    use constant NUMBER => "000-1234-5678";
    use constant DBNAME => "book";

    sub main {
        my($depot, $val);

        # open the database
        if(!($depot = new Depot(&DBNAME, Depot::OWRITER | Depot::OCREAT))){
            printf(STDERR "new failed: %s\n", $Depot::errmsg);
            return 1;
        }

        # store the record
        if(!$depot->put(&NAME, &NUMBER)){
            printf(STDERR "put failed: %s\n", $Depot::errmsg);
        }

        # retrieve the record
        if(!($val = $depot->get(&NAME))){
            printf(STDERR "get failed: %s\n", $Depot::errmsg);
        } else {
            printf("Name: %s\n", &NAME);
            printf("Number: %s\n", $val);
        }

        # close the database
        if(!$depot->close()){
            printf(STDERR "close failed: %s\n", $Depot::errmsg);
            return 1;
        }

        return 0;
    }

    exit(main());

The following example is a transcription of the one above, using tying functions.

    use Depot;

    use constant NAME => "mikio";
    use constant NUMBER => "000-1234-5678";
    use constant DBNAME => "book";

    sub main {
        my(%hash, $val);

        # open the database
        if(!tie(%hash, "Depot", &DBNAME, Depot::OWRITER | Depot::OCREAT)){
            printf(STDERR "tie failed: %s\n", $Depot::errmsg);
            return 1;
        }

        # store the record
        if(!($hash{&NAME} = &NUMBER)){
            printf(STDERR "store failed: %s\n", $Depot::errmsg);
        }

        # retrieve the record
        if(!($val = $hash{&NAME})){
            printf(STDERR "fetch failed: %s\n", $Depot::errmsg);
        } else {
            printf("Name: %s\n", &NAME);
            printf("Number: %s\n", $val);
        }

        # close the record
        if(!untie(%hash)){
            printf(STDERR "untie failed: %s\n", $Depot::errmsg);
            return 1;
        }

        return 0;
    }

    exit(main());

The following example performs forward matching search for strings, using the class `Villa'.

    use Villa;

    use constant DBNAME => "words";
    use constant PREFIX => "apple";

    sub main {
        my($villa, $key, $val);

        # open the database
        if(!($villa = new Villa(&DBNAME, Villa::OWRITER | Villa::OCREAT))){
            printf(STDERR "new failed: %s\n", $Villa::errmsg);
            return 1;
        }

        # store the record
        if(!$villa->put("applet", "little application", Villa::DDUP) ||
           !$villa->put("aurora", "polar wonderwork", Villa::DDUP) ||
           !$villa->put("apple", "delicious fruit", Villa::DDUP) ||
           !$villa->put("amigo", "good friend", Villa::DDUP) ||
           !$villa->put("apple", "big city", Villa::DDUP)){
            printf(STDERR "put failed: %s\n", $Villa::errmsg);
        }

        # set the cursor at the top of candidates
        $villa->curjump(&PREFIX);

        # scan with the cursor
        while($key = $villa->curkey()){
            my($prefix) = &PREFIX;
            ($key =~ m/^$prefix/) || last;
            $val = $villa->curval();
            printf("%s: %s\n", $key, $val);
            $villa->curnext();
        }

        # close the database
        if(!$villa->close()){
            printf(STDERR "close failed: %s\n", $Villa::errmsg);
            return 1;
        }

        return 0;
    }

    exit(main());

## Bugs

So far, this API is not associated with AnyDBM_File.

This API can be implemented more effectively by Perl hackers.

For the sake of simplicity of interface, Curia for Perl does not feature handling large objects, and Villa for Perl can not be binded with a comparing function defined by users.