<chapter id=chapter.gdbm>
    <title/GDBM Database Interface/
  <p>The <code/gdbm/ module implements an interface to the GNU
GDBM database library and builds some higher level facilities on top
of it.</p>
  <section id=chapter.gdbm.interface>
    <title/Interface/
    <p>The module may be imported as follows:
<code display>import Gdbm at 'x-oz://contrib/gdbm'</code>
The interface provided is similar to dictionaries and allows to store
stateless Oz terms under keys.  A key is an arbitrary virtual
string.
<list>
      <entry/<code/Gdbm.is//
      <synopsis/<code/{Gdbm.is ?+{X} ??{B}}//
      <item>Returns <code/true/ iff ?_{X} is a gdbm object.
      <entry/<code/Gdbm.new//
      <synopsis/<code/{Gdbm.new ?+{R} ??{DB}}//
      <item>This is the convenient way of creating a gdbm
object ?_{DB}. ?_{R} is a record that describes how to open the
database.  The label is the opening method, &EG; <code/read/,
<code/write/, <code/create/, or <code/new/.  The first
argument of the record is the file name.  For example
<code>read('/usr/local/people.db')</code> asks to open the database
located in <file>/usr/local/people.db</file> for reading only.
<code>create('~/data')</code> opens or creates the database
<file/data/ in the user's home directory and opens it both for reading
and writing; <code>new('~/data')</code> is similar, but overwrites it
if it already existed.
	<p>Optional feature <code/mode/ indicates with what
permissions the file should be created (this of course is only
relevant for creating a new database).  The mode may be specified as
an integer, with the usual Unix meaning.  It may also be specified
symbolically, as a record or list of records:
<code display/[owner group(read)]/
This indicates that the owner has all permission rights and that group
members are granted read access.  Others have no rights.  To also
grant write access to group members, you could say:
<code display/[owner group(read write)]/
The default is 0644: owner has read and write access; all others have
read access.
	<p>Optional feature boolean <code/fast/ requests updates
without disk synchronization.  See the GDBM documentation for details.
Default is <code/false/.
      <entry/<code/Gdbm.open//
      <synopsis/<code/{Gdbm.open ?+{FILE} ?+{FLAGS} ?+{MODE} ?+{BLOCK} ??{DB}}//
      <item>This is the more complicated way of opening a gdbm database.
The ?_{FLAGS} specify the opening method. This is an atom or list of
atoms from the set: <code/read/, <code/write/, <code/create/
(equivalently <code/new/ or <code/truncate/).  It may also include the
atom <code/fast/ (see above).  Each symbol may be abbreviated to its
initial letter. ?_{MODE} was described above. ?_{BLOCK} is an integer
for the block size of transfers (see GDBM documentation): use 0 to get
a system dependent appropriate default.
      <entry/<code/Gdbm.get//
      <synopsis/<code/{Gdbm.get ?+{DB} ?+{KEY} ??{VAL}}//
      <item>Retrieves the Oz value ?_{VAL} stored under ?_{KEY}.
The latter may be an arbitrary virtual string.  If there is no such
?_{KEY} in ?_{DB}, an exception is raised.
      <entry/<code/Gdbm.condGet//
      <synopsis/<code/{Gdbm.condGet ?+{DB} ?+{KEY} ?_{DEFAULT} ??{VAL}}//
      <item>Similar to the above, but returns ?_{DEFAULT} if there
is no such ?_{KEY} in ?_{DB}.
      <entry/<code/Gdbm.put//
      <synopsis/<code/{Gdbm.put ?+{DB} ?+{KEY} ?+{VAL}}//
      <item>Stores Oz value ?_{VAL} under ?_{KEY} in
?_{DB}. ?_{VAL} must be ground and stateless.
      <entry/<code/Gdbm.firstkey//
      <entry/<code/Gdbm.firstkeyBS//
      <synopsis/<code/{Gdbm.firstkey ?+{DB} ??{KEY}}//
      <item>Returns a ?_{KEY} in ?_{DB} (see below).  There is
absolutely no guarantee as to which key this is going to be.  Returns
<code/unit/ if the database is empty. <<Gdbm.firstkey>> returns ?_{KEY}
as an atom, <<Gdbm.firstkeyBS>> as a bytestring.
      <entry/<code/Gdbm.nextkey//
      <entry/<code/Gdbm.nextkeyBS//
      <synopsis/<code/{Gdbm.nextkey ?+{DB} ?+{KEY} ??{NEXT}}//
      <item>Returns the ?_{NEXT} key after ?_{KEY}.  Again, there
is no guarantee as to which key this is going to be.  The only
guarantee is that if you continue in this manner, you will enumerate
all the keys in the database, in some order, without repeats.  Returns
<code/unit/ when there are no more keys. <<Gdbm.nextkey>> returns
?_{NEXT} as an atom, <<Gdbm.nextkeyBS>> as a bytestring.
      <entry/<code/Gdbm.close//
      <synopsis/<code/{Gdbm.close ?+{DB}}//
      <item>Closes the database.  Subsequent access attempts
