[Cl-perec-devel] Lots of questions :-)
mihai at bazon.net
Mon Sep 14 10:01:21 UTC 2009
Thanks for your fast reply!
Indeed, I knew about pinterface series, it helped a lot to get started.
I tried defining my own type today and after some embarrassing amount of
trial and error I came up with this:
(cl-perec:defptype password ()
(cl-perec::defmapping password (cl-rdbms::sql-character-varying-type :size 128)
'cl-perec:identity-reader ; unexported
(defun password-writer (val rdbms-values index)
(setf (elt rdbms-values index)
(ironclad:digest-sequence :sha1 (babel:string-to-octets val)))))
(pushnew 'password cl-perec::*canonical-types*)
(pushnew 'password cl-perec::*mapped-type-precedence-list*)
It works, it creates SHA1 automatically for password fields, but there's
one weird side effect: now *all* columns of a TEXT type are
VARCHAR(128), and they are all mangled to SHA1. :-) Could you point out
what did I do wrong?
Attila Lendvai <attila.lendvai at gmail.com> wrote:
> loads of useful information is available here:
> > 1. I'm defining my own DB package in which I :USE :CL-PEREC. This
> > introduces some conflicts that can be mitigated by
> > :shadowing-import-from :cl-perec :set :time. What is the recommended
> > way, though? Would it be better if I don't :USE :cl-perec and prefix
> > all names with "cl-perec:"?
> these are usual CL namespace (package) issues. using
> :shadowing-import-from is the right way, unless you want to do more
> > 2. I have a (defpclass* page) which shows the following warning in SBCL:
> > ; caught STYLE-WARNING:
> > ; defclass* for CL-PEREC:PAGE while its home package is not *package* (#<PACKAGE "DLWEB.DB">)
> > I can guess that there's a class named "page" in cl-perec?
> not a class, but an exported symbol. defclass* interns some symbols,
> and it's warning you that you are defining a class called
> cl-perec:page while you are in another package. this _may_ lead to
> problems (symbols interned into cl-perec instead of your package
> causing some clashes, redefinitions, etc)
> if you want to be tidy then you should (:shadow #:page) in your package.
> > 3. OIDs seem to be randomly generated. Are they generated by cl-perec,
> > or by Postgres itself? (I haven't use PG in many years so sorry if
> > it's PG-related).
> oid's encode both the class and the identity of persistent objects,
> that's why the oid's seem to be random. first n bits are the class,
> last k bits are the identity.
> > 4. I have a Perl background and have used various DB-to-Object mappers
> > (and even wrote my own). Most of them, in Perl, provide an easy way
> > to "inflate/deflate" columns. For example, if a column is of type
> > TIMESTAMP (which the DB server returns as a string), when an instance
> > is retrieved I can make that slot return an object of type DateTime,
> > which is more comfortable to work with. So in other words, an
> > automatic conversion happens when a row is fetched from the DB, and
> > the reverse conversion when it's stored into DB.
> > Another example is storing hashed passwords in the DB. In Perl I
> > would do:
> > $user->password("foobar");
> > $user->update;
> > ## and now $user->password is some MD5 of "foobar"
> > Is there a way to do this with cl-perec?
> i think that's how perec works... just look at the predefined
> timestamp type, it returns localtime:timestamp instances.
> you can define your own persistent types, see the blog entries above,
> or look at the standard-type.lisp in perec (which should be plural,
> standard-types.lisp, but someone else needs to convince Levy, i've
> tried already... :)
> > 5. I plan to use cl-perec with hunchentoot for creating sites. One of
> > the things I commonly did in Perl was to use the same code (and
> > server) for multiple websites; because they had different data, the
> > database connection was selected at runtime, depending on the target
> > domain name of the incoming request. I presume a way to do this in
> > cl-perec would be to set the value of *database* accordingly on each
> > request, but since Hunchentoot is multithreaded, would this be safe?
> > If not, can you recommend a better way?
> you should never set these contextual variables when working with
> multiple threads, but bind them at a high enough point:
> (defmethod handle-request :around ((x some-of-my-stuff))
> (let ((*database* *my-database*))
> this will introduce a new separate thread-local binding of the special
> variable in each thread when they get to that point.
> btw, we will start a website Real Soon Now (weeks at most) that will
> demo our web architecture, including a detailed shell script that can
> reproduce that site locally on your machine and start it up.
> > 7. How do I define columns of type VARCHAR(255)? It seems wasteful to
> > use TEXT for every string..
> (text 255)
> hth, and good luck with perec!
More information about the cl-perec-devel