Add normalized view classes
[clsql.git] / sql / metaclasses.lisp
index a9e3ccd84efe2290fdd74e1f705e203981472634..0d6471b19654fdeeb722dc16ffa5eec3626edccb 100644 (file)
@@ -46,6 +46,9 @@
    (key-slots
     :accessor key-slots
     :initform nil)
+   (normalisedp
+    :accessor normalisedp
+    :initform nil)
    (class-qualifier
     :accessor view-class-qualifier
     :initarg :qualifier
                                           base-table))
                                  (class-name class)))))
 
+(defmethod ordered-class-direct-slots ((self standard-db-class))
+  (let ((direct-slot-names
+         (mapcar #'slot-definition-name (class-direct-slots self)))
+        (ordered-direct-class-slots '()))
+    (dolist (slot (ordered-class-slots self))
+      (let ((slot-name (slot-definition-name slot)))
+        (when (find slot-name direct-slot-names)
+          (push slot ordered-direct-class-slots))))
+    (nreverse ordered-direct-class-slots)))
+
 (defmethod initialize-instance :around ((class standard-db-class)
                                         &rest all-keys
                                         &key direct-superclasses base-table
-                                        qualifier
+                                        qualifier normalisedp
                                         &allow-other-keys)
   (let ((root-class (find-class 'standard-db-object nil))
         (vmc 'standard-db-class))
                    (remove-keyword-arg all-keys :direct-superclasses)))
         (call-next-method))
     (set-view-table-slot class base-table)
+    (setf (normalisedp class) (car normalisedp))
     (register-metaclass class (nth (1+ (position :direct-slots all-keys))
                                    all-keys))))
 
 (defmethod reinitialize-instance :around ((class standard-db-class)
                                           &rest all-keys
-                                          &key base-table
+                                          &key base-table normalisedp
                                           direct-superclasses qualifier
                                           &allow-other-keys)
   (let ((root-class (find-class 'standard-db-object nil))
         (vmc 'standard-db-class))
     (set-view-table-slot class base-table)
+    (setf (normalisedp class) (car normalisedp))
     (setf (view-class-qualifier class)
           (car qualifier))
     (if (and root-class (not (equal class root-class)))
     (setf (key-slots class) (remove-if-not (lambda (slot)
                                              (eql (slot-value slot 'db-kind)
                                                   :key))
-                                           (ordered-class-slots class)))))
+                                           (if (normalisedp class)
+                                               (ordered-class-direct-slots class)
+                                               (ordered-class-slots class))))))
 
 #+(or sbcl allegro)
 (defmethod finalize-inheritance :after ((class standard-db-class))
   (setf (key-slots class) (remove-if-not (lambda (slot)
                                            (eql (slot-value slot 'db-kind)
                                                 :key))
-                                         (ordered-class-slots class))))
+                                         (if (normalisedp class)
+                                             (ordered-class-direct-slots class)
+                                             (ordered-class-slots class)))))
 
 ;; return the deepest view-class ancestor for a given view class