Tclgdbm Library for Tcl

Introduction | Commands | Examples

Introduction

Tclgdbm provides an easy to understand interface to the GNU-dbm-library (gdbm).
Gdbm uses extendible hashing and stores key/value pairs, where each key must be unique.
Though gdbm provides compatibility for ndbm and dbm only the gdbm-commands are supported in Tclgdbm.

When opening a gdbm-database-file a handle for this database is provided for accessing the file. This handle is used to call the gdbm-commands (see the man-pages from gdbm).

Tclgdbm is meant to be used in Tcl-Applications which has to store some small/medium amount of data. In many cases there is not enough data to be stored, so that a "real" database is justified.
But though there is only a small amount of data, you often have to use an efficient way to store them (not just write them in a plain text-file).

Because Tclgdbm is provided as a loadable Tcl-Module, it can be easily integrated into a Tcl-Application.

To have a more highlevel (sql-like) access to data stored in a gdbm-database-file you should have a look at Qgdbm.

Commands

Let's have a look at a simple walk-through.
  package require gdbm

  set gdbm_handle [gdbm_open -writer -newdb first.gdbm]

  $gdbm_handle -insert store key1 {Some value to be stored.}

  set value [$gdbm_handle fetch key1]
  puts "value: $value"

  $gdbm_handle close
That's nearly all there is. When opening/creating a gdbm-database-file a handle is returned, which is used as a Tcl-command for accessin this database-file. When calling this command you provide the "usual" gdbm-commands (like gdbm_store, ...) but without the gdbm-prefix as a parameter.

The following commands are available (for a detailed discussion of these commands you should also look-up the gdbm-man-pages):

gdbm_open

Syntax: gdbm_open [option] file
Options: -writer -reader -wrcreat -newdb -nolock -sync -block_size block_size_number -mode file-mode -fatal_func function_name
Gdbm-Command: gdbm_open
Return-Value: Handle to database-file file
Description: The specified file is opened either for reading or writing. Gdbm sets a lock on this file so there is only one writer. With -wrcreat the file is created if it is not existent. -newdb creates file regardless if one exists.
With -mode the file mode may be specified.
In case of a fatal-error a Tcl-callback-function may be specified with -fatal_func

Example:
gdbm_open -writer -newdb -nolock -fatal_func my_callback_fct help.gdbm
Opens/creates a new gdbm-database-file help.gdbm and doesn't lock the file even though it will write to this file (should really be used with care).
The fatal-error-function my_callback_fct must be defined as this:
proc my_callback_fct {error_message} {
  ...
}

close

Syntax: gdbm_handle close
Options: none
Gdbm-Command: gdbm_close
Return-Value: none
Description: Close the database-file which is associated with gdbm_handle. Where gdbm_handle is retrieved with a call to gdbm_open

store

Syntax: gdbm_handle [option] store key value
Options: -insert -replace
Gdbm-Command: gdbm_store
Return-Value: none
Description: The given value is stored in the database-file with the given key. If -insert is specified and the provided key is already stored in the database an error is thrown.

fetch

Syntax: gdbm_handle [option] fetch key
Options: none
Gdbm-Command: gdbm_fetch
Return-Value: The value associated with key in the database.
Description: Fetch the key/value-pair from the database

exists

Syntax: gdbm_handle exists key
Options: none
Gdbm-Command: gdbm_exists
Return-Value: 0 or 1
Description: If the key does exists, 1 is returned. Otherwise 0.

delete

Syntax: gdbm_handle delete key
Options: none
Gdbm-Command: gdbm_delete
Return-Value: none
Description: Delete the given key from databasefile. If the key does not exist an error is thrown.

firstkey, nextkey

Syntax: gdbm_handle firstkey
gdbm_handle firstkey key
Options: none
Gdbm-Command: gdbm_firstkey, gdbm_nextkey
Return-Value: key
Description: These commands are used for iterating through the database-file. You can use it like this:
set gdbm [gdbm_open -reader file.gdbm]
if {[set key [$gdbm firstkey]] != "") {
  puts "key: '$key' value: '[$gdbm fetch $key]'"
  while {[set key [$gdbm nextkey $key]] != ""} {
    puts "key: '$key' value: '[$gdbm fetch $key]'"
  }
}
$gdbm close

reorganize

