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:
- gdbm_open
gdbm_handle
closegdbm_handle
storegdbm_handle
fetchgdbm_handle
existsgdbm_handle
deletegdbm_handle
firstkey andgdbm_handle
nextkeygdbm_handle
reorganizegdbm_handle
sync
Furthermore there are some useful additional commands:
gdbm_handle
countgdbm_handle
maxkeygdbm_handle
attach_arraygdbm_handle
detach_arraygdbm_handle
keys
gdbm_open
Syntax: | gdbm_open [option] file |
Options: | -reader (default)
|
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 With In case of a fatal-error a Tcl-callback-function may be specified with The fatal-error-function proc my_callback_fct {error_message} { ... } Example:
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
returns my_array. When the name of the given (global) array is already attached to a gdbm-file an error is thrown. If An array could be attached after opening a file with:
Warning: Due to the problem that one cannot determine if a variable is global or local to a current procedure (you can use 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)
|
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 |
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 |
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).
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