X-Git-Url: http://git.kpe.io/?a=blobdiff_plain;ds=sidebyside;f=sql%2Foodml.lisp;h=f289a49d0d2660dc29580b28315c9eba2a9fc1c7;hb=566670ff665e99a1774e0899a02ecde2d62b99cc;hp=3b3ef5748c9ead8ddc77c5871a860049f2900f11;hpb=32a9217aad2888c93943daf5752b785216700484;p=clsql.git diff --git a/sql/oodml.lisp b/sql/oodml.lisp index 3b3ef57..f289a49 100644 --- a/sql/oodml.lisp +++ b/sql/oodml.lisp @@ -204,6 +204,7 @@ (sql-expression :table (view-table o))) (defmethod attribute-references ((o class-and-slots)) + "build sql-ident-attributes for a given class-and-slots" (loop with class = (view-class o) for sd in (slot-defs o) @@ -248,7 +249,8 @@ rtns)) (defun update-auto-increments-keys (class obj database) - ;; handle pulling any autoincrement values into the object + " handle pulling any autoincrement values into the object + if normalized and we now that all the " (let ((pk-slots (keyslots-for-class class)) (table (view-table class)) new-pk-value) @@ -265,10 +267,9 @@ "This seems kindof wrong, but this is mostly how it was working, so its here to keep the normalized code path working" (when (typep in-class 'standard-db-class) - (loop for slot in (keyslots-for-class in-class) - do (do-update slot)) - (loop for c in (class-direct-superclasses in-class) - do (chain-primary-keys c))))) + (loop for slot in (ordered-class-slots in-class) + when (key-slot-p slot) + do (do-update slot))))) (loop for slot in pk-slots do (do-update slot)) (let ((direct-class (to-class obj))) (when (and new-pk-value (normalizedp direct-class)) @@ -278,7 +279,10 @@ (defmethod %update-instance-helper (class-and-slots obj database &aux (avps (attribute-value-pairs class-and-slots obj database))) - ;; we dont actually need to update anything on this particular parent class + "A function to help us update a given table (based on class-and-slots) + with values from an object" + ;; we dont actually need to update anything on this particular + ;; class / parent class (unless avps (return-from %update-instance-helper)) (let* ((view-class (view-class class-and-slots)) @@ -313,6 +317,12 @@ (defmethod update-record-from-slots ((obj standard-db-object) slots &key (database *default-database*)) + "For a given list of slots, update all records associated with those slots + and classes. + + Generally this will update the single record associated with this object, + but for normalized classes might update as many records as there are + inheritances " (setf slots (listify slots)) (let* ((classes-and-slots (view-classes-and-slots-by-name obj slots)) (database (choose-database-for-instance obj database))) @@ -323,6 +333,10 @@ (defmethod update-record-from-slot ((obj standard-db-object) slot &key (database *default-database*)) + "just call update-records-from-slots which now handles this. + + This function is only here to maintain backwards compatibility in + the public api" (update-record-from-slots obj slot :database database)) (defun view-classes-and-storable-slots (class) @@ -352,6 +366,7 @@ (defmethod primary-key-slot-values ((obj standard-db-object) &key class slots ) + "Returns the values of all key-slots for a given class" (defaulting class (class-of obj) slots (keyslots-for-class class)) (loop for slot in slots @@ -382,6 +397,10 @@ (primary-key-slot-values obj))) (defmethod delete-instance-records ((instance standard-db-object) &key database) + "Removes the records associated with a given instance + (as determined by key-qualifier-for-instance) + + TODO: Doesnt handle normalized classes at all afaict" (let ((database (choose-database-for-instance instance database)) (vt (sql-expression :table (view-table (class-of instance))))) (if database @@ -442,6 +461,8 @@ (defmethod update-slot-from-record ((instance standard-db-object) slot &key (database *default-database*)) + "Pulls the value of a given slot form the database and stores that in the + appropriate slot on instance" (multiple-value-bind (res slot-def) (get-slot-value-from-record instance slot :database database) (let ((vd (choose-database-for-instance instance database))) @@ -983,44 +1004,39 @@ maximum of MAX-LEN instances updated in each query." (normalized-key-value object)) (update-slot-from-record object slot-def))) +(defun all-home-keys-have-values-p (object slot-def) + "Do all of the home-keys have values ?" + (let ((home-keys (join-slot-info-value slot-def :home-key))) + (loop for key in (listify home-keys) + always (easy-slot-value object key)))) + (defun join-qualifier (class object slot-def) + "Builds the join where clause based on the keys of the join slot and values + of the object" (declare (ignore class)) - (let* ((dbi (view-class-slot-db-info slot-def)) - (jc (find-class (gethash :join-class dbi))) + (let* ((jc (join-slot-class slot-def)) ;;(ts (gethash :target-slot dbi)) ;;(tsdef (if ts (slotdef-for-slot-with-class ts jc))) - (foreign-keys (gethash :foreign-key dbi)) - (home-keys (gethash :home-key dbi))) - (when (every #'(lambda (slt) - (and (slot-boundp object slt) - (not (null (slot-value object slt))))) - (if (listp home-keys) home-keys (list home-keys))) - (let ((jc - (mapcar #'(lambda (hk fk) - (let ((fksd (slotdef-for-slot-with-class fk jc))) - (sql-operation '== - (typecase fk - (symbol - (sql-expression - :attribute - (database-identifier fksd nil) - :table (database-identifier jc nil))) - (t fk)) - (typecase hk - (symbol - (slot-value object hk)) - (t - hk))))) - (if (listp home-keys) - home-keys - (list home-keys)) - (if (listp foreign-keys) - foreign-keys - (list foreign-keys))))) - (when jc - (if (> (length jc) 1) - (apply #'sql-and jc) - jc)))))) + (foreign-keys (listify (join-slot-info-value slot-def :foreign-key))) + (home-keys (listify (join-slot-info-value slot-def :home-key)))) + (when (all-home-keys-have-values-p object slot-def) + (clsql-ands + (loop for hk in home-keys + for fk in foreign-keys + for fksd = (slotdef-for-slot-with-class fk jc) + for fk-sql = (typecase fk + (symbol + (sql-expression + :attribute (database-identifier fksd nil) + :table (database-identifier jc nil))) + (t fk)) + for hk-val = (typecase hk + ((or symbol + view-class-effective-slot-definition + view-class-direct-slot-definition) + (easy-slot-value object hk)) + (t hk)) + collect (sql-operation '== fk-sql hk-val)))))) ;; FIXME: add retrieval immediate for efficiency ;; For example, for (select 'employee-address) in test suite =>