[elephant-devel] Re: Master-detail how to

Robert L. Read read at robertlread.net
Tue Apr 8 03:53:32 UTC 2008


On Mon, 2008-04-07 at 16:51 -0700, Vagif Verdi wrote:
> If I will make item class persistent, then items will be saved independently
> of their parent. That means manual housekeeping.
> When order object is deleted, I will have to intercept that and manually
> delete all items objects.
> And this is only simplest hierarchy. 
> Imagine how much manual work must be done in case or deeper hierarchies.
> 
> Maybe I do not understand how elephant work.
> Maybe it somehow automatically deletes all objects that are in a pset slot
> of the object being deleted.
> Is that the case?
> 
> 
Dear Vagif,

	No, you are understanding how elephant works.  It does not provide
"cascading delete", because LISP itself does not provide this (except
via the somewhat different mechanism of garbage collection.)

	The test code below should work for you if you have elephant installed
and can open a store-controller (you should be in the ELE-TESTS package,
see the file RUNTESTS.lisp).

Although it is a lot of test code, you can see the that function
"delete-order", which deletes and order and all of its items, is
trivial.

	One might philosophically prefer SQL.  I personally vaster prefer to
work in a powerful programming language to accomplish these things.
Obviously, whether two classes that refer to each other stand in a
"parent-child" relationship or not depends entirely on the
circumstances.  I prefer to write simple functions such as
"delete-order" below, which both utilize and (in a sense) expand the
power of LISP applied to persistent objects.


(open-store *testpm-spec*)

(defun delete-order (order)
	(mapcar #'(lambda (i) (drop-instances (list i))) (items-of order))
	(drop-instances (list order)))


(test simple-order-item-deletion
  (wipe-class 'order)
  (wipe-class 'item)

  (defpclass order ()
   ((name :accessor name-of :initarg :name :index t)
    (items :initform '() :accessor items-of :initarg :items)
    ))

  (defpclass item ()
  ((partnumber :accessor partnumber-of :initarg :partnumber-of :index
t)))

  (let ((NUM_ORDERS 100)
	(NUM_ITEMS_PER_ORDER 5))
    (dotimes (x NUM_ORDERS)
      (let ((order
	     (make-instance 'order  :name (string (gensym)))))
      (dotimes (y NUM_ITEMS_PER_ORDER)
	(push (make-instance 'item  :partnumber (string (gensym))) (items-of
order))
	)
      ))
    ;; Now let's see how many isntances we have....
    (is (equal (* NUM_ORDERS NUM_ITEMS_PER_ORDER)
	       (length (get-instances-by-class (find-class 'item)))))
    ;; Now let's delete them...
    (mapcar #'delete-order (get-instances-by-class (find-class 'order)))
    ;; Now we should have zero items.
 
    (is (= 0 (length (get-instances-by-class (find-class 'item)))))))








More information about the elephant-devel mailing list