Syncing documents in 2 views
I got quite some requests on the details of the syncing documents in views pattern/anti-pattern.So this is what you need to do:
This LotusScript was converted to HTML using the ls2html routine,
provided by Julian Robichaux at nsftools.com.
- Have 2 views with identical keys, sorted by the key
- Julian's OpenLog database
- The main function SyncAllDocument
- 3 auxiliary functions: getCompareKeySource, getCompareKeyTarget and updateSourceDoc
Option Public Option Declare Use "OpenLogFunctions" Function getCompareKey (doc As NotesDocument ) As String getCompareKey = doc .getitemvalues ( "someidfield" ) (0 ) End Function Sub updateSourcedoc (curDoc As NotesDocument , newDoc As NotesDocument ) 'We only save if the items have changed! Dim saveFlag As Boolean Dim curItem As NotesItem Dim newItem As NotesItem On Error Goto Err_updateSourcedoc saveFlag = False Forall it In newDoc .Items Set newItem = it If curDoc .HasItem (newItem . Name ) Then Set curItem = curDoc .GetFirstItem (newItem . Name ) If curItem . Text < > newitem . Text Then Call curItem . Remove Call newItem .CopyItemToDocument (curDoc ,newItem . Name ) saveFlag = True End If Else Call newItem .CopyItemToDocument (curDoc ,newItem . Name ) saveFlag = True End If End Forall 'Todo Optional: remove items that don't exist anymore If saveFlag Then Call curDoc .Save ( True , True ) End If Exit_updateSourcedoc : Exit Sub Err_updateSourcedoc : Call LogErrorEx ( "" ,SEVERITY_HIGH ,curDoc ) Resume Exit_updateSourcedoc End Sub Function SyncAllDocuments (sourceView As NotesView , targetView As NotesView ) As Boolean 'The documents to be compared Dim SourceDoc As NotesDocument Dim nextSourceDoc As NotesDocument Dim targetDoc As NotesDocument Dim nextTargetDoc As NotesDocument 'Auxiliary variables Dim gotoNextSource As Boolean Dim gotoNextTarget As Boolean Dim sourceKey As String Dim targetKey As String On Error Goto Err_SyncAllDocuments 'Important: the two views are designed that at the end of this algorythm both views have the same number of documents 'with the same data in it. gotoNextSource = True 'We need to set this to get the loop started gotoNextTarget = True 'We need to set this to get the loop started Set sourceDoc = SourceView .GetFirstDocument Set targetDoc = TargetView .GetFirstDocument 'This is the outer loop running through the documents in this database 'The "inner" loop is for the target database Do Until sourceDoc Is Nothing If gotoNextSource Then 'Since we just advanced to the current source we need to know the next one Set nextSourceDoc = SourceView .GetNextDocument (sourceDoc ) 'This must be BEFORE any action with the doc End If If targetDoc Is Nothing Then 'We don't have any target documents, so we copy point blank Call sourceDoc .CopyToDatabase (targetView .Parent ) gotoNextSource = True 'We can read the next source document gotoNextTarget = False 'We are already at nothing for the target Else 'Since targetdocument exists we can get the next target document now if we need it If gotoNextTarget Then 'Since we just advanced to the current target we need to know the next one Set nextTargetDoc = targetView .GetNextDocument (targetDoc ) 'This must be BEFORE any action with the doc End If 'Now we need to compare the keys sourceKey = getCompareKeySource (sourceDoc ) targetKey = getCompareKeyTarget (targetDoc ) If sourceKey = targetKey Then 'We found an existing document and would need to update it if values have changed Call updateSourcedoc (sourceDoc , targetDoc ) 'We can move our pointer one up for source and target documents gotoNextSource = True gotoNextTarget = True Elseif sourceKey > targetKey Then 'We found a document that doesn't exist in the source database anymore 'so we need to remove that from the target database Call targetDoc . Remove ( True ) gotoNextSource = False 'We stay on the source until we get even or less with the key gotoNextTarget = True 'We just removed the document Else 'We have a source document that is not yet in the target database, We just copy it over. Call sourceDoc .CopyToDatabase (targetView .Parent ) gotoNextSource = True 'We just copied this document we move on gotoNextTarget = False 'They key was too big, so we need to wait End If End If 'Advance the pointers If gotoNextSource Then Set sourceDoc = nextSourceDoc End If If gotoNextTarget Then Set targetDoc = nextTargetDoc End If Loop 'Finally we need to remove all documents in the target view that are still here since 'We ran out of source documents 'If we ran out of target documents already targetDoc is nothing aready Do Until targetDoc Is Nothing Set nextTargetDoc = targetView .getNextDocument (targetDoc ) Call targetDoc . Remove ( True ) Set targetDoc = nextTargetDoc Loop SyncAllDocuments = True 'If we got here it worked Exit_SyncAllDocuments : Exit Function Err_SyncAllDocuments : SyncAllDocuments = False LogError Resume Exit_SyncAllDocuments End Function Function getCompareKeySource (doc As NotesDocument ) As String getCompareKeySource = getCompareKey (doc ) End Function Function getCompareKeyTarget (doc As NotesDocument ) As String getCompareKeyTarget = getCompareKey (doc ) End Function
provided by Julian Robichaux at nsftools.com.
Posted by Stephan H Wissel on 21 September 2007 | Comments (3) | categories: Show-N-Tell Thursday