Lisp-Database-Package
Das Lisp-Database-Package ist eine in Java geschriebene Erweiterung zum Lisp-Package. Es stellt mehrere Funktionen zur Verfügung, mit denen auf eine relationale Datenbank zugegriffen werden kann. Das Package ist als Open Source veröffentlicht.
Im Folgenden werden die Funktionen des Packages erläutert.
get-database
(get-database datasource-class pair-list) erzeugt ein Objekt, das eine Datenbank repräsentiert. Dabei ist die Zeichenkette datasource-class der Java Klassenname einer XADataSource. Die pair-list enthält Paare aus Zeichenketten, mit denen die DataSource konfiguriert wird. Für Apache Derby kann ein Aufruf von get-database beispielsweise so aussehen:
(get-database
"org.apache.derby.jdbc.EmbeddedXADataSource"
(quote (("databasename" "./wikidb"))))
make-read
(make-read sql parameter-types max-rows) erzeugt ein Prepared Statement, mit dem Daten gelesen werden können. Mit der Zeichenkette sql wird die Query als SQL angegeben. Die Liste von Symbolen parameter-types spezifiziert die Typen der Parameter des Prepared Statements. Erlaubt sind die Symbole int und string. Die Ganzzahl max-rows erlaubt es, die maximale Anzahl von Zeilen anzugeben, die bei der Ausführung des Prepared Statements zurückgeliefert werden. Wird hier der Wert 0 übergeben, dann bedeutet das, dass alle Rows geliefert werden sollen. Beispiel:
(make-read
"SELECT DISTINCT id, title FROM documents, titles, tags WHERE id = titles.documentid AND id = tags.documentid AND (documents.userid = ? OR visibility >= ?) AND normalizedtag = ? ORDER BY normalizedtitle ASC"
(quote (int int string))
0)
make-write
(make-write sql parameter-types) erzeugt ein Prepared Statement, mit dem der Datenbankinhalt verändert werden kann. Die Parameter verhalten sind analog zu make-read. Beispiel:
(make-write
"INSERT INTO documents(userid, visibility, text) VALUES (?, ?, ?)"
(quote (int int string)))
begin-transaction
(begin-transaction database) erzeugt eine Transaktion. Dabei ist database ein mit get-database erzeugtes Objekt.
end-transactions
(end-transactions txn-list success) beendet eine oder mehrere Transaktionen. txn-list ist eine Liste von Transaktionen, die mit begin-transaction erzeugt wurden. Der Wert von success steuert die Art des Transaktionsendes: nil führt zum Rollback der Transaktionen, alle anderen Werte führen zu einem Commit.
end-transaction
(end-transaction txn success) verhält sich analog zu end-transactions, jedoch wird eine Transaktion beendet.
with-transaction
(with-transaction database symbol s-expr1 s-expr2 ...) ist ein Macro, das zunächst eine Transaktion anhand der Datenbank database erzeugt und diese in der lokalen Variablen symbol speichert. Die S-Expressions s-expr1, ... werden der Reihe nach in einer Umgebung ausgeführt, die die lokale Variable symbol enthält. Die Auswertung der S-Expressions wird abgebrochen, sobald eine den Wert nil ergibt. In diesem Fall wird die Transaktion zurückgerollt. Wenn alle S-Expressions zu einen Wert ungleich nil ausgewertet werden können, dann wird die Transaktion festgeschrieben. Das Resultat von with-transaction ist das Resultat der letzten ausgewerteten S-Expression s-expr<i>.
Ausführen von Prepared Statements
Mit den Funktionen make-read und make-write werden Prepared Statements lediglich erzeugt. Da es sich bei Prepared Statements um Funktionen handelt, werden sie aktiviert, indem man die Funktion aufruft. Dann kommt das SQL zur Ausführung. Als erstes Argument muss beim Funktionsaufruf eine Transaktion übergeben werden, die weiteren Argumente füllen die Lücken im Prepared Statement.
Eine mit make-read erzeugte Funktion hat eine Liste von Assoziationsliste zum Ergebnis, wenn sie angewendet wird. Die Keys der Assoziationslisten bestimmen sich aus den Spaltennamen des SELECTs.
Eine mit make-write erzeugte Funktion hat entweder eine Ganzzahl als Ergebnis, es handelt sich um die Anzahl der vom INSERT, UPDATE oder DELETE betroffenen Datensätze. Als Ergebnis kann auch eine Liste von Assoziationslisten auftreten. Dabei handelt es sich dann um die Generated Keys eines INSERT Statements.
Einbinden ins Lisp-Package
In das Lisp-Package können die Funktionen aus dem Lisp-Database-Package eingebunden werden, indem der folgende Lisp-Code ausgeführt wird:
(setq get-database (make-combinator "lisp.database.combinator.GetDatabase" nil))
(setq begin-transaction (make-combinator "lisp.database.combinator.BeginTransaction" nil))
(setq end-transactions (make-combinator "lisp.database.combinator.EndTransactions" nil))
(setq end-transaction (lambda (txn success) (end-transactions (cons txn nil) success)))
(setq make-read (make-combinator "lisp.database.combinator.MakeRead" nil))
(setq make-write (make-combinator "lisp.database.combinator.MakeWrite" nil))
(setq with-transaction
(mlambda args
(let
((database (first args))
(txn (second args))
(terms (rest (rest args))))
(list3
let
(list (list2 txn (list2 (quote begin-transaction) database)))
(list3
let
(list
(list2
(quote result)
(list3
(quote catch)
(quote (quote sql-exception))
(cons (quote and) terms))))
(list3
progn
(list3
end-transaction
txn
(quote result))
(quote result)))))))
Weitere Beispiele
Wie die Funktionen des Lisp-Database-Packages verwendet werden, kann an der Demoanwendung Do you Lisp Wiki studiert werden.
Download
Die Quelltexte unterliegen der Modified Artistic License v1 finden sich in der Version v2 in der Jar-Datei unter dieser URL: http://www.qrst.de/downloads/lispdatabasesrc.jar
Zusätzlich werden noch das Collections-Package und das Lisp-Package benötigt.