Tgdbm Library for Tcl (Version 0.5)

This is the documentation of the functions provided by the Gdbm-Tcl-Wrapper.

Overview

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.

Furthermore you can use Tgdbm for transparently accessing and storing tcl-
arrays (persistant arrays). An array is attached to the gdbm-file as a handle.
With this you can set an array-entry which is stored or updated transparently
in the corresponding gdbm-file.

Tgdbm 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 Tgdbm is provided as a loadable Tcl-Module, it can be easily
integrated into any Tcl-Application.

For information about downloads, … see the Tgdbm-overview.

Commands

Let’s have a look at a simple walk-through.

  package require tgdbm
  set gdbm_handle [gdbm_open -wrcreat -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.

Now let’s use the persistant array feature:

  package require tgdbm
  gdbm_open -wrcreat -newdb -array my_array second.gdbm
  set my_array(1) one  ;# this will store 1/one in my_array and directly
                       ;# in file "second.gdbm"
  set my_array(2) two
  unset my_array(2)    ;# this will delete key '2' from second.gdbm
  set my_array(1) eins ;# this will update key '1' to 'eins'
  my_array -replace store 2 zwei
  set x $my_array(2)   ;# x == zwei
  unset my_array       ;# this will close the file second.gdbm
                       ;# this could be done with:
                       ;#  my_array close
                       ;#  too, which will also unset the array

The following commands are available which are directly mapped from
aequivalent gdbm-commands:

Furthermore there are some useful additional commands:

gdbm_open

Syntax:gdbm_open [option] file
Options:-reader (default)

-writer

-wrcreat

-newdb

-nolock

-sync

-block_size block_size_number

-mode file-mode

-fatal_func function_name

-array array_name

-full_cache

-no_trailing_null

Gdbm-Command:gdbm_open
Return-Value:Handle (and Tcl-command) to database-file file or list of currently opened handles.
Description:If no option is provided to gdbm_open, it will simply return all currently opened gdbm_handles as a list.

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. This Tcl-callback will be called if something inside Tgdbm crashes.

The fatal-error-function my_callback_fct must be defined as this:

 proc my_callback_fct {error_message} {
     ...
 }

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).

Array-Handling (Version 0.5)

With -array_name an array named array_name is attached to the gdbm-file. When given an array_name this is also the returned gdbm-handle.

gdbm_open -writer -array_name my_array test.gdbm

returns my_array. When the name of the given (global) array is already attached to a gdbm-file an error is thrown.

If -array_name is given the caching-mechanism can be specified with -full_cache, which means that the whole gdbm-file is stored in the given array directly (be careful, should be used with small files anyway). When -full_cache is not specified, the gdbm-file is read as needed.

An array could be attached after opening a file with:

gdbm_handle attach_array (then the name of the array is the same as the handle).

Warning:

Due to the problem that one cannot determine if a variable is global or local to a current procedure (you can use Tcl_FindNamespaceVar but than you cannot compile the tgdbm-library with stubs-enabled, because this function is not in the stub-enabled-library). If you want to use the array attached to a gdbm-file in a procedure you have to make this a global array (else you access a procedure local-array, which is not the same!).

Here is an example:

  gdbm_open -writer -array ini ini.gdbm
  set ini(font) Times
  proc setSize {size} {
    # wrong!!!: set ini(size) $size
    global ini
    set ini(size) $size
  }

End-of-string-Handling (Version 0.5)

-no_trailing_null Usually all strings either stored or returned have the usual C-style-string-ending (null). In some cases you don’t want to store this trailing null or you have gdbm-files which have the keys and values stored without trailing null. In such rare cases you could use argument -no_trailing_null. Tgdbm will not store end-of-string within the gdbm-file.

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 (with error-code GDBM_ILLEGAL_DATA).

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.

sync

Syntax:gdbm_handle sync
Options:none
Gdbm-Command:gdbm_sync
Return-Value:none
Description:Unless you have opened a gdbm-file with option -sync writes are not flushed directly to the disk.
With this function you can force a flush to the disk.

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.

attach_array (extension of gdbm)

Syntax:gdbm_handle attach_array
Options:none
Gdbm-Command:none
Return-Value:none
Description:To attach an array after opening a file you can use this command. The name of the array is the same as the name of the gdbm_handle.

detach_array (extension of gdbm)

Syntax:gdbm_handle detach_array
Options:none
Gdbm-Command:none
Return-Value:none
Description:If you don’t want the transparent storing/retrieving of data through the array you can remove the array from the gdbm_handle with this command.

keys (extension of gdbm)

Syntax:gdbm_handle keys
Options:none
Gdbm-Command:none
Return-Value:List of ALL keys from gdbm-file.
Description:This works like array keys (without the option to add a search-pattern). You should be careful to use this, if your data exceeds the medium-amount of data.

Versions and Errors

Variablename/Syntax:GDBM_VERSION, GDBM_ERRNO, gdbm_strerror error-code
Options:none
Gdbm-Command:gdbm_version, gdbm_errno, dbm_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 -wrcreat 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 Tgdbm-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.

1. Store a bunch of data (which is stored in the array data)

package require tgdbm
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 Bible"}
store_array books.gdbm books

2. List the content of a database-file

See Description of firstkey, nextkey

3. Using the array-commands

Example with array-extension (since version 0.5).

package require tgdbm
gdbm_open -wrcreat -array books books.gdbm
# this one automagically stores the data in books.gdbm
# in the form (ISBN title)
array set books {
    1-567xyz "XML Pocket Reference"
    abc      "The Bible"
}
# now closing the file
unset books
# this could also be done with
# books close

4. gdbm-arrays and namespaces

This example shows how to use “global” gdbm-arrays inside namespaces:

package require tgdbm
namespace eval gdbm::ar {
    variable myArray
}
proc gdbm::ar::init {gdbm_file} {
	variable myArray
	gdbm_open -wrcreat -array myArray $gdbm_file
}
proc gdbm::ar::close {} {
	variable myArray
	myArray close
}
proc gdbm::ar::printData {} {
	variable myArray
    parray myArray
}
proc gdbm::ar::get {key} {
	variable myArray
	return $myArray($key)
}
proc gdbm::ar::fillData {args} {
	variable myArray
	array set myArray $args
}
gdbm::ar::init "airports.gdbm"
gdbm::ar::fillData ADD "Addis Ababa" MUC "Munich" ZAG "Zagreb"
gdbm::ar::printData
gdbm::ar::close

This example can be immediately used for implementing something
similar to ini-files (where configurable user-data like
window-positions or font-selections are stored).

Recent Related Posts

Ein Gedanke an “Tgdbm Library for Tcl (Version 0.5)

  1. I have been getting error that reads
    couldn’t load library “../../lib_tcl/gdbgm0.4/tgdbm.dll”: invalid argument
    while executing “load ../../lib_tcl/gdbgm0.4/tgdbm.dll tgdbm”
    invoked from within
    “package require tgdbm”
    when I run a tcl script. Have not been able to figure out how to get around this problem, using Activetcl 8.4.19
    Please any help is very appreciated

Hinterlasse eine Antwort

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind markiert *

Du kannst folgende HTML-Tags benutzen: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>