Re: [patch] Updated Patch for fault-join-target-slot and update-objects-joins

Drew Crampsie <[email protected]> Tue, 01 Nov 2005 09:14:42 -0800
Newsgroups gmane.lisp.clsql.devel
Message-ID <[email protected]>
Aleksandar Bakic wrote:
>>>Attached is an updated version of my previous patch which also fixes the 
>>>problems with update-objects-joins when using the :target-slot attribute.
>>
>>Thanks for the patch, Drew.
>>
>>I've applied it and released CLSQL 3.3.3 with your fix.
> 
> 
> Hi,
> 
> What should happen if the target slot is not a join slot at all, but a regular
> one? I am getting an error at this point in fault-join-target-slot:
> 
> 	 (tdbi (view-class-slot-db-info
> 		(find ts (class-slots (find-class jc)) 
> 		      :key #'slot-definition-name))) 
> 	 (retrieval (gethash :retrieval tdbi)) ; tdbi is nil

What is it that you are trying to do? :target-slot is specifically for 
many-to-many joins, and i can't see it making sense outside of them. it 
would probably be trivial to simply return the sql-slot-value of the 
:target-slot when it is not a join slot, but i can't see what value this 
gains.

FWIW, although the patch corrects 'can't find class' issue, f-j-t-s 
still doesn't work for my purposes as it doesn't fill in the primary 
keys (when using :deferred, none of the instances actually come from the 
database. when using :immediate (which i never use) the target class has 
"real" instances, but the join-class (hosting the many-to-many) just 
fills the joined keys, but does not get the actual rows from the 
database. Both of these behaviors i find completely useless. A 'regular' 
join slot returns 'real' instances that i can manipulate and 
UPDATE-RECORDS-FROM-INSTACE, where a many-to-many returns these 'pseudo' 
instances that do me no good at all.

I've modified my clsql f-j-t-s locally to use the following definition :

(defun fault-join-target-slot (class object slot-def)
   (let* ((dbi (view-class-slot-db-info slot-def))
	 (ts (gethash :target-slot dbi))
	 (jc  (gethash :join-class dbi))
	 (foo (warn "~A ~A " (class-slots (find-class jc)) ts ))
	 (jc-view-table (view-table (find-class jc)))
	 (tdbi (view-class-slot-db-info
		(find ts (class-slots (find-class jc))
		      :key #'slot-definition-name)))
	 (retrieval (gethash :retrieval tdbi))
	 (tsc (gethash :join-class tdbi))
	 (ts-view-table (view-table (find-class tsc)))
	 (jq (join-qualifier class object slot-def))
	 (key (slot-value object (gethash :home-key dbi))))

     (when jq
       (let ((res
		(find-all (list jc)
			  :inner-join (sql-expression :table ts-view-table)
			  :on (sql-operation
			       '==
			       (sql-expression
				:attribute (gethash :foreign-key tdbi)
				:table ts-view-table)
			       (sql-expression
				:attribute (gethash :home-key tdbi)
				:table jc-view-table))
			  :where jq
			  :result-types :auto
			  :database (view-database object))))
	   (mapcar #'(lambda (i)
		       (setf (slot-value (car i) 'view-database) (view-database object))
		       (cons (car
			      (select tsc
				      :where (sql-= (sql-slot-value tsc (gethash :foreign-key tdbi))
						    (slot-value (car i)  (gethash :home-key tdbi)))
				      :flatp t))
			     i))
		   res)))))


This 'works', although it hits the database a lot. I'd rather do a join, 
but clsql seems to offer no way of doing what i need to do (although my 
clsql-internals-fu is quite possibly not up to the task). I'm still 
hacking on this locally, but am using the above in production (with 
great success i might add).

The behavior of f-j-t-s as i've patched it locally, to me, seems the be 
the right-thing (tm). It is consistent with the rest of the OODML 
interface, and removes a major source of confusion. I'm not sure what 
behavior CommonSQL specified here, but the current behavior simply can't 
be right.

Does anybody actually use :join-slot with the current behavior and can 
justify keeping it that way? if not, i'd like to see my version, or 
something that returns the same instances, in 3.3.4. I'll even volunteer 
to update the documentation to remove any confusion about :target-slot :)

Thoughts?

drewc