Syntax: gdbm_handle reorganize
Options: none
Gdbm-Command: gdbm_reorganize
Return-Value: none
Description: When you have done many deletes on a database-file, the space is not freed until you call reorganize.

count (extension of gdbm)

Syntax: gdbm_handle count
Options: none
Gdbm-Command: none
Return-Value: Number of total rows in gdbm-file
Description: This is aequivalent to a "select count(*) from table" in a relational database.

maxkey (extension of gdbm)

Syntax: gdbm_handle maxkey
Options: none
Gdbm-Command: none
Return-Value: Number of the maximum primary-key
Description: Should be used only when the primary-key consists of integer-numbers (as always when you use an ID as the primary key). In most cases you want to insert a new element and give this element a unique ID. Use [expr [gdbm_handle maxkey] + 1] for this purpose.
You could also simulate sequences that way.

Versions and Errors

Variablename/Syntax: GDBM_VERSION
GDBM_ERRNO
gdbm_strerror error-code
Options: none
Gdbm-Command: gdbm_version
gdbm_errno
gdbm_strerror
Return-Value: gdbm_version returns a version-string
gdbm_strerror gives an error-description to an error-number
Description: You can access the version-string provided in the variable GDBM_VERSION. In case of an error the variable GDBM_ERRNO is filled with the corresponding gdbm-error-number (see gdbm.h for detailer error-numbers). With
gdbm_strerror $GDBM_ERRNO
an error-description could be retrieved. In case of most errors the error-description is thrown with the error-command.
 
Variablename: gdbm_error
Description: To provide a way to access the error-code-defines in gdbm (e.g.: GDBM_FILE_OPEN_ERROR, ..) the array gdbm_error is provided. With these you can check GDBM_ERRNO for specific error-codes without using the integer-values of the gdbm-error-code-defines.
The following "defines" (that is array-entries) exists:
gdbm_error(GDBM_NO_ERROR)
gdbm_error(GDBM_MALLOC_ERROR)
gdbm_error(GDBM_BLOCK_SIZE_ERROR)
gdbm_error(GDBM_FILE_OPEN_ERROR)
gdbm_error(GDBM_FILE_WRITE_ERROR)
gdbm_error(GDBM_FILE_SEEK_ERROR)
gdbm_error(GDBM_FILE_READ_ERROR)
gdbm_error(GDBM_BAD_MAGIC_NUMBER)
gdbm_error(GDBM_EMPTY_DATABASE)
gdbm_error(GDBM_CANT_BE_READER)
gdbm_error(GDBM_CANT_BE_WRITER)
gdbm_error(GDBM_READER_CANT_DELETE)
gdbm_error(GDBM_READER_CANT_STORE)
gdbm_error(GDBM_READER_CANT_REORGANIZE)
gdbm_error(GDBM_UNKNOWN_UPDATE)
gdbm_error(GDBM_ITEM_NOT_FOUND)
gdbm_error(GDBM_REORGANIZE_FAILED)
gdbm_error(GDBM_CANNOT_REPLACE)
gdbm_error(GDBM_ILLEGAL_DATA)
gdbm_error(GDBM_OPT_ALREADY_SET)
gdbm_error(GDBM_OPT_ILLEGAL)

Example:
set gdbm [gdbm_open -writer file.gdbm]
if {[catch {$gdbm fetch store key1} result]} {
    if {$GDBM_ERRNO == $gdbm_error(GDBM_ITEM_NOT_FOUND)} {
        puts stderr "Item not found."
    }
}

Examples

Even though the Tclgdbm-commands should be easy enough (if you know the gdbm-library) a few examples should help to start immediately.

Pay attention to the reduced error-handling.

Example #1: Store a bunch of data (which is stored in the array data)

package require gdbm

proc store_array {file data} {
  upvar $data dat
  # create file if it doesn't exist
  set gdbm [gdbm_open -wrcreat $file]

  foreach entry [array names dat] {
    $gdbm -replace store $entry $dat($entry)
  }
  $gdbm close
}

# ISBN - Booktitles
array set books {1-567xyz "XML Pocket Reference" abc "The Bibel"}
store_array books.gdbm books

Example #2: List the content of a database-file

See Description of firstkey, nextkey
Last change: 24. Feb 2000 21:00 (MET)

For Suggestions, improvements, bugs or bug-fixes please contact:

Stefan Vogel (stefan.vogel@avinci.de)