I’ve learnt a lot over the years, but occasionally I’m reminded of reusable bits of code I created years ago and am still using today. Deletion logging is an example of that. Before I joined Intec I created a lotusscript library with a couple of function to track attempted deletions, either via a log or an email to an administrator. Time and again it’s helped me out, whether to confirm user error or to prove a document must still be in the database somewhere. It’s been very reliable and I’m still using it virtually unchanged, although I have considered convering it into a class or, more recently, into a server-side javascript library. I will at some point and it will probably take less than an hour, but at the moment it’s something I’ve not got round to.
The script library is attached. In the QueryDocumentDelete method of the Database Script, I enter the following code to call the DeletionTrack function:
-
Sub Querydocumentdelete(Source As Notesuidatabase, Continue As Variant)
-
Dim dc As notesdocumentcollection
-
Dim doc As notesdocument
-
Dim db As notesdatabase
-
Dim deleteAccess As Variant
-
-
On Error Goto logErr
-
-
deleteAccess = Evaluate(“@UserAccess(@DbName;[DeleteDocuments])”)
-
If deleteAccess(0) = “1” Then
-
Set dc = Source.Documents
-
Set db = Source.Database
-
Call DeletionTrack(“DELETE”, dc, db)
-
Else
-
Msgbox “You do not have delete rights to the database. Please use the relevant button.”, 16, “Delete Aborted”
-
continue = False
-
End If
-
Exit Sub
-
-
logErr:
-
continue = False
-
Msgbox LogError()
-
Exit Sub
-
End Sub
In the QueryDocumentUndelete, I enter similar code, tracking any undeletion, but this time without checking access levels because the attempt to delete was already aborted if the user didn’t have access:
-
Sub Querydocumentundelete(Source As Notesuidatabase, Continue As Variant)
-
Dim dc As notesdocumentcollection
-
Dim doc As notesdocument
-
Dim db As notesdatabase
-
-
On Error Goto logErr
-
-
Set dc = Source.Documents
-
Set db = Source.Database
-
Call DeletionTrack(“UNDELETE”, dc, db)
-
Exit Sub
-
-
logErr:
-
continue = False
-
Msgbox LogError()
-
Exit Sub
-
End Sub
This means when the user presses Delete, a log is generated with the type of DELETE, if they press Delete again to unflag the documet(s) for deletion, a log is generated with the type UNDELETE. The DeletionTrack function then uses constants to determine whether logging is enabled, whether logging should be via docuemnts in the database or via email. The DeletionLog and DeletionMail both call a GetDescription where a default description is generated and specific description messages can be generated for particular Form types. This can be useful to capture any unique references, for example, that you might want to search on.
The only downside of this functionality is that if a user has documents flagged for deletion and exits the database, choosing not to delete those documents, no UNDELETE log is created. This is a minor inconvenience and one that needs to be borne in mind, but not one that has ever caused me difficulties.
In one of the recent releases there was a new and very useful column in the application properties > user activity properties which listed deletions but it seems to have dissappered again
@1: Thee appearance of that column is dependent on the ODS version of the db.
I added deletion logging to NotesTracker several versions ago — see for example { Link } for an illustration. NotesTracker is coded largely in LotusScript, and I discovered (empirically, that is) what seems to be the case that a document deletion request — such as notesDocument.Remove(force) — is an asynchronous event. You’re asking/telling the Notes Client or Domino Server that you’d like to remove the document, and while it probably will happen almost straight away there’s no immediate and dependable return code that you can rely on. Therefore in some situations (determined empirically, as I said earlier) you cannot be sure whether or not the document is still there. And that’s without the additional considerations imposed by soft/hard deletions!
@2 Thanks for the information. I also thought I’d seen it, but then couldn’t. After reading your post I found that for a database with ODS 51 I have the Deletes column, for a database with ODS 43 I don’t. That columns certainly useful, but the column only shows a delete as opposed to information on what was deleted, and the User Detail can be limited in the time period it covers.
@3 That’s useful information to be aware of, another little quirk. I guess the only option would be a daily agent to cross-reference and try to find the document by UNID in the database, which could well be overkill for some applications. But it’s certainly useful to know that a document can still be in a database when your code should have deleted it.