r9280: sql/objects.lisp: more framework for supporing immediate retrieval
[clsql.git] / sql / objects.lisp
index 6b2fb4b0b892391a84bd15227ff298c98cd94b2e..0285ca45e4cf00fa1d2b04991290eaac63e34297 100644 (file)
@@ -234,17 +234,18 @@ superclass of the newly-defined View Class."
        sels
         (error "No slots of type :base in view-class ~A" (class-name vclass)))))
 
+(defun generate-immediate-joins-list (vclass)
+  "Returns list of pairs of join slots and their class for a class."
+  (let ((sels nil))
+    (dolist (slotdef (ordered-class-slots vclass))
+      (when (and (eq :join (view-class-slot-db-kind slotdef))
+                (eq :immediate (gethash :retrieval (view-class-slot-db-info slotdef))))
+       (push slotdef sels)))
+    (cons vclass (list sels))))
 
-;;
 ;; Called by 'get-slot-values-from-view'
 ;;
 
-(declaim (inline delistify))
-(defun delistify (list)
-  (if (listp list)
-      (car list)
-      list))
-
 (defvar *update-context* nil)
 
 (defmethod update-slot-from-db ((instance standard-db-object) slotdef value)
@@ -738,6 +739,8 @@ superclass of the newly-defined View Class."
   (let* ((dbi (view-class-slot-db-info slot-def))
         (ts (gethash :target-slot dbi))
         (jc (gethash :join-class dbi))
+        (ts-view-table (view-table (find-class 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)))
@@ -749,11 +752,15 @@ superclass of the newly-defined View Class."
        (:immediate
         (let ((res
                (find-all (list ts) 
-                         :inner-join (sql-expression :attribute jc)
+                         :inner-join (sql-expression :table jc-view-table)
                          :on (sql-operation 
                               '==
-                              (sql-expression :attribute (gethash :foreign-key tdbi) :table ts)
-                              (sql-expression :attribute (gethash :home-key tdbi) :table jc))
+                              (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)))
           (mapcar #'(lambda (i)
@@ -778,8 +785,8 @@ superclass of the newly-defined View Class."
                   (setf (slot-value jcc (gethash :home-key tdbi)) 
                         fk)
                   (list instance jcc)))
-            (select (sql-expression :attribute (gethash :foreign-key tdbi) :table jc)
-                    :from (sql-expression :table jc)
+            (select (sql-expression :attribute (gethash :foreign-key tdbi) :table jc-view-table)
+                    :from (sql-expression :table jc-view-table)
                     :where jq)))))))
 
 (defun update-object-joins (objects &key (slots t) (force-p t)
@@ -787,7 +794,7 @@ superclass of the newly-defined View Class."
   "Updates the remote join slots, that is those slots defined without :retrieval :immediate."
   (when objects
     (unless class-name
-      (class-name (class-of (first object))))
+      (class-name (class-of (first objects))))
     )
   )
 
@@ -853,6 +860,10 @@ superclass of the newly-defined View Class."
                 (apply #'sql-and jc)
                 jc))))))
 
+;; FIXME: add retrieval immediate for efficiency
+;; For example, for (select 'employee-address) in test suite =>
+;; select addr.*,ea_join.* FROM addr,ea_join WHERE ea_join.aaddressid=addr.addressid\g
+
 (defun find-all (view-classes 
                 &rest args
                 &key all set-operation distinct from where group-by having 
@@ -896,6 +907,7 @@ superclass of the newly-defined View Class."
                   objects))))
     (let* ((*db-deserializing* t)
           (sclasses (mapcar #'find-class view-classes))
+          (immediate-joins (mapcar #'generate-immediate-joins-list sclasses))
           (sels (mapcar #'generate-selection-list sclasses))
           (fullsels (apply #'append sels))
           (sel-tables (collect-table-refs where))