[elephant-devel] Mixing "logical" layers in an elephant application

Alain Picard Alain.Picard at memetrics.com
Sun Dec 9 05:41:56 UTC 2007


Dear Elephant developers,

I'm trying to develop an application using Elephant, and
I think I've settled on the POSTMODERN back end.

Now, part of the application maps very naturally in what Elephant can
do, and other parts of it map better onto raw SQL processing,
where I wish to use POSTMODERN more or less directly.  As a
toy example, consider this:

    ;; in postmodern specific file
    (defun map-visits (fn thing-id &key (from 0) (to 9999999999) collect)
      (let ((results '()))
        (flet ((collector (thing)
                 (push (funcall fn thing) results)))
          (let ((fn (if collect #'collector fn)))
            (doquery (:select thing-id
                              :from :visit
                              :where (:and (:= thing-id id)
                                           (:< from 'timestamp)
                                           (:<= 'timestamp to)))
                (arg)
              (funcall fn arg))))
        results))

    ;; Later, in an elephant specific file
    (defmethod process (thing &key from to)
      (let ((contribs (make-hash-table)))
        (flet ((compute-something (arg)
                 (incf (gethash arg contribs 0))))
          (ensure-transaction ()
            (map-visits #'add-contribution (person-name fan) :from from :to to)))
        contribs))

The first function knows how to map over "visits", which are things
inserted into a postgresql table by a process other than my app.
It's a very simple SQL table.  But it relates semantically to objects
held within the elephant database; e.g. the second function, 
PROCESS-THING wants to map over all the visits of a THING, and do
some elephantine business with each visit, but doesn't want to concern
itself with how VISITS are implemented.

When I tried the above, it blew up when I added the ENSURE-TRANSACTION
clause; because all of a sudden the DOQUERY found itself querying
on the "wrong" database.  (I'm assuming ENSURE-TRANSACTION binds
something like a *DATABASE* var which got mistakenly inherited by
the postmodern layer)

This led me to thinking about what other unknown effects/surprises
may be lurking for me; e.g. how transactions in one "world" will
interact with another one, etc.  I have read the manual, including the
terse section "4.12 Multi-repository Operation", but what I'm attempting
may be even hairier.

Inspecting the code, I'm currently tempted to go hack up something
based on DB-POSTMODERN::CONTROLLER-CONNECTION-FOR-THREAD to
"marry" the two DB layers, but I thought I'd ask first if anyone
else has considered these sorts of issues and if there is a
"recommended" way of proceeding in a case such as this.  I guess
the first thing I'd try is to bind something way up in the elephant
call stack which would cause all lower level "raw" postmodern calls
to act on the same DB that the *STORE-CONTROLLER* is currently 
using.

Any thoughts or comments will be deeply appreciated.

                              Alain Picard



-- 
Please read about why Top Posting
is evil at: http://en.wikipedia.org/wiki/Top-posting
and http://www.dickalba.demon.co.uk/usenet/guide/faq_topp.html

Please read about why HTML in email is evil at: http://www.birdhouse.org/etc/evilmail.html



More information about the elephant-devel mailing list