dominoGuru.com

Your Development & Design Resource

Quicktip: Environment Variables, Database Scripts, NotesDocument UniversalIDs, and non-View NotesDocument Indexing

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 Evaluates 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:

  1. @GetDocField(@Environment("HASH_preferences"); "Categories");
  2. 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!


About the author: Chris Toohey

Thought Leadership, Web & Mobile Application Development, Solutions Integration, Technical Writing & Mentoring

A published developer and webmaster of dominoGuru.com, Chris Toohey specializes in platform application development, solutions integration, and evangelism of platform capabilities and best practices.



More from dominoGuru.com


dominoGuru.com is powered by IBM Notes Domino XPages & hosted by Prominic.NET

Contact Us

Use our Contact / Feedback form or one of these email addresses:

Creative Commons License

Except where otherwise noted, dominoGuru.com by Chris Toohey is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.