[elephant-devel] using association slots
Ian Eslick
eslick at media.mit.edu
Tue Jun 17 21:31:36 UTC 2008
On Jun 17, 2008, at 3:23 PM, LukasGiessmann wrote:
> hello,
>
> just in case you're wondering why i'm coming up with questions
> concerning
> marc's topic "associations in the elephant system", i'm trying to
> assist
> him with this topic, so there might be several questions coming up
> in the
> next time - hope you don't mind.
> to get straight to the point:
>
> 1)
> i tried to work with the last person/job example and the new
> association
> slots, so i made the following example:
I apologize for not documenting or providing better examples for the
final association design. Hopefully this will help in the meantime.
> ---
> (defpclass job()
> ((title :initarg :title :accessor title-of :index t)
> (company :initarg :company :accessor company-of :index t)))
>
(defpclass job()
((title :initarg :title :accessor title-of :index t)
(company :initarg :company :accessor company-of :index t)
(people :accessor job-holders :associate (person job))))
Associations are restricted to mappings between classes. Here we
indicate that a virtual slot people (accessor is job-holders) is
associated with all objects of class 'person that contain this
instances in slot 'job.
> (defpclass person()
> ((name :initarg :name :accessor name-of :index t)
> (job :initarg :job :accessor job-of :associate t)))
>
(defpclass person()
((name :initarg :name :accessor name-of :index t)
(job :initarg :job :accessor job-of :associate job)))
Providing :associate job tells the person class that the slot 'job
contains instances of type job and to maintain an association to job
instances (each person has 1 job, each job may have many people).
The initarg for job here requires a patch that I'll submit shortly.
>
> (defvar *max-persons* 500)
> (defvar *max-jobs* 100)
>
> (defun make-instances ()
> (with-transaction ()
> (dotimes (i *max-jobs*)
> (let ((current-job (make-instance 'job :title (string (gensym))
> :company (string (gensym)))))
> (dotimes (j (/ *max-persons* *max-jobs*))
> (make-instance 'person :name (string (gensym)) :job current-
> job))))))
> ---
>
> after the call of make-instances there are 100 jobs and for every job
> there exist 5 persons.
> but i have still the following problem:
> how can i get all persons which associate a certain job by using the
> instance of the job which should be associated by the persons.
> i thought on something like:
>
> ---
> (defvar *obj* (first (get-instances-by-class 'job)))
> (get-instance-by-value 'person 'job *obj*)
> ---
(job-holders *obj*) => < list of five people >
(setf (job-holders *obj*) (sixth (get-instances-by-class 'person)))
(job-holders *obj*) => < list of six people >
I made two small enhancements while exploring this example which I
will checkin shortly:
1) Can treat a slot associated with another class as an indexed slot:
(get-instances-by-value 'person 'job *obj*)
2) Now allows :initargs to set the slot value for association slots that
contain a single object. (I may allow this for other types later)
>
> 2)
> what is the better way for using association slots in your opinion,
> the one of the example above or a special class which contains only
> associations of jobs and persons?
> ---
> (defpclass p-j-assoc()
> ((job :initarg :job :accessor job-of :associate t)
> (person :initarg :person :accessor person-of :associate t)))
> ---
>
> 3)
> how do i work with many-to-many association slots, since it is not
> possible for me to assign a value to the slot.
This is what associations are an effective shorthand for; so you don't
have to create an explicit object.
(defpclass job()
((title :initarg :title :accessor title-of :index t)
(company :initarg :company :accessor company-of :index t)
(people :accessor job-holders :associate (person job) :many-to-many
t)))
(defpclass person()
((name :initarg :name :accessor name-of :index t)
(jobs :accessor jobs-of :associate (job people) :many-to-many t))
This defines a many-to-many relationship between job and person.
Unfortunately currently initargs don't work here. You can add
elements by (setf (jobs-of joe) janitor) and get access to all
associated elements via (job-holders janitor) => joe.
I need to add insert/delete operations (there are stubs in
association.lisp) so you can work with the association more directly.
I also fixed a bug or two as well. I'll let you know when I've
checked in the fixes. Thanks for prompting the exercise!
>
> thank you in advance.
>
>
> best regards
>
> lukas
>
> _______________________________________________
> elephant-devel site list
> elephant-devel at common-lisp.net
> http://common-lisp.net/mailman/listinfo/elephant-devel
More information about the elephant-devel
mailing list