dominoGuru.com
Your Development & Design Resource
Quicktip: Environment Variables, Database Scripts, NotesDocument UniversalIDs, and non-View NotesDocument Indexing
09/15/2008 01:36 PM by Chris Toohey
The majority of the Lotus Notes Applications I've written lately - from customer applications to the freeware/tip jar-ware that I've been publishing to this site - all feature a Preferences NotesDocument, which contains... well, preferences for the given application. The Preferences Document is a simple NotesDocument containing Keywords and other data items that help the given Notes Application do whatever it's supposed to do.
Now, before we even hear from anyone asking "Why aren't you using Profile Documents?" - issues like HTTP Caching and their tendency to corrupt keep them off my radar. And, in the spirit of being truthful here: I just prefer to handle a NotesDocument as a NotesDocument, not some voodoo mystery back-end thing that's really just a special type of - you guessed it - NotesDocument.
There are, however, some issues with the Preferences NotesDocument approach. The biggest being it's dependancy on a Domino Views for NotesDocument lookups. For example, I've added a Domino View named (bykey)|bykey into pretty much all of the freeware/tip jar-ware applications, but it's there for the sole purpose of providing me with a lookup-point to get a handle on the Preferences Document. So... what's wrong with that?!
How many of you have a 2GB+ Domino Application lying around? Okay... do this for me. Create a new view containing any number of columns that you want, that shows all NotesDocuments in the database... and tell me how long that takes to open.
Now, run this simple script against your 2GB+ Domino Application:
Function getDocs() As NotesDocumentCollection
Dim s As New NotesSession
Dim db As NotesDatabase
Dim col As NotesDocumentCollection
Set db = s.GetDatabase("", "db.nsf")
Set col = db.AllDocuments
Msgbox "Got " & Cstr(col.Count) & " NotesDocuments!"
End Function
Obviously change your db
declaration to get a handle on your
2GB+ Domino Application... but you get the idea here. What slows down your
Domino Applications are NOT the number of or size of your NotesDocuments...
it's their rendering in Domino Views. Sure - they cache... but ViewIndex
caching makes the Domino Application even larger than it really needs to be,
and what happens when something happens to the View or the ViewIndex itself?
Yeah, prepare to stare at your Lotus Notes Client for a while...
I don't want to add to that for a Preferences Document. How can I justify that bloat to just allow someone to assign keywords and other Domino Application... stuff to make it work. Yeah, I can't do that in good conscience. And I have been doing just that...
So, from now on, my freeware/tip jar-ware Domino Applications are going to use the following approach, recently popularized by Andrew and Nathan. Specifically, I'm going to logically-define the "Preferences" NotesDocument UniversalID!
Doing this is pretty simple actually... I just need to define a schema and
stick with it. So, for example, let's say that this will be for a global
Preferences Document. We'll create our @Password
HASH logic to
create a UNID for our Preferences Document:
@ReplaceSubString(@Text(@Password("preferences")); "(":")";"")
So... my real problem with this approach is that I don't like having to bail
out of whatever language I'm running at the given moment to get a handle on the
Preferences Document UNID. I want to keep the Evaluate
s to a
minimum here, so I'll look to the Lotus Notes Client cookie-like
behavior of the Environment Variables to provide me with access-from-anything
cache of the UNID for my Preferences Document.
To do this, I've simply added the following to the Initialize Event in my Applications Database Script:
Sub Initialize
Dim s As New NotesSession
Dim hash As String
hash = s.GetEnvironmentString(|HASH_preferences|)
If Len(hash) = 0 Then
hash =
Join(Evaluate(|@ReplaceSubString(@Text(@Password("preferences"));
"(":")";"")|), "")
Call s.SetEnvironmentVar(|HASH_preferences|, hash)
End If
End Sub
Pretty basic stuff here, as this creates the following line in the Notes.ini:
$HASH_preferences=A68506D12B73EC4E4A77FB934144FD97
So, since we've taken the steps to set the UNID of our Preferences Document
to be the evaluated @Password
hash of "preferences", we
can now use the Preference Document via View Index-free lookups in (for
example) just one of the following ways:
@GetDocField(@Environment("HASH_preferences"); "Categories");
Set doc = db.GetDocumentByUNID(s.GetEnvironmentString("HASH_preferences"))
Now, while I will place this into the freeware/tip jar-ware
Domino Applications as just Preference Document lookups... keep in mind that
you can easily expand this to evaluate more user-specific
lookups by adding such considerations into your Domino Applications. For
example, you can have user-specific "Profile" Documents by setting the UNID to
something like @Password("profile_" + @Name([CN]; @UserName))
, and
using either the Environment Variable approach or an inline HASH to get those
NotesDocuments View/Index-free!