cl-perec tutorial, lisp clos persistency
Update: in case you’ve already had a database, like the one below, a more up to date session is available here.
cl-perec is an RDBMS based CLOS persistency library. Consider these about a fresh install of a postgresql server before starting. Socket connections are refused by default. Then create a database for storing the instances:
$ sudo -u postgres psql
[sudo] password for grault:
Welcome to psql 8.3.7, the PostgreSQL interactive terminal.
Type: \copyright for distribution terms
\h for help with SQL commands
\? for help with psql commands
\g or terminate with semicolon to execute query
\q to quit
postgres=# create database perec_db1;
CREATE DATABASE
postgres=# create user perec_user with password 'perec999pass';
CREATE ROLE
postgres=# grant all on database perec_db1 to perec_user;
GRANT
postgres=# \q
$
and then load the following forms:
(asdf:oos 'asdf:load-op :cl-perec)
(cl-def:def defclass-star:class* myconn
(cl-perec:database-mixin cl-rdbms:postgresql-postmodern) ())
(setf cl-perec:*database*
(make-instance 'myconn
:generated-transaction-class-name 'transaction
:default-result-type 'vector
:muffle-warnings t
:connection-specification '(:host "localhost"
:port 5433
:database "perec_db1"
:user-name "perec_user"
:password "perec999pass")))
(cl-rdbms:start-sql-recording)
(cl-perec:defpclass c1 ()
((s1 :type string :initform "foo" :initarg :s1 :accessor s1-of)))
Finally issue some make-instance:
CL-USER> (cl-perec:with-transaction
(make-instance 'c1 :s1 "hello"))
; BEGIN
; SELECT relname FROM pg_class WHERE relkind = 'r'
; CREATE TABLE _c1 (_oid BIGINT NOT NULL PRIMARY KEY, _s1 TEXT)
; DROP VIEW IF EXISTS _c1_di
; CREATE VIEW _c1_di AS SELECT _oid FROM _c1
; DROP VIEW IF EXISTS _c1_dp
; CREATE VIEW _c1_dp AS SELECT _oid, _c1._s1 FROM _c1
; DROP VIEW IF EXISTS _c1_dd
; CREATE VIEW _c1_dd AS SELECT _oid, _c1._s1 FROM _c1
; DROP VIEW IF EXISTS _c1_ai
; CREATE VIEW _c1_ai AS SELECT _oid FROM _c1
; DROP VIEW IF EXISTS _c1_ap
; CREATE VIEW _c1_ap AS SELECT _oid, _c1._s1 FROM _c1
; DROP VIEW IF EXISTS _c1_ad
; CREATE VIEW _c1_ad AS SELECT _oid, _c1._s1 FROM _c1
; COMMIT
; BEGIN
; SELECT relname FROM pg_class WHERE relkind = 'S'
; CREATE SEQUENCE _instance_id
; SELECT NEXTVAL('_instance_id')
; $1 = 121174 as BIGINT, $2 = hello as TEXT
; INSERT INTO _c1 (_oid, _s1) VALUES ($1::BIGINT, $2::TEXT)
; COMMIT
#<C1 :persistent #t 1>
CL-USER> (cl-perec:with-transaction
(make-instance 'c1 :s1 "hello2"))
; BEGIN
; SELECT NEXTVAL('_instance_id')
; $1 = 186710 as BIGINT, $2 = hello2 as TEXT
; INSERT INTO _c1 (_oid, _s1) VALUES ($1::BIGINT, $2::TEXT)
; COMMIT
#<C1 :persistent #t 2>
CL-USER>