Programme müssen ihre Daten nicht immer am SQL-Datenbankserver aufgeben: Für viele Aufgaben sind eingebettete Datenbanken die bessere Wahl. Jean-Claude Wippler hat mit Metakit eine DB-Engine entwickelt, die sehr sparsam mit den Ressourcen umgeht und dennoch einen großen Funktionsumfang bietet.
Viele Programme benötigen eine leistungsfähige Datenbank, um Informationen geordnet abzulegen und zu suchen, etwa Adress- oder Kundenverwaltungen, Literaturlisten und Kataloge. Unter Linux ist der Griff zu einer SQL-Datenbank wie PostgreSQL oder MySQL zumindest finanziell kein Problem, der Aufwand ist jedoch erheblich. Will man das Programm inklusive Datenbank per Internet verbreiten oder soll eine Kataloganwendung von CD laufen, dann kommt eine SQL-Datenbank kaum in Frage.
Datenbank und Anwendung im selben Prozess
Für solche Aufgaben ist die eingebettete Datenbank Metakit von Jean-Claude Wippler eine leistungsfähige Alternative. Sie läuft ohne großen Aufwand innerhalb der Anwendung und verzichtet auf einen extern Server. Metakit wurde bis hin zu IBMs Großrechner S390 auf praktisch jede Architektur portiert, auch das Address Book von Mac OS X nutzt dieses freie Produkt (X/MIT-Lizenz). Tcl-Programmierer betten Metakit per Mk4Tcl in ihre Programme ein.
Die Quellen sind von[1] zu beziehen, zur Zeit ist Version 2.4.9.2 aktuell. Das nächste Feder-Lesen wird das Konzept der Starkits vorstellen – das verspricht das Ende des Kompilierens. Bis es soweit ist, muss der Programmierer noch etwas Handarbeit investieren. Das Auspacken, Konfigurieren und Übersetzen ist aber in wenigen Schritten erledigt:
tar -xzvf metakit-2.4.9.2.tar.gz cd metakit-2.4.9.2/builds/ ../unix/configure --enable-shared --with-tcl=/usr/local/include make install
Danach lässt sich die Tcl-Erweiterung mit »package require Mk4tcl« in den Interpreter laden. Sie enthält neun Kommandos im Namespace »mk«, um Datenbanken und deren Inhalt zu bearbeiten. Die wichtigsten Kommandos sind in Tabelle 1 zusammengefasst.
Gut strukturiert
Die meisten CD-Abspielprogramme greifen inzwischen auf die Daten von Freedb.org oder Gracenote zurück, um Informationen über Künstler und Titel einer CD anzuzeigen. Manchmal wäre es aber praktisch, in dieser Diskographie suchen zu können, ohne online zu sein. Freedb.org stellt die Datensätze zum Download bereit, sie bestehen aus einer Textdatei pro CD. Nachdem die Daten in einer Metakit-Datenbank gelandet sind, fehlt nur noch ein kleines GUI mit Suchfunktion. Das Auslesen der Textdateien ist hier nicht weiter interessant, die Quellen liegen auf dem FTP-Server des Linux-Magazins bereit[2].
Während bei den großen Datenbanken (auch bei der Berkeley DB[3]) mehrere Dateien zu einer Datenbank gehören, legt Metakit alles in einem File ab. Das Metakit-Kommando »mk::file open Tagname Dateiname« öffnet eine Datenbank aus einer Datei und versieht sie mit einem Tag. Tags identifizieren die Datenbanken, sie sind bei den weiteren Kommandos nötig.
Das Äquivalent zu Tabellen sind in Metakit so genannte Views. Views bilden zusammen mit dem Tag (durch einen Punkt verbunden) einen eindeutigen Pfad. Eine neue View entsteht mit dem Kommando »mk::view layout Tagname.View Definition«. Die Definition ist eine Liste der Spaltennamen. Normalerweise sind alle Spalten vom Typ String, durch das Anhängen eines Typkennzeichens lassen sich andere Datentypen erzeugen:
- »:I« Integer
- »:L« Long
- »:F« Float
- »:B« Binary
In Listing 1 legen die Zeilen 7 und 8 zwei Views an. Die erste enthält die CD-Daten, die zweite dient für die Trackdaten. Die »NR«-Spalte der »tracks«-Views ist ein Integer, die anderen Spalten sind Strings. Neben einfachen Tabellen kennt Metakit auch Untertabellen. Die beiden Tabellen könnte man durch eine einzige mit einer Untertabelle für die Tracks ersetzen:
mk::view layout db.cds
{DISCID ARTIST ALBUM {TRACKS {NR:I LABEL}}
Die in einer Datenbank enthaltenen Views lassen sich mit »mk::file views« jederzeit abfragen. Sind alle Views angelegt, können sie Daten aufnehmen. Ein einzelner Datensatz nennt sich Row, er entspricht einer Zeile in einer View.
Bequem beladen
Das Auslesen der Daten von Freedb.org ist im Beispiel nicht enthalten, der vollständige Quellcode zu diesem Feder-Lesen ist aber auf unserem FTP-Server zu finden[2]. Das Beispiel in Listing 1 erzeugt nur die Daten für eine CD, hierzu dient das »mk::row append«-Kommando in den Zeilen 11 bis 18. Die Daten sind dabei als Paare der Form » Spaltenname Wert« anzugeben.
Wie immer bei Datenbanken stellt sich auch für Metakit die Konsistenzfrage. Normalerweise arbeitet Metakit im Autocommit-Modus und speichert alle Änderungen sofort in der Datenbank. Gibt der Programmierer bei »mk::file open« jedoch die Option »-nocommit« an, dann muss er alle Änderungen mit »mk::file commit« bestätigen oder mit »mk::file rollback« den letzten gespeichert Zustand wiederherstellen. Anders als SQL-Datenbanken belohnt Metakit die »-nocommit«-Option allerdings nicht mit zusätzlicher Performance.
Die Anzahl der Einträge in einer Tabelle (einer View) ermittelt das Kommando »mk::view size View« (siehe Zeile 21). Die Ausgaben des Beispielprogramms sind im Abbildung 1 zu sehen.

Abbildung 1: Das Beispielprogramm, hier von einer Tkcon aus aufgerufen. Die ersten beiden Ausgaben (blau) stammen von den Programmzeilen 20 und 21 aus Listing 1. Die Tracks-View enthält demnach sechs Zeilen.
Beispielskript
01 package require Mk4tcl
02
03 # Datenbank öffnen
04 mk::file open cddb cddb.db
05
06 # Zwei Views anlegen
07 mk::view layout cddb.cds "DISCID ARTIST ALBUM"
08 mk::view layout cddb.tracks "DISCID NR:I LABEL"
09
10 # Daten einfügen
11 mk::row append cddb.cds DISCID eb101210
12 ARTIST "Maria Graf" ALBUM "Harp Recital"
13 mk::row append cddb.tracks DISCID eb101210
14 NR 1
15 LABEL "Louis Spohr: Fantasie for Harp, Op. 35 in C minor"
16 mk::row append cddb.tracks DISCID eb101210
17 NR 2
18 LABEL "Johann Christian Boch: Sonata Op. 5 No. 3 in G major 1."
19
20 puts "nnBeispiel 1"
21 puts "Größe [mk::view size cddb.tracks]"
22
23 # Eine Reihe ausgeben
24 puts "Zeile cddb.tracks!0 "[mk::get cddb.tracks!0]""
25
26 # ... mit Cursor
27 mk::cursor create tcrs cddb.tracks 0
28 puts "Position [mk::cursor position tcrs]"
29 mk::cursor incr tcrs
30 puts "Position [mk::cursor position tcrs]"
31 puts "Zeile cursor "[mk::get $tcrs]""
32
33 # Daten aus Views in ein Tcl-Array kopieren
34 set result [lindex [mk::select cddb.cds -keyword ARTIST "graf"] 0]
35 array set cd [mk::get cddb.cds!$result]
36 parray cd
37
38 # Foreach-Multiset
39 foreach row [mk::select cddb.tracks -exact DISCID $cd(DISCID)] {
40 foreach {name wert} [mk::get cddb.tracks!$row] {
41 set $name $wert
42 }
43 puts "Track $NR: $LABEL"
44 }
45
46 # Daten ändern
47 set result [lindex [mk::select cddb.tracks -exact DISCID $cd(DISCID) NR 2] 0]
48 mk::set cddb.tracks!$result LABEL "Johann Christian Bach: Sonata Op. 5 No. 3 in G major 1."
49 puts [mk::get cddb.tracks!$result ]
50
51 # Schema implizit ändern
52 mk::set cddb.cds!0 VORHANDEN:I 1
Leichtes Abfragen
Nachdem die Datenbank gefüllt ist, kann es an das Abfragen gehen. Metakit speichert alle Daten in Zeilen, die im Format » Tagname.View!Zeile« adressiert werden. Damit lässt sich eine komplette Zeile abfragen: »mk::get Tagname.View!Zeile« gibt die Daten paarweise als Spaltenname und Wert aus (Zeile 24). Sie lassen sich daher per »array set« in ein Tcl-Array umwandeln (ab Zeile 34) und von dort gegebenenfalls per »array get« wieder abfragen und in die Datenbank speichern.
Ein anderer Trick kommt in Zeile 40 zum Einsatz: eine »foreach«-Schleife mit mehreren Variablennamen (Foreach-Multiset). Normalerweise wird »foreach« nur mit einer Variablen verwendet, die bei jedem Schleifendurchlauf einen weiteren Wert aus der Liste erhält. Das gilt auch für mehrere Variablen: Diese erhalten auch jeweils den nächsten Wert aus der Liste, im Beispiel den Variablennamen aus der Datenbank und den dort abgelegten Wert. Das »set«-Kommando im Schleifenkörper weist dann dem Variablennamen den Wert zu, der ab nun in der Variablen zur Verfügung steht. Dieser Trick kann viele »lindex«-Aufrufe sparen, wenn ein Programm Daten aus Listen extrahieren soll.
Zum Erzeugen und Bearbeiten der Zeilenadresse steht das »mk::cursor«-Kommando zur Verfügung. Im Beispiel erzeugt Zeile 27 einen Cursor für die Tracks, Zeile 29 verschiebt ihn und Zeile 31 gibt die Daten aus, die sich an der neuen Position befinden.
Einer der großen Vorteile von Datenbanken gegenüber einfachen Dateien sind ihre Suchfunktionen. Metakit hat hierfür das »mk::select«-Kommando zu bieten. Anders als bei SQL-Datenbanken ist dies zwar keine ausgefeilte Abfragesprache mit Subselects und Verknüpfungen über mehrere Tabellen, es ist dennoch für die meisten Aufgaben ausreichend. Das »mk::select«-Kommando erwartet neben der View eine Liste mit Spaltennamen und Werten, die sich in den gesuchten Zeilen befinden sollen.
Datensätze suchen, finden und verändern
Der Default-Suchmodus ist Case-insensitive, Groß- und Kleinschreibung spielen also keine Rolle. Es stehen aber eine Reihe weiterer Suchmodi zur Verfügung (Tabelle 2). Bei der Namenssuche ist die Option »-keyword« besonders praktisch, hier muss der Suchwert (zum Beispiel der Nachname) nur im Namen enthalten sein, damit Metakit den Eintrag findet. Beim GUI für die CDDB-Datenbank (Abbildung 2) kann der Anwender die Suchoption per Menü ändern.
![Abbildung 2: Mit Metakit lässt sich sehr schnell eine Oberfläche zur Offline- Suche in der CDDB (CD-Datenbank von Freedb.org) programmieren. Das vollständige Listing dazu liegt auf dem Linux-Magazin-FTP-Server [2].](https://www.linux-magazin.de/wp-content/uploads/2007/01/cddbgui_jpg-300x210.jpg)
Abbildung 2: Mit Metakit lässt sich sehr schnell eine Oberfläche zur Offline- Suche in der CDDB (CD-Datenbank von Freedb.org) programmieren. Das vollständige Listing dazu liegt auf dem Linux-Magazin-FTP-Server [2].
Änderungen kommen in den besten Datenbanken vor. Im zweiten Track (Zeile 18) zum Beispiel hat sich ein Tippfehler eingeschlichen, den es zu korrigieren gilt. Hierzu dient das »mk::set«-Kommando in Zeile 48, das einen einzelnen Eintrag (nur den »LABEL«-Wert) in der Datenbank überschreibt.
Neben dem einfachen Ändern bestehender Zeilen kann der Programmierer bei Metakit sogar die Datenbankstruktur dynamisch ergänzen. Um aus der einfachen Anzeige der CDDB-Daten ein Programm zu entwickeln, das die eigene CD-Sammlung verwaltet, fehlen (je nach Ordnungsliebe) einige Spalten. Eine könnte aussagen, ob man diese CD hat oder gar, welche Nummer sie in der eigenen Sammlung trägt. Eine weitere Spalte würde das gescannte Cover aufnehmen.
Für diese Ergänzungen ist keine Änderung des Schemas notwendig, es reicht aus, diesen Wert per »mk::set« einzufügen (siehe Zeile 52 im Beispielprogramm). Dieses Kommando ergänzt implizit die neue Spalte bei allen vorhandenen Einträgen. Die Kehrseite ist, dass Fehler bei der Eingabe eventuell zu keiner Fehlermeldung führen, sondern zu einer geänderten View.
Wer sich näher mit Metakit beschäftigen will, dem sei neben der Dokumentation auf der Homepage auch Mark Rosemans Einleitung[4] sowie das Tcl\’ers Wiki[5] empfohlen. Wie immer in der Welt der freien Software gibt es zu Metakit natürlich Alternativen. Bei den eingebetteten Datenbanken ist das vor allem die Berkeley DB[3], die sich unter anderem im Slapd-LDAP-Server oder in Evolution findet. Allerdings können je nach Konfiguration mehrere Dateien für eine Berkeley DB notwendig sein, was das Verbreiten der Datenbank erschwert.
Das fertige Skript für die CDDB-Oberfläche wird vermutlich aus mehreren Teilen bestehen: einer Reihe von kleinen Skripten, einer oder mehreren kompilierten (also plattformabhängigen) Erweiterungen und vielleicht noch Bitmaps für Icons. Die Anwendung läuft damit zwar prima auf dem eigenen Rechner, zum Ausliefern (neudeutsch Deployment) ist das jedoch wenig kundenfreundlich.
Lieferbar
Bisher gab es die Möglichkeit, mit Prowrap[6] von Active State oder dem freien Pendant Freewrap[7] von Dennis LaBelle eine ausführbare Datei zu erstellen, die alle Bestandteile eines Programms enthält. Jean-Claude Wippler hat sich auch dieses Themas angenommen, seine Starkit-Lösung[8] ist – neben virtuellen Dateisystemen – Thema im nächsten Feder-Lesen. (fjl)

Abbildung 3: Ram Debugger ist ein grafischer Debugger für Tcl-Programme, der gleichzeitig als Editor und IDE dienen kann. Praktisch: Per GDB-Backend entwanzt er auch C- und C++-Programme.
|
Größe |
|---|
|
Das Laden der Mk4Tcl-Erweiterung kostet etwa ein halbes MByte, dazu kommen noch die Daten. Aus 5860 KByte Textdateien mit dem CDDB-Inhalt erzeugt das Beispiel[2] eine Datenbank der Größe 2536 KByte. Diese Datenbank enthält etwa 1400 CDs mit 20000 Tracks, die Suche nach einem Musiker oder Titel kostet im Mittel fünf Millisekunden (gemessen auf einem Athlon 800). Das Abfragen aller Daten zu einem Suchwort ist in zehn Millisekunden erledigt, der residente Speicher wächst dabei gegenüber der leeren »tclsh« nur um 1 MByte. Das sind Werte, mit denen sich wirklich leben lässt. |
|
Das |
|---|
|
Dank diverser korrigierter Fehler ist Tcl/Tk inzwischen bei Version 8.4.2 angekommen, unter anderem unterstützt diese Version serielle Ports besser[9]. Version 8.4.3 mit weiteren Bugfixes beim Threading steht vor der Tür. Auch die Tcllib liegt in einer neuen Version vor, hinzugekommen sind unter anderem DES-Verschlüsselung und DNS- und NTP-Abfragen (Network Time Protocol). In OSNews[10] steht ein Interview mit vier Entwicklern des Tcl-Core-Teams: Jeffrey Hobbs, Andreas Kupries, Donal K. Fellows und Mark Harrison. Nach einer Schaffenspause ist Groupkit, eine Groupware-Lösung von Mark Roseman und Chad Thatcher zu Sourceforge umgezogen[11]. Mit Groupkit können sich mehrere Benutzer zu einer Konferenz zusammenfinden, bei der sie Editoren oder Whiteboards teilen. Zur Entspannung ist auch Tic Tac Toe dabei. Steve Ball hat Tcl XML, Tcl DOM und Tcl XSLT[12] in Version 2.6 herausgebracht. Wie die Namen schon sagen, umfassen die Pakete eine Reihe von Erweiterungen, um XML-Dokumente zu bearbeiten und zu erstellen. Die Erweiterungen verwenden Libxml2 und Libxslt aus dem Gnome-Projekt. Debugger für Tcl, C und C++ Hin und wieder brauchen Tcl-Entwickler – trotz Tkcon – einen Debugger. Ramon Ribó hat deshalb seinen Ram Debugger[13] vorgestellt (Abbildung 3). Mit ihm lassen sich Tcl-, C- und C++-Programme untersuchen. Das Projekt ist eine willkommen Erweiterung des Werkzeugkastens, da die Entwicklung bei den anderen freien Tcl-Debuggern etwas eingeschlafen zu sein scheint. Am 30. und 31. Mai fand in Nürnberg die vierte Europäische Tcl/Tk-Konferenz statt, weitere Informationen sind unter[14] zu finden. Ein eher virtuelles Treffen soll bei der deutschen Tcl/Tk-Community stattfinden[15]. Ob die Sprachhürden beim Tcl\’ers Wiki[16] so groß sind, dass sich ein weiteres Portal (und dann noch in PHP) lohnt, wird sich zeigen. Passend zu diesem Feder-Lesen präsentiert Martin Lemburg im Wiki einen kleinen Viewer für MP3-Tags[17]. Dort findet sich auch eine handliche Sammlung von Algorithmen[18], angefangen von nützlichen Einzeilern bis zu längeren Prozeduren. |
|
Infos |
|---|
|
[1] Metakit: [http://www.equi4.com/metakit/] [2] Quellen: [ftp://ftp.linux-magazin.de/pub/listings/magazin/2003/07/Feder-Lesen] [3] Berkeley DB: [http://www.sleepycat.com/] [4] Metakit-Tutorial: [http://www.markroseman.com/tcl/] [5] Wiki: [http://mini.net/tcl/2?metakit] [6] Prowrap: [http://www.activestate.com/Products/Tcl_Dev_Kit/] [7] Freewrap: [http://freewrap.sourceforge.net/] [8] Starkit: [http://www.equi4.com/starkit/] [9] Tcl 8.4.2: [http://www.tcl.tk/software/tcltk/8.4.html] [10] Interview: [http://www.osnews.com/story.php?news_id=3003] [11] Groupkit: [http://www.groupkit.org] [12] Tcl XML: [http://tclxml.sourceforge.net/] [13] Ram Debugger: [http://gid.cimne.com/RamDebugger] [14] Europäische Tcl/Tk-Konferenz: [http://www.t-ide.com/tcl2003e.html] [15] Deutsche Tcl/Tk-Community: [http://www.self-tcl.de] [16] Tcl\’ers Wiki: [http://mini.net/tcl/] [17] MP3-Viewer: [http://mini.net/tcl/8698] [18] Algorithmen in Tcl: [http://mini.net/tcl/526] |
|
Der |
|---|
|
Carsten Zerbst arbeitet bei Atlantec an einem PDM-System für den Schiffbau. Daneben beschäftigt er sich mit dem Einsatz von Tcl/Tk. |