raise an exception.
      <entry/<code/Gdbm.remove//
      <synopsis/<code/{Gdbm.remove ?+{DB} ?+{KEY}}//
      <item>Deletes the entry for ?_{KEY} if it exists.
      <entry/<code/Gdbm.reorganize//
      <synopsis/<code/{Gdbm.reorganize ?+{DB}}//
      <item>see the GDBM documentation.
      <entry/<code/Gdbm.keys//
      <entry/<code/Gdbm.keysBS//
      <synopsis/<code/{Gdbm.key ?+{DB} ??{KEYS}}//
      <item>Returns the lazy list of all ?_{KEYS} in the database.
      <<Gdbm.keys>> returns each key as an atom, <<Gdbm.keysBS>> as
      a bytestring.
      <entry/<code/Gdbm.entries//
      <entry/<code/Gdbm.entriesBS//
      <synopsis/<code/{Gdbm.entries ?+{DB} ??{ENTRIES}}//
      <item>Returns the lazy list of all pairs <code/KEY#VALUE/ in
the database.  <<Gdbm.entries>> returns each key as an atom,
<<Gdbm.entriesBS>> as a bytestring.
      <entry/<code/Gdbm.items//
      <entry/<code/Gdbm.itemsBS//
      <synopsis/<code/{Gdbm.items ?+{DB} ??{ITEMS}}//
      <item>Returns the lazy list of all values stored in the
database. <<Gdbm.items>> returns each key as an atom, <<Gdbm.itemsBS>>
as a bytestring.
      <entry/<code/Gdbm.forAll//
      <entry/<code/Gdbm.forAllBS//
      <synopsis/<code/{Gdbm.forAll ?+{DB} ?+{P}}//
      <item>Calls <code/{P VALUE}/ for every entry in the database.
      <<Gdbm.forAll>> loops over all keys as atoms, <<Gdbm.forAllBS>>
      as bytestrings.
      <entry/<code/Gdbm.forAllInd//
      <entry/<code/Gdbm.forAllIndBS//
      <synopsis/<code/{Gdbm.forAllInd ?+{DB} ?+{P}}//
      <item>Calls <code/{P KEY VALUE}/ for every entry in the
database.  <<Gdbm.forAllInd>> loops over all keys as atoms,
<<Gdbm.forAllIndBS>> as bytestrings.
    </list></p>
  </section>

  <section id=chapter.gdbm.install proglang=sh>
    <title/Installation/
    <p>The GDBM library must be available on your system as a shared
object library.  For Linux systems, this is normally the case.  For
other systems, it may need to be built and installed.  Newer versions of
GDBM (&EG; 1.8.0) will automatically build a shared object library if that
is possible on your system.  Thus you should download the most recent version
of GDBM from <ref.extern
to="ftp://ftp.gnu.org/gnu/gdbm/"><file>ftp://ftp.gnu.org/gnu/gdbm/</file></ref.extern>
and install it on your system.</p>
    <p>If, for some bizarre reason, you must use an older version, the standard
distribution needs to be patched to compile for <em>position independent code</em>
and to create a shared object library.  Thus, for the older version 1.7.3, we
provide a fix for the standard gdbm distribution: its purpose is to automate the
creation of the shared object library. Both the standard gdbm 1.7.3 distribution and
our fix can be downloaded from our ftp server:
<list>
	<item><ref.extern to="http://www.mozart-oz.org/download/mozart-ftp/extras/gdbm-1.7.3.tar.gz">http://www.mozart-oz.org/download/mozart-ftp/extras/gdbm-1.7.3.tar.gz</ref.extern>
	<item><ref.extern to="http://www.mozart-oz.org/download/mozart-ftp/extras/gdbm-1.7.3-fix.tar.gz">http://www.mozart-oz.org/download/mozart-ftp/extras/gdbm-1.7.3-fix.tar.gz</ref.extern>
      </list>
They both unpack into the same directory (namely
<file>gdbm-1.7.3</file>).  You should unpack the standard distribution
first, then our fix since it overwrites certain files.
<code display>
tar zxf gdbm-1.7.3.tar.gz
tar zxf gdbm-1.7.3-fix.tar.gz
cd gdbm-1.7.3
./configure
make
make install
</code>
We also make available the following targets: <code/install.so/,
<code/install.h/, <code/install.man/, <code/install.info/.</p>
    <p>If you install in a non-standard directory, you may have to set
<var env/LD_LIBRARY_PATH/ appropriately so that <file/libgdbm.so/ may
be found.</p>
  </section>

</chapter>
<!--
Local Variables:
mode: sgml
mode: auto-fill
sgml-default-dtd-file: "chapter.ced"
sgml-auto-activate-dtd: t
adaptive-fill-mode: nil
End:
-->
