common-lisp
Arbeta med databaser
Sök…
Enkel användning av PostgreSQL med Postmodern
Postmodern är ett bibliotek för att gränssnitta den relationsdatabas PostgreSQL . Det erbjuder flera nivåer av åtkomst till PostgreSQL, från exekvering av SQL-frågor representerade som strängar, eller som listor, till en objekt-relationskartläggning.
Databasen som används i följande exempel kan skapas med dessa SQL-satser:
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}');
Det första exemplet visar resultatet av en enkel fråga som returnerar en relation:
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
Observera att resultatet kan returneras som en lista med alister eller plister som lägger till valfria parametrar :alists
eller :plists
till :plists
.
Ett alternativ till query
är doquery
, att upprepa resultatet av en fråga. Parametrarna är query (&rest names) &body body
, där namnen är bundna till värdena i raden vid varje iteration:
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
När frågan kräver parametrar kan man använda förberedda uttalanden:
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
Funktionen prepare
får en fråga med platshållare $1
, $2
osv. Och returnerar en ny funktion som kräver en parameter för varje platshållare och kör frågan när den anropas med rätt antal argument.
Vid uppdateringar returnerar funktionen exec
antalet ändrade tupplar (de två DDL-uttalningarna ingår i en transaktion):
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
Förutom att skriva SQL-frågor som strängar, kan man använda listor med nyckelord, symboler och konstanter, med en syntax som påminner om lisp (S-SQL):
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