1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
|
This S-Lang module provides access to gdbm databases.
features
* when the GDBM_Type handle goes out of scope, the database is automatically
closed
* it's also possible to explicitly close a database
* gdbm_get_keys() returns all keys in the database as an array
* gdbm_get_values() returns an array of all values
* 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().
* 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.
limitations
* only strings are allowed as keys and values.
* 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.
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.
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.
applications
A recent files mode for JED using slgdbm is available from the Jed Modes
Repository.
copyright
Slgdbm is Copyright (c) 2004, 2005, 2007 Paul Boekholt. Released under the
terms of the GNU GPL (version 2 or later).
|