(FILECREATED "30-Jul-85 19:24:41" {PHYLUM}<NOTECARDS>RELEASE1.2I>FGHPATCH020.;4 12093  

      changes to:  (FNS NC.ScavengeDatabaseFile)
		   (VARS FGHPATCH020COMS)

      previous date: "22-Jul-85 22:52:27" {PHYLUM}<NOTECARDS>RELEASE1.2I>FGHPATCH020.;1)


(* Copyright (c) 1985 by Xerox Corporation. All rights reserved.)

(PRETTYCOMPRINT FGHPATCH020COMS)

(RPAQQ FGHPATCH020COMS ((* * Fix for scavenger to reconstruct file boxes uing From links -- redefined 
			   from NCREPAIR)
			(FNS NC.ScavengeDatabaseFile)))
(* * Fix for scavenger to reconstruct file boxes uing From links -- redefined from NCREPAIR)

(DEFINEQ

(NC.ScavengeDatabaseFile
  (LAMBDA (FileNameOrStream BadLinkLabelsFlg ListOfCardsToReconstruct ListOfGlobalLinksToReconstruct)
                                                             (* fgh: "30-Jul-85 19:20")

          (* Scavenge the database FileName. Essentially throw away all of the information about From and ToLinks and recreate
	  them by retrieving the link information from the substance of each card and from the list of global links from the 
	  card.)



          (* * rht 8/9/84: Now calls NC.OpenDatabaseFile to do the file open.)



          (* * rht 7/17/85: Changed so can take a stream argument. Also handles link labels. If BadLinkLabelsFlg is non-nil, 
	  then don't try to read current link labels. Just rebuild them from what's out there. Otherwise, only rebuild if find
	  new any new ones.)



          (* * fgh 22-Jul-85 Takes a list of bad file box cards and reconstructs the file boxes from the From pointer lists of
	  all the cards in the NoteFile.)



          (* * fgh 30-Jul-85 Takes a list of cards with bad global links and reconstructs the global links list from the From 
	  pointer lists of all the cards in the NoteFile.)


    (PROG (FileName OldLinkLabels DiscoveredLinkLabels FromLinks ToLinks DatabaseStream Status ID 
		    Links Entry FullName CardTotal GlobalLinks ActiveCardsList ReconstructLinks 
		    ReconstructGlobalLinks (ListOfValidCards (LIST (QUOTE **Header**))))

          (* * First, take care of checking stream's validity, etc.)


          (COND
	    ((AND (STREAMP FileNameOrStream)
		  (OPENP FileNameOrStream))                  (* There's already an open stream to repair.)
	      (SETQ DatabaseStream FileNameOrStream))
	    (T                                               (* Get file name and open the file if conditions are 
							     okay.)
	       (COND
		 ((AND (STREAMP PSA.Database)
		       (OPENP PSA.Database))
		   (NC.PrintMsg NIL T "There is an open NoteFile -- " (FULLNAME PSA.Database)
				(CHARACTER 13)
				"It must be closed before link rebuilding can be done."
				(CHARACTER 13))
		   (RETURN)))
	       (SETQ FileName FileNameOrStream)
	       (AND (NULL FileName)
		    (NULL (SETQ FileName (NC.DatabaseFileName 
						   "What is the name of the NoteFile to repair? "
							      NIL T)))
		    (RETURN NIL))
	       (AND (NULL (SETQ PSA.Database (SETQ DatabaseStream (NC.OpenDatabaseFile FileName NIL T)
			      )))
		    (NC.PrintMsg NIL NIL "Couldn't open " FileName "." (CHARACTER 13)
				 "Repair aborted."
				 (CHARACTER 13))
		    (RETURN NIL))
	       (NC.PrintMsg NIL NIL "Done.")))

          (* * If link labels aren't screwed up, then read them in.)


          (OR BadLinkLabelsFlg (SETQ OldLinkLabels (NC.GetLinkLabels DatabaseStream)))

          (* Read through all NoteCard substances to find actual pointers. Use this to create the To Links list.
	  The list collection function checks to make sure each link is valid.)


          (NC.PrintMsg NIL T "Collecting Links ... ")
          (for NoteCardNumber from 1 to (SETQ CardTotal (SUB1 (SUBATOM (NC.GetNewID DatabaseStream T)
								       3)))
	     do (SETQ ID (NC.IDFromNumber NoteCardNumber))
		(NC.PrintMsg NIL T "Rebuilding notefile links." (CHARACTER 13)
			     "Collecting Links for item " NoteCardNumber " out of " CardTotal "."
			     (CHARACTER 13))
		(COND
		  ((NOT (FMEMB ID ListOfCardsToReconstruct))
		    (SETQ Status (NC.GetNoteCard ID DatabaseStream))
		    (COND
		      ((NC.IDP Status)
			(SETQ ActiveCardsList (CONS Status ActiveCardsList))
			(AND (NOT (FMEMB ID ListOfValidCards))
			     (SETQ ListOfValidCards (CONS ID ListOfValidCards)))
			(SETQ Links (NC.CollectAndCheckLinks ID DatabaseStream ListOfValidCards))
			(SETQ ToLinks (CONS (CONS ID Links)
					    ToLinks))
			(SETQ GlobalLinks (CONS (CONS ID (NC.FetchGlobalLinks ID))
						GlobalLinks))

          (* If there are file boxes to be reconstructed, then look thru the From links to see if this card was filed in one 
	  of the to-be-reconstructed boxes)


			(AND ListOfCardsToReconstruct (for Link in (NC.FetchFromLinks ID)
							 when (FMEMB (fetch (NOTECARDLINK SOURCEID)
									of Link)
								     ListOfCardsToReconstruct)
							 do (SETQ ReconstructLinks (CONS Link 
										 ReconstructLinks))))

          (* If there are global links to be reconstructed, then look thru the From links to see if this card had a global 
	  link to a card whose global links need reconstructing.)


			(AND ListOfGlobalLinksToReconstruct (for Link in (NC.FetchFromLinks ID)
							       when
								(AND (NC.GlobalLinkP Link)
								     (FMEMB (fetch (NOTECARDLINK
										     SOURCEID)
									       of Link)
									    
								   ListOfGlobalLinksToReconstruct))
							       do (SETQ ReconstructGlobalLinks
								    (CONS Link ReconstructGlobalLinks)
								    )))
			(NC.DeactivateCard ID T))))
		  (T (NC.GetLinks ID DatabaseStream)
		     (SETQ GlobalLinks (CONS (CONS ID (NC.FetchGlobalLinks ID))
					     GlobalLinks))
		     (SETQ ToLinks (CONS (CONS ID (NC.FetchGlobalLinks ID))
					 GlobalLinks))
		     (NC.DeactivateCard ID T))))

          (* * Reconstruct any cards as requested)


          (for CardID in ListOfCardsToReconstruct
	     do                                              (* Make a new file box with the given ID)
		(NC.MakeNoteCard (QUOTE FileBox)
				 "Untitled: Reconstructed during repair" T NIL CardID)
                                                             (* File cards whose from links indicate that they used 
							     to be filed in this file box)
		(SETQ Links (for Link in ReconstructLinks when (AND (EQ CardID (fetch (NOTECARDLINK
											SOURCEID)
										  of Link))
								    (OR (NC.ContentsLinkP Link)
									(NC.SubContentsLinkP Link)))
			       collect (NC.FileBoxCollectChildren (NC.FetchSubstance CardID)
								  CardID
								  (LIST (fetch (NOTECARDLINK 
										    DESTINATIONID)
									   of Link))
								  T)
				       (create NOTECARDLINK copying Link)))
                                                             (* Add the new links to the collected links list)
		(COND
		  ((SETQ ThisCardsToLinks (FASSOC CardID ToLinks))
		    (NCONC ThisCardsToLinks Links))
		  (T (SETQ ToLinks (CONS (CONS CardID Links)
					 ToLinks))))
		(SETQ ActiveCardsList (CONS CardID ActiveCardsList)) 
                                                             (* Put the card away)
		(NC.PutNoteCard CardID DatabaseStream)
		(NC.DeactivateCard CardID T))

          (* * Reconstruct any global link lists as required)


          (for Link in ReconstructGlobalLinks
	     do                                              (* Add it to the GlobalLinks list)
		(COND
		  ((SETQ ThisCardsGlobalLinks (FASSOC (fetch (NOTECARDLINK SOURCEID) of Link)
						      GlobalLinks))
		    (COND
		      ((for GlobalLink in ThisCardsGlobalLinks never (EQUAL (fetch (NOTECARDLINK
										     LINKID)
									       of Link)
									    (fetch (NOTECARDLINK
										     LINKID)
									       of GlobalLink)))
			(COND
			  ((CADR ThisCardsGlobalLinks)       (* were there global links before?)
			    (NCONC1 ThisCardsGlobalLinks Link))
			  (T (RPLACD ThisCardsGlobalLinks (LIST Link)))))))
		  (T (SETQ GlobalLinks (CONS (CONS (fetch (NOTECARDLINK SOURCEID) of Link)
						   (LIST Link))
					     GlobalLinks))))
                                                             (* Add it to the ToLinks list if its not already there)
		(COND
		  ((SETQ ThisCardsToLinks (FASSOC (fetch (NOTECARDLINK SOURCEID) of Link)
						  ToLinks))
		    (COND
		      ((for ToLink in ThisCardsToLinks never (EQUAL (fetch (NOTECARDLINK LINKID)
								       of Link)
								    (fetch (NOTECARDLINK LINKID)
								       of ToLink)))
			(COND
			  ((CADR ThisCardsToLinks)
			    (NCONC1 ThisCardsToLinks Link))
			  (T (RPLACD ThisCardsToLinks (LIST Link)))))))
		  (T (SETQ ToLinks (CONS (CONS (fetch (NOTECARDLINK SOURCEID) of Link)
					       (LIST Link))
					 ToLinks)))))

          (* * Compute the From Links list by "inverting" the To Links list)


          (NC.PrintMsg NIL T "Processing Links ... ")
          (for Item in ToLinks do (for Link in (CDR Item) bind LinkLabel
				     do (SETQ Entry (FASSOC (fetch (NOTECARDLINK DESTINATIONID)
							       of Link)
							    FromLinks))
					(COND
					  (Entry (NCONC1 Entry Link))
					  (T (SETQ FromLinks (CONS (LIST (fetch (NOTECARDLINK 
										    DESTINATIONID)
									    of Link)
									 Link)
								   FromLinks))))
                                                             (* Accumulate the link labels into a list.)
					(COND
					  ((NOT (FMEMB (SETQ LinkLabel (fetch (NOTECARDLINK LINKLABEL)
									  of Link))
						       DiscoveredLinkLabels))
					    (SETQ DiscoveredLinkLabels (CONS LinkLabel 
									     DiscoveredLinkLabels)))))
	       )                                             (* Reset all of the To and From Links lists in the 
							     database)
          (NC.PrintMsg NIL T "Rewriting Links ... ")
          (for NoteCardNumber from 1 to (SETQ CardTotal (SUB1 (SUBATOM (NC.GetNewID DatabaseStream T)
								       3)))
	     do (AND (ZEROP (IREMAINDER NoteCardNumber 10))
		     (NC.PrintMsg NIL T "Repairing NoteFile." (CHARACTER 13)
				  "Rewriting links for item " NoteCardNumber " out of " CardTotal "."
				  (CHARACTER 13)))
		(SETQ ID (NC.IDFromNumber NoteCardNumber))
		(COND
		  ((FMEMB ID ActiveCardsList)
		    (NC.SetGlobalLinks ID (CDR (FASSOC ID GlobalLinks)))
		    (NC.SetToLinks ID (CDR (FASSOC ID ToLinks)))
		    (NC.SetFromLinks ID (CDR (FASSOC ID FromLinks)))
		    (NC.PutLinks ID DatabaseStream)
		    (NC.DeactivateCard ID T))))              (* Rewrite link labels if we've found any new ones.)
          (COND
	    ((LDIFFERENCE DiscoveredLinkLabels OldLinkLabels)
	      (NC.PutLinkLabels DatabaseStream (UNION DiscoveredLinkLabels OldLinkLabels))))
          (NC.CheckpointDatabase DatabaseStream T)
          (NC.ForceDatabaseClose DatabaseStream)
          (NC.PrintMsg NIL T "Repair Completed for " (FULLNAME DatabaseStream)
		       "."
		       (CHARACTER 13)))))
)
(PUTPROPS FGHPATCH020 COPYRIGHT ("Xerox Corporation" 1985))
(DECLARE: DONTCOPY
  (FILEMAP (NIL (627 12011 (NC.ScavengeDatabaseFile 637 . 12009)))))
STOP