
TITLE INFORMATION: the slgdbm module 

This S-Lang module provides access to gdbm databases.
The current version is 1.7.

1: features

o when the GDBM_Type handle goes out of scope, the database is
automatically closed
o it's also possible to explicitly close a database
o gdbm_get_keys() returns all keys in the database as an array
o gdbm_get_values() returns an array of all values
o gdbm_get_keys_and values() returns both arrays. This is more efficient 
than first calling gdbm_get_keys() and then gdbm_get_values(). Also, in dbm's
that allow concurrent write access, another process might delete or insert
records inbetween gdbm_get_keys() and gdbm_get_values().
o assoc-like syntax

To implement this I started by stealing from the pcre module, then I went
on to steal from slstdio.c, then from slassoc.c.

2: limitations

o only strings are allowed as keys and values.
o keys and values are stored as strings, not including the trailing \0.
This is compatible with python and perl, but not with slgdbm 1.2, and maybe
other programs (probably the db files in the Netscape cache directory, but
since these are in Berkeley DB format I can't access those anyway). In fact
when I try to read from a slgdbm 1.2 file, I get an "invalid attempt to free
string." Maybe I should use bstrings. That would also allow me to use pack()
to store other datatypes.
o When I open a gdbm file for writing twice, it works. When I free or close
the first file, the second one stays open. However the file is not locked
anymore. This seems to be to do with the fact that gdbm uses fcntl()-style
locking on Debian.

The Debian changelog says:
Use fcntl locking (POSIX) instead of lockf (BSD). Noted by Neal Becker 
  <neal@ctd.comsat.com>. This is just to be on the safe side. I don't 
  think it makes any difference - flock(2) states "Under Linux, flock is
  implemented as a call to fcntl".

That may have been true in 1996, but not since 1997. See 
/usr/src/linux/Documentation/locks.txt.

Info:(libc)File Locks says this:
Locks are associated with processes.  A process can only have one
kind of lock set for each byte of a given file.  When any file
descriptor for that file is closed by the process, all of the locks
that process holds on that file are released, even if the locks were
made using other descriptors that remain open.

 ....

 - Macro: int F_SETLK 

     This macro is used as the COMMAND argument to `fcntl', to specify
     that it should set or clear a lock.  This command requires a third
     argument of type `struct flock *' to be passed to `fcntl', so that
     the form of the call is:

          fcntl (FILEDES, F_SETLK, LOCKP)

     If the process already has a lock on any part of the region, the
     old lock on that part is replaced with the new lock.

3: assoc syntax

You can access a dbf with an assoc-like syntax. This is similar to the anydbm
interface of python and perl's tie() interface. You can write
val = key[dbf];
as an alternative to
val = gdbm_fetch(dbf, key);
as well as
dbf[key]=val;
as shorthand for
() = gdbm_store(dbf, key, val, GDBM_REPLACE);
In this last case, gdbm_store() returns a value but dbf[key]=val;
does not. I don't know if a syntax like ret = (dbf[key]=val); is
possible, but such a syntax would be confusing to C programmers anyway.
Also, the chosen syntax has the advantage that it is possible to some extent
to write code that works on an object without knowing if the object is an
assoc or a dbf. 

3.1: foreach

You can also iterate over the database entries using the syntax
foreach (dbf) using ("keys", "values") However, this uses gdbm's
sequential access method. If you do this

 foreach(dbf) using ("keys")
   {
      key = ();
      if ( some condition )
        gdbm_delete ( dbf, key );
   }

the hash will be rearranged and some entries may be skipped by the loop.
See also info:(gdbm)Sequential. Changing values of entries in a foreach loop
is OK, I think.

4: applications

A recent files mode for JED using slgdbm is available from the 
Jed Modes Repository. You need the
beta version of JED 0.99-17 to load modules. This mode also remembers line
and column information much like Klaus Seistrup's jedstate program was
supposed to do.

5: copyright

Slgdbm is Copyright (c) 2004, 2005 Paul Boekholt.
Released under the terms of the GNU GPL (version 2 or later).
