common-lisp
Mit Datenbanken arbeiten
Suche…
Einfache Verwendung von PostgreSQL mit Postmodern
Postmodern ist eine Bibliothek zur Anbindung der relationalen Datenbank PostgreSQL . Es bietet mehrere Zugriffsebenen für PostgreSQL, von der Ausführung von SQL-Abfragen, die als Zeichenfolgen oder Listen dargestellt werden, bis zu einer objektrelationalen Zuordnung.
Die in den folgenden Beispielen verwendete Datenbank kann mit diesen SQL-Anweisungen erstellt werden:
create table employees
(empid integer not null primary key,
name text not null,
birthdate date not null,
skills text[] not null);
insert into employees (empid, name, birthdate, skills) values
(1, 'John Orange', '1991-07-26', '{C, Java}'),
(2, 'Mary Red', '1989-04-14', '{C, Common Lisp, Hunchentoot}'),
(3, 'Ron Blue', '1974-01-17', '{JavaScript, Common Lisp}'),
(4, 'Lucy Green', '1968-02-02', '{Java, JavaScript}');
Das erste Beispiel zeigt das Ergebnis einer einfachen Abfrage, die eine Beziehung zurückgibt:
CL-USER> (ql:quickload "postmodern") ; load the system postmodern (nickname: pomo)
("postmodern")
CL-USER> (let ((parameters '("database" "dbuser" "dbpass" "localhost")))
(pomo:with-connection parameters
(pomo:query "select name, skills from employees")))
(("John Orange" #("C" "Java")) ; output manually edited!
("Mary Red" #("C" "Common Lisp" "Hunchentoot"))
("Ron Blue" #("JavaScript" "Common Lisp"))
("Lucy Green" #("Java" "JavaScript")))
4 ; the second value is the size of the result
Das Ergebnis kann als Liste von Listen oder Plisten zurückgegeben werden, die die optionalen Parameter hinzufügen :alists
oder :plists
zur Abfragefunktion.
Eine Alternative zur query
ist doquery
, um die Ergebnisse einer Abfrage zu doquery
. Seine Parameter sind query (&rest names) &body body
, wobei die Namen bei jeder Iteration an die Werte in der Zeile gebunden sind:
CL-USER> (let ((parameters '("database" "dbuser" "dbpass" "localhost")))
(pomo:with-connection parameters
(format t "The employees that knows Java are:~%")
(pomo:doquery "select empid, name from employees where skills @> '{Java}'" (i n)
(format t "~a (id = ~a)~%" n i))))
The employees that knows Java are:
John Orange (id = 1)
Lucy Green (id = 4)
NIL
2
Wenn die Abfrage Parameter erfordert, können vorbereitete Anweisungen verwendet werden:
CL-USER> (let ((parameters '("database" "dbuser" "dbpass" "localhost")))
(pomo:with-connection parameters
(funcall
(pomo:prepare "select name, skills from employees where skills @> $1")
#("Common Lisp")))) ; find employees with skills including Common Lisp
(("Mary Red" #("C" "Common Lisp" "Hunchentoot"))
("Ron Blue" #("JavaScript" "Common Lisp")))
2
Die Funktion prepare
empfängt eine Abfrage mit den Platzhaltern $1
, $2
usw. und gibt eine neue Funktion zurück, die für jeden Platzhalter einen Parameter erfordert, und führt die Abfrage aus, wenn sie mit der richtigen Anzahl von Argumenten aufgerufen wird.
Bei Aktualisierungen gibt die Funktion exec
die Anzahl der modifizierten Tupel zurück (die beiden DDL-Anweisungen sind in einer Transaktion eingeschlossen):
CL-USER> (let ((parameters '("database" "dbuser" "dbpass" "localhost")))
(pomo:with-connection parameters
(pomo:ensure-transaction
(values
(pomo:execute "alter table employees add column salary integer")
(pomo:execute "update employees set salary =
case when skills @> '{Common Lisp}'
then 100000 else 50000 end")))))
0
4
Neben dem Schreiben von SQL-Abfragen als Zeichenfolgen können Listen mit Schlüsselwörtern, Symbolen und Konstanten verwendet werden, deren Syntax an lisp (S-SQL) erinnert:
CL-USER> (let ((parameters '("database" "dbuser" "dbpass" "localhost")))
(pomo:with-connection parameters
(pomo:query (:select 'name :from 'employees :where (:> 'salary 60000)))))
(("Mary Red") ("Ron Blue"))
2