Domino Code Fragment

Code Name*
Lock a document that is being edited?
Date*
04/19/2000
Source (or email address if you prefer)*
Rlatulippe@romac.com
IP address:.
Description*
How do you lock a document that is being edited? Eric Koeler has written a set of functions for doing this in Notes 4.x. You can grab the code and a code sample at his web site. The Lotuscript code works by adding a lock field to the document the user wishes to edit and then immediately saving the document; when other users try to open the document, they will see that there is a lock field so they cannot edit the document. This technique will only work if the database is on a single server (no replication). There is also a small chance for a race condition if two users manage to read a document simultaneously without the lock. Finally, if the user's system crashes while editing this locked document, the document will remain locked unless you implement some sort of emergency unlock mechanism.
Type*
LotusScript
Categories*
User Interface (Notes), Workflow
Implementation:
Required Client:
Server:
Limitations:
Comments:
Files/Graphics attachments (if applicable): Code:
%REM
----------------------------------------------------------------------------
FILE:    EKDOCLOC.LSS - Function Library
UPDATED: April 1997
AUTHOR:  Eric Koeler
        mailto:ekoeler@panix.com
        http://www.panix.com/~ekoeler
NOTE:    Copyright (C) 1997 by Eric Koeler, this file is protected by the
        GNU General Public License
----------------------------------------------------------------------------
In the Declarations section of the script in which you plan to use these
functions, add the following line:


     %INCLUDE "FILEPATH\EKDOCLOC.LSS"

Where FILEPATH is the OS-specific, fully qualified path to the location
where you saved this file.
----------------------------------------------------------------------------
%ENDREM


' Function declarations
Declare Function DocLockCheck (doc    As NotesDocument, _
                              prompt As Integer)       As Integer
Declare Function DocLockCreate(doc    As NotesDocument) As Integer
Declare Function DocLockRemove(doc    As NotesDocument) As Integer


' Fields used for document locking
Const LOCKFIELD   = "$LockEdit"
Const LOCKFIELDTD = "$LockEditTime"


'----------------------------------------------------------------------------

Function DocLockCheck(doc As NotesDocument, prompt As Integer) As Integer
 
    On Error Goto ErrorHandler
    DocLockCheck = False


     Dim sess     As New NotesSession
    Dim thisUser As     String
    Dim thatUser As     String


     '----- Get the user names
    thisUser = sess.CommonUserName
    If doc.HasItem(LOCKFIELD) Then
         thatUser = doc.GetFirstItem(LOCKFIELD).Text
    Else
         thatUser = ""
    End if


     '----- Check if this document is already locked
    If Strcomp(thatUser, thisUser) And Strcomp(thatUser, "") Then
         DocLockCheck = True
         If (prompt) Then
              Msgbox thatUser & " is currently viewing or editing this document. " & _
              "You will not be able to edit this document until this user is finished.", 0, _
              "Edit Lock"
        End If
    End If
   
TheEnd:
    Exit Function
   
ErrorHandler:
    Print Trim$(Str(Err)) & ": " & Error$
    Resume TheEnd


End Function

'----------------------------------------------------------------------------

Function DocLockCreate(doc As NotesDocument) As Integer

     On Error Goto   ErrorHandler
    Dim sess As New NotesSession
    DocLockCreate = False


     '----- Check if this user is locked out
    If DocLockCheck(doc, True) Then Goto TheEnd


     '----- Otherwise, lock this document  
    Call doc.ReplaceItemValue(LOCKFIELD,   sess.CommonUserName)
    Call doc.ReplaceItemValue(LOCKFIELDTD, Now)
    DocLockCreate = doc.Save(True, True)
   
TheEnd:
    Exit Function
   
ErrorHandler:
    Print Trim$(Str(Err)) & ": " & Error$
    Resume TheEnd


End Function

'---------------------------------------------------------------------------

Function DocLockRemove(doc As NotesDocument) As Integer

     On Error Goto   ErrorTime
    DocLockRemove = False
         
    '----- Check if this user is locked out, but don't prompt
    If DocLockCheck(doc, False) Then Goto TheEnd


     '----- This user had the lock, so remove it now
    Call doc.RemoveItem(LOCKFIELD)
    Call doc.RemoveItem(LOCKFIELDTD)
    DocLockRemove = doc.Save(True, True)


TheEnd:
    Exit Function


ErrorTime:

     '----- Print the error to the status bar
    Print Trim$(Str$(Err)) & ": " & Error$
    Resume TheEnd

End Function



%REM
----------------------------------------------------------------------------
FILE:    EKDOCLOC.LSS - Documentation and Sample Usage
UPDATED: May 1997
AUTHOR:  Eric Koeler
        mailto:ekoeler@panix.com
        http://www.panix.com/~ekoeler
NOTE:    Copyright (C) 1997 by Eric Koeler, this file is protected by the
        GNU General Public License
----------------------------------------------------------------------------
The functions in the EKDOCLOC library are to be used for document edit-
locking.  This is a useful feature if you have many users who could
open and/or edit the same document simultaneously, which can lead to
replication/save conflicts.  


To implement document locking in a form module, call DocLockCreate() in the
QueryOpen event.  This will create an edit-lock name field with the current
user's name and an edit-lock time field with the current time.  If the doc
is already locked, the user will be prompted and told who currently has the
document open.  In the QueryModeChange event, call DocLockCheck(), which
will return True if the current user is locked out (the second parameter
to the function tells the function to prompt the user if they are locked
out).  In the QueryClose event, call DocLockRemove to remove the current
user's edit-lock; if the current user is locked out, this function doesn't
do anything.


You can simply import the sample the code below into a form module to
enable document locking.
----------------------------------------------------------------------------
%ENDREM


'Declarations
%INCLUDE "EKDOCLOC.LSS"


Sub Queryopen(Source   As Notesuidocument, _
             Mode     As Integer,         _
             Isnewdoc As Variant,         _
             Continue As Variant)
   
    On Error     Goto   ErrorHandler
    Dim sess     As New NotesSession
   
    '----- If this is a new doc, don't bother locking it
    If (Source.IsNewDoc) Then Goto TheEnd
   
    '----- If we can't create the doc lock, don't allow editing
    If Not(DocLockCreate(Source.Document)) Then


          '----- If we are opening directly in edit mode, cancel the open
         If Mode = 1 Then Continue = False
    End If
   
TheEnd:
    Exit Sub
   
ErrorHandler:
    Print Trim$(Str(Err)) & ": " & Error$
    Resume TheEnd
   
End Sub




Sub Querymodechange(Source As Notesuidocument, Continue As Variant)
   
    On Error Goto ErrorHandler
   
    '----- If we are trying to go into edit mode
    If Source.EditMode = False Then
                   
         '----- Check if the current user is locked out
         If DocLockCheck(Source.Document, True) Then Continue = False
    End If
   
TheEnd:
    Exit Sub
   
ErrorHandler:
    Print Trim$(Str(Err)) & ": " & Error
    Resume TheEnd
   
End Sub




Sub Queryclose(Source As Notesuidocument, Continue As Variant)
   
    On Error     Goto   ErrorTime
    Dim sess     As New NotesSession
    Dim temp     As     String
   
    '----- Remove the doc lock
    Call DocLockRemove(Source.Document)
         
TheEnd:
    Continue = True
    Exit Sub
   
ErrorTime:
    Print Trim$(Str$(Err)) & ": " & Error$
    Resume TheEnd
   
End Sub