[isidorus-cvs] r720 - in trunk/src: json/isidorus-json rest_interface

lgiessmann at common-lisp.net lgiessmann at common-lisp.net
Fri Aug 12 08:43:54 UTC 2011


Author: lgiessmann
Date: Fri Aug 12 01:43:53 2011
New Revision: 720

Log:
trunk: rest-interface: fixed a potential bug => if a foreign association is contained in a fragment, i.e. an association that is not bound to the actual main topic of the passed fragment, the corresponding fragments of all players of the foreign associations are updated

Modified:
   trunk/src/json/isidorus-json/json_importer.lisp
   trunk/src/rest_interface/set-up-json-interface.lisp

Modified: trunk/src/json/isidorus-json/json_importer.lisp
==============================================================================
--- trunk/src/json/isidorus-json/json_importer.lisp	Wed Aug 10 12:45:20 2011	(r719)
+++ trunk/src/json/isidorus-json/json_importer.lisp	Fri Aug 12 01:43:53 2011	(r720)
@@ -38,7 +38,8 @@
 	(let ((psi-of-topic
 	       (let ((psi-uris (getf topic-values :subjectIdentifiers)))
 		 (when psi-uris
-		   (first psi-uris)))))
+		   (first psi-uris))))
+	      (committed-associations nil))
 	  (elephant:ensure-transaction (:txn-nosync nil) 
 	    (xtm-importer:with-tm (rev xtm-id (first tm-ids))
 	      (loop for topicStub-values in
@@ -47,10 +48,20 @@
 				  :xtm-id xtm-id))
 	      (json-merge-topic topic-values rev :tm xtm-importer::tm :xtm-id xtm-id)
 	      (loop for association-values in associations-values
-		 do (json-to-association association-values rev
-					 :tm xtm-importer::tm))))
+		 do (push (json-to-association association-values rev
+					       :tm xtm-importer::tm)
+			  committed-associations))))
 	  (when psi-of-topic
-	    (create-latest-fragment-of-topic psi-of-topic)))))))
+	    (let* ((frag (create-latest-fragment-of-topic psi-of-topic))
+		   (foreign-assocs
+		    (nset-difference
+		     committed-associations
+		     (map 'list (lambda(role)
+				  (parent role :revision rev))
+			  (player-in-roles (topic frag) :revision rev)))))
+	      (list :fragment frag
+		    :foreign-associations foreign-assocs))))))))
+		  
 
 
 (defun json-to-association (json-decoded-list start-revision

Modified: trunk/src/rest_interface/set-up-json-interface.lisp
==============================================================================
--- trunk/src/rest_interface/set-up-json-interface.lisp	Wed Aug 10 12:45:20 2011	(r719)
+++ trunk/src/rest_interface/set-up-json-interface.lisp	Fri Aug 12 01:43:53 2011	(r720)
@@ -501,11 +501,15 @@
 					    :force-text t)))
 	    (with-writer-lock
 	      (handler-case
-		  (let ((frag (json-importer:import-from-isidorus-json json-data)))
-		    (when frag
-		      (push-to-cache (d:topic frag))
-		      (update-list (d:topic frag)
-				   (d:psis (d:topic frag) :revision 0))))
+		  (let ((result (json-importer:import-from-isidorus-json json-data)))
+		    (when (getf result :fragment)
+		      (update-fragments-after-commit
+		       (getf result :fragment)
+		       (getf result :foreign-associations))
+		      (push-to-cache (d:topic (getf result :fragment)))
+		      (update-list (d:topic (getf result :fragment))
+				   (d:psis (d:topic (getf result :fragment))
+					   :revision 0))))
 		(condition (err)
 		  (progn
 		    (setf (hunchentoot:return-code*)
@@ -515,6 +519,60 @@
 	(setf (hunchentoot:return-code*) hunchentoot:+http-bad-request+))))
 
 
+(defun update-fragments-after-commit (new-fragment foreign-associations)
+  "Deleted all old fragment that belongs to the topic that is bound to
+   the passed new-fragment. Deletes and creates a new fragment of all
+   players of any association of the passed list foreign-associations."
+  (declare (FragmentC new-fragment)
+	   (List foreign-associations))
+  (map 'list #'elephant:drop-instance
+       (delete new-fragment
+	       (elephant:get-instances-by-value
+		'd:FragmentC 'd::topic (d:topic new-fragment))))
+  (let* ((rev (d:revision new-fragment))
+	 (tops
+	  (loop for assoc in foreign-associations
+	     append (loop for role in (d:roles assoc :revision rev)
+		       collect (d:player role :revision rev)))))
+    (map 'list (lambda(top)
+		 (map 'list #'elephant:drop-instance
+		      (elephant:get-instances-by-value
+		       'd:FragmentC 'd::topic top))
+		 (serialize-fragment (d:create-latest-fragment-of-topic top)
+				     (fragment-serializer)))
+	 (delete-duplicates (delete-if #'null tops)))))
+    
+
+(defun update-fragments-after-commit (new-fragment)
+  "Removes all fragments that belongs to the same topic that the
+   new fragment is bound to, but are older than the new fragment.
+   Updates all fragments that are bound to topics that are players
+   of associations contained in the new fragment."
+  (declare (FragmentC new-fragment))
+  (map nil (lambda(frg)
+	     (when (not (eql frg new-fragment))
+	       (elephant:drop-instance frg)))
+       (elephant:get-instances-by-value
+	'd:FragmentC 'd::topic (d:topic new-fragment)))
+  (let* ((rev (d:revision new-fragment))
+	 (top (d:topic new-fragment))
+	 (tops-to-update
+	  (delete
+	   top
+	   (let ((assocs (map 'list (lambda(role)
+				      (d:parent role :revision rev))
+			      (d:player-in-roles top :revision rev))))
+	     (loop for assoc in assocs
+		append (loop for role in (d:roles assoc :revision rev)
+			  collect (d:player role :revision rev)))))))
+    (map nil (lambda(top)
+	       (map nil #'elephant:drop-instance
+		    (elephant:get-instances-by-value 'd:FragmentC 'd::topic top))
+	       (d:serialize-fragment (create-latest-fragment-of-topic top)
+				     (fragment-serializer)))
+	 tops-to-update)))
+
+
 (defun return-topic-summaries(&optional param)
   "returns a summary of the requested topics"
   (declare (ignorable param))
@@ -610,7 +668,7 @@
 					      (elephant:drop-instance fragment)))
 				      (elephant:get-instances-by-value
 				       'd:FragmentC 'd:topic result))
-				 (update-fragments result rev))
+				 (update-fragments-after-delete result rev))
 				((typep result 'd:AssociationC)
 				 (let ((players
 					(delete-if
@@ -656,7 +714,7 @@
 
 
 
-(defun update-fragments(deleted-topic delete-revision)
+(defun update-fragments-after-delete(deleted-topic delete-revision)
   "Updates all fragments of topics that directly and indireclty
    related to the delete-topic."
   (declare (TopicC deleted-topic)




More information about the Isidorus-cvs mailing list