15/01/2022

Use @DbColumn in LotusScript with more than 32K data

Reading view entries in LotusScript is awfully slow. @DbColumn is very fast, but it doesn't allow me to get more than 32K data from a view column. So I developed some code that gets all the data. Enjoy!

The code below is an extract of a Class that contains several variables:

		
Private Const MAXBLKSIZE= 1024
Private Const MINBLKSIZE= 64	

Class DbList		
	Private dbinfo As String
	Private vwName As String
	Private vw As NotesView
	Private cache As Variant 
	Private searchCol As String  
	Private searchValues As Variant 
	Private searchKeys As String ' imploded searchValues, as in "a":"b"
	
	Sub New(db As NotesDatabase, vwName As String)
		Me.vwName= vwName
		dbInfo= |"| + db.server + |":"| + Replace(db.Filepath, "\", "/") + |"|
	End Sub
	.
	.
		
The function fillCache will recursively get the view entries:
	
	.
	.
	%REM
		Function fillCache
		Description: Load all selectable values 
	%END REM
	Private Sub fillCache 
		If IsEmpty(searchValues) Then 
			Call fillCacheR(0, CInt(vw.Entrycount))
		Else
			Call fillCacheR(0, CInt(vw.Getallentriesbykey(searchValues, True).Count))
		End If 
	End Sub 
	
	%REM
		Sub fillCacheR
		Description: Load a subset of selectable values, takes care of >32K problems;
		DbColumn and DbLookup are a lot faster than NotesViewEntries 
	%END REM
	Private Sub fillCacheR(offset As Long, count As Long)
		Dim v As Variant
		Dim n As Long 
		Dim s As String 
		If count=0 Then
			Exit Sub 
		End If
		If count<=MAXBLKSIZE Then ' try to get the values, otherwise split
			If searchKeys="" Then 
				s= |@Subset(@Subset(@DbColumn(""; | + dbinfo +|; "| + vwname + |"; | _
				   + searchCol + |); | + CStr(offset+count) + |); | + CStr(-count) + |)|
			Else
				s= |@Subset(@Subset(@DbLookup(""; | + dbinfo +|; "| + vwname + |"; "| + searchKeys + |"; | _
				   + searchCol + | ); | + CStr(offset+count) + |); | + CStr(-count) + |)|
			End If 
			v= Evaluate(s)
			If IsArray(v) Then ' we have data!
				If IsEmpty(cache) Then
					cache= v
				Else
					cache= ArrayAppend(cache, v)
				End If
				Exit Sub 
			End If 
		End If 
		' if we got here, there's too much to read, so split in 2
		n= count\2
		If n<MINBLKSIZE Then ' too small, must be some error...
			Error 1001, "Caching problem on " + vwname
		End If
		Call fillCacheR(offset, n)
		Call fillcacheR(offset+n, count-n) 
	End Sub
End Class

Is there room for improvement? Possibly, please let me know!

© 2020 Sjef Bosman · Consultant HCL Domino/Notes
SIRET 442 133 252 00019 · tél. +33 475 252 805
sjef@bosman.fr · sjef.bosman