Desenvolvimento de Sistemas

Autor: Arnaldo Nizer do Vale - GSR

DESENVOLVIMENTO NOTES - EVITANDO CONFLITO DE GRAVAÇÃO

Muitas vezes já foi questionado se existe alguma maneira de o Notes mostrar um aviso quando se tenta editar um documento que outra pessoa já esteja editando. Até o momento, não existe nenhum modo de saber se um outro usuário está editando o documento antes de se tentar salvá-lo. Em determinados casos, seria muito útil se uma mensagem avisasse que o documento está sendo editado, quem é o editor e quanto tempo já se passou desde o início da operação.

Embora os tradicionais sistemas de informação evitem o conflito de gravação através do Lock de registro, isto é difícil de implementar em um ambiente distribuído, como o Notes. Para amenizar este problema, a Lotus resolveu deixar uma marca no documento resultante de um conflito para que o gerente da base possa resolver este conflito.

Como existem situações onde documentos precisam ser editados por mais de uma pessoa, esta programação em Lotus Script visa prevenir para que duas pessoas não editem o mesmo documento no Notes, evitando assim conflitos de gravação.

Para tanto, foi criado um banco de dados (Lockdb.nsf) que manterá os documentos atualmente reservados para edição. A idéia é a seguinte: Quando a 1ª pessoa acessa um documento, um script no evento PostOpen cria um documento correspondente na base Lockdb, armazenando seu UniqueID, o nome de quem reservou e a hora que isto ocorreu. Adicionalmente, toda vez que um documento estiver para ser aberto, um script verificará se este se encontra na lista dos "reservados". Caso não se encontre, ele será aberto normalmente. Caso contrário, o usuário recebe uma mensagem dizendo que o documento está sendo editado e não habilita o modo de edição. Somente quando o 1º usuário terminar sua edição, outro evento marca este documento como "liberado", podendo outro usuário então alterá-lo. Para finalizar, deverá existir um agente na base Lockdb para fazer a limpeza desta base, deletando os documentos já liberados.

A base Lockdb.nsf deve ter um formulário (locdoc) com quatro campos: dbTitle, SavedReplicaId, SavedUNID, EXPIRED.

Código:

Evento: PostOpen do documento que estiver sendo editado:

  • Sub Postopen(Source As Notesuidocument)

If source.editmode Then

Dim session As New NotesSession

Dim db As NotesDatabase

Dim doc As NotesDocument

Set doc = source.Document

Set db = doc.ParentDatabase

Dim locdb As New NotesDatabase (db.Server, "Lockdb.nsf")

If locdb.IsOpen Then

Dim locdoc As New NotesDocument (locdb)

Dim coldoc As New NotesDocument (locdb)

Dim collection As NotesDocumentcollection

Dim locdoctime As New NotesDateTime("")

Dim coldoctime As New NotesDatetime("")

Dim expirydate As New NotesDateTime("")

Dim cutoffdate As New NotesDateTime("01/01/97")

'Cria o documento de Lock

Dim authorsitem As New NotesItem(locdoc, "userid", _

session.CommonUserName, AUTHORS)

locdoc.dbtitle = db.Title

locdoc.savedReplicaID = db.ReplicaID

locdoc.savedUNID = doc.UniversalID

locdoc.form = "locdoc"

Call locdoc.save(True, False)

locdoctime.LSLocalTime = locdoc.created

'Encontra documentos não expirados para este documento

searchformula$ = "form = ""locdoc"" & savedUNID = """ + doc.UniversalID _

+ """ & savedReplicaID = """ + db.ReplicaID + """ & @Text(EXPIRED) =''"

Set collection = locdb.Search(searchformula$, cutoffdate, 0)

Call expirydate.SetNow

For i = 1 To collection.Count

Set coldoc = collection.GetNthDocument(i)

If Not(coldoc.userid(0) = session.CommonUserName) Then

locdoc.Expired = expirydate.LocalTime

Call locdoc.Save(True, False)

source.editmode = False

coldoctime.LSLocalTime = coldoc.created

diff& = locdoctime.TimeDifference (coldoctime)

Messagebox (coldoc.userid(0) + " reservou este documento para edição há " _

+ Cstr(diff&) + " segundos, em " + Cstr(coldoctime.LSLocalTime))

Exit For

End If

Next

End If

End If

End Sub

Evento: Querymodechange do documento que estiver sendo editado:

  • Sub Querymodechange(Source As Notesuidocument, Continue As Variant)

Continue = True

If Not(source.editmode) Then

Dim session As New NotesSession

Dim db As NotesDatabase

Dim doc As NotesDocument

Set doc = source.Document

Set db = doc.ParentDatabase

Dim locdb As New NotesDatabase(db.Server, "Lockdb.nsf")

If locdb.IsOpen Then

Dim locdoc As New NotesDocument (locdb)

Dim coldoc As New NotesDocument (locdb)

Dim collection As NotesDocumentcollection

Dim locdoctime As New NotesDateTime("")

Dim coldoctime As New NotesDatetime("")

Dim expirydate As New NotesDatetime("")

Dim cutoffdate As New NotesDateTime("01/01/97")

'Cria o locdoc

Dim authorsitem As New NotesItem(locdoc, "userid", _

session.CommonUserName, AUTHORS)

locdoc.dbtitle = db.Title

locdoc.savedReplicaID = db.ReplicaID

locdoc.savedUNID = doc.UniversalID

locdoc.form = "locdoc"

Call locdoc.save(True, False)

locdoctime.LSLocalTime = locdoc.created

'Encontra locdocs para este documento

searchformula$ = "form = ""locdoc"" & savedUNID = """ + doc.UniversalID _

+ """ & savedReplicaID = """ + db.ReplicaID + """ & @Text(EXPIRED) = '' "

Set collection = locdb.Search(searchformula$, cutoffdate, 0)

'Verifica locdocs para outros usuários

Call expirydate.SetNow

For i = 1 To collection.Count

Set coldoc = collection.GetNthDocument(i)

If Not(coldoc.userid(0) = session.CommonUserName) Then

locdoc.Expired = expirydate.LocalTime

Call locdoc.Save(True, False)

Continue = False

coldoctime.LSLocalTime = coldoc.created

diff& = locdoctime.TimeDifference (coldoctime)

Messagebox (coldoc.userid(0) + " reservou este documento para edição há " _

+ Cstr(diff&) + " segundos, em " + Cstr(coldoctime.LSLocalTime))

Exit For

End If

Next

End If

End If

End Sub

Evento: Postmodechange do documento que estiver sendo editado:

  • Sub Postmodechange(Source As Notesuidocument)

If Not(source.editmode) Then

Dim session As New NotesSession

Dim db As NotesDatabase

Dim doc As NotesDocument

Set doc = source.Document

Set db = doc.ParentDatabase

Dim locdb As New NotesDatabase(db.Server, "Lockdb.nsf")

If locdb.IsOpen Then

Dim coldoc As New NotesDocument (locdb)

Dim collection As NotesDocumentcollection

Dim expirydate As New NotesDateTime("")

Dim cutoffdate As New NotesDateTime("01/01/97")

'Marca estes documentos como expirados para este documento

searchformula$ = "form = ""locdoc"" & savedUNID = """ + doc.UniversalID _

+ """ & savedReplicaID = """ + db.ReplicaID + """ & userid = """ _

+ session.CommonUserName + """ & @Text(EXPIRED) = '' "

Set collection = locdb.Search(searchformula$, cutoffdate, 0)

Call expirydate.SetNow

For i = 1 To collection.Count

Set coldoc = collection.GetNthDocument(i)

coldoc.Expired = expirydate.LocalTime

Call coldoc.Save(True, False)

Next

End If

End If

End Sub

Evento: Terminate do documento que estiver sendo editado:

  • Sub Terminate

Dim workspace As New NotesUIWorkspace

Dim uidoc As NotesUIDocument

Set uidoc = workspace.CurrentDocument

If uidoc.editmode Then

Dim session As New NotesSession

Dim doc As NotesDocument

Set doc = uidoc.Document

Dim db As NotesDatabase

Set db = doc.ParentDatabase

Dim locdb As New NotesDatabase(db.Server, "Lockdb.nsf")

If locdb.IsOpen Then

Dim coldoc As New NotesDocument (locdb)

Dim collection As NotesDocumentcollection

Dim expirydate As New NotesDateTime("")

Dim cutoffdate As New NotesDateTime("01/01/97")

searchformula$ = "form = ""locdoc"" & savedUNID = """ + doc.UniversalID _

+ """ & savedReplicaID = """ + db.ReplicaID + """ & userid = """ _

+ session.CommonUserName + """ & @Text(EXPIRED) = '' "

Set collection = locdb.Search(searchformula$, cutoffdate, 0)

Call expirydate.SetNow

For i = 1 To collection.Count

Set coldoc = collection.GetNthDocument(i)

coldoc.Expired = expirydate.LocalTime

Call coldoc.Save(True, False)

Next

End If

End If

End Sub

Agente de Limpeza da Base de Reservas (lockdb.nsf)

  • Sub Initialize

Dim session As New NotesSession

Dim db As NotesDatabase

Set db = session.CurrentDatabase

Dim doc As NotesDocument

Dim collection As NotesDocumentcollection

Set collection = db.UnprocessedDocuments

'Remover documentos expirados desta base

For i = 1 To collection.Count

Set doc = collection.GetNthDocument(i)

If doc.HasItem("Expired") And doc.Form(0) = "locdoc" Then

Call doc.remove(True)

End If

Next

End Sub