Everything you ever wanted to know about lotus script


Published on

Presented at BE LUG, Belgium, 2012

Published in: Technology, Business
  • Be the first to comment

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

Everything you ever wanted to know about lotus script

  1. 1. Everything you everwanted to know aboutLotuscriptBill BuchanhadslThursday, 22 March 12
  2. 2. Who am I?• Bill Buchan, CEO of hadsl - one of thesponsors of this show• Come visit the booth - we don’t bite• Dual PCLP in v3, v4, v5, v6, v7, v8, and v8.5• Enterprise-level consultant on Dominosince 1995Thursday, 22 March 12
  3. 3. Agenda• What is LotusScript? Where is it going?• LotusScript Basics• LotusScript Advanced• Web ServicesThursday, 22 March 12
  4. 4. What is LotusScript• LotusScript is:• A p-code partially compiled, partiallyinterpreted language• Syntactically identical toVisual Basic 3• In most Notes Applications.Thursday, 22 March 12
  5. 5. What is LotusScript• LotusScript• is old. It was introduced with Notes v4,and was first implemented in Ami Pro• Supports Object Orientated techniques• Is fast, scalable, robust• Is Multi-PlatformThursday, 22 March 12
  6. 6. Where is it going?• Number of LotusSphere 2012 sessions thatmentioned LotusScript: one• No language modifications since Notes v4.6• (Every version has had class extensionsto support some new version features)• Its fair to say that it is not considered apriority for LotusThursday, 22 March 12
  7. 7. So why are we here?• I wanted to give you a single session thatcovered everything I knew aboutLotusScript• We still have to maintain applicationsThursday, 22 March 12
  8. 8. Agenda• What is LotusScript? Where is it going?• LotusScript Basics• LotusScript Advanced• Web ServicesThursday, 22 March 12
  9. 9. Basics: How to code• Code for maintenance.• You will change this code.This code willrun for 10+ years. Unchanged.• Log everything.• If the users find out before you, you’velost.• Good log information means fasterdebuggingThursday, 22 March 12
  10. 10. Basics: How to code• Bugs cost money.The closer to production,the more expensive they are. More testingand debugging and logging costs less• Isolate business logic from display logic.Your look and feel WILL change• Simplicity is cheapThursday, 22 March 12
  11. 11. Basics: Option Declare• You should use ‘Option Declare’ whenpossible.Why?• Not using Option declare, and notdeclaring your variables in advance,makes every variable aVARIANT• Variants move all errors to run-time• Variants are slower to use.Thursday, 22 March 12
  12. 12. Basics: lsi_info• LSI_Info was a student intern project, and isa global variable created and maintained bythe LotusScript environment• It contains lots of ‘interesting’ values• Superseded by getThreadInfo• Its not thread-safe. Heavily loaded serversmay crash if its accessed.Thursday, 22 March 12
  13. 13. Basics: lsi_info• lsi_info(10) gives the calling class• lsi_info(11) gives the calling function.• So we can write a pretty cool errorhandler..Thursday, 22 March 12
  14. 14. Function RaiseError()Dim thisType As String Dim es as StringthisType = Typename(Me) Not a class, use the calling module insteadIf (thisType = "") Then thisType = Getthreadinfo(11)es = thisType & "::" & Getthreadinfo(10) & ": "If (Err = 0) Thenes = es + "Manually raised an error"Elsees = es + "Run time error: (" + Trim(Str(Err)) + ") "+ _Error$ + " at line: "+ Trim(Str(Erl)) End IfPrint esend function calling code...ExitFunction:exit functionerrorhandler:Call RaiseError()resume exitFunctionend functionThursday, 22 March 12
  15. 15. Basics. NotesSession• This piece of code:dim s as new NotesSession• Doesn’t actually create anything. It justreferences the same global NotesSessionobject, built in advance• No performance hit for declaring it(But that doesn’t excuse bad code!)Thursday, 22 March 12
  16. 16. Basics:AdminP• AdminP documents havespecial fields for ReplicaID• Stored as Notes Date/Time fields Dim dt As New NotesDateTime(targetDatabase.ReplicaID) Call doc.replaceItemValue("ProxyReplicaID", dt)Thursday, 22 March 12
  17. 17. Basics:AdminPThursday, 22 March 12
  18. 18. Basics: Performance• A crude agent profile mechanism wasintroduced in Notes 7• You enable it from the agent/web serviceproperties pane:Thursday, 22 March 12
  19. 19. Basics: PerformanceThursday, 22 March 12
  20. 20. Basics: Lists• A list is acollectionof values,which hasa fixedlookupvaluedim Surnames list as StringSurnames(“Bill”) = “Buchan”Surnames(“Paul”) = “Mooney”Surnames(“Chris”) = “Coates”Print “Bill’s surname is: “ + Surnames(“Bill”)if (isElement(Surnames(“Charlie”))) thenPrint “Charlies Surname is: “ + Surnames(“Charlie”)elsePrint “I can’t find a surname for Charlie”end ifforall thisName in SurnamesPrint listtag(thisName) + “ “ + thisNameend forallerase Surnames(“Buchan”)Thursday, 22 March 12
  21. 21. Basics: Lists• So lists can collect together similar valuesin an ordered way• Lists have no real overhead• Lists can contain millions of items• Lists are very fastThursday, 22 March 12
  22. 22. Basics: Lists• You cannot read and write Lists directlyfrom Documents• Convert into a array first, and store as amulti-value• You have to iterate a list to see how manyitems it contains• Lists can only store values of the same typeThursday, 22 March 12
  23. 23. Agenda• What is LotusScript? Where is it going?• LotusScript Basics• LotusScript Advanced• Web ServicesThursday, 22 March 12
  24. 24. Advanced: Classes• LotusScript allows you to define classes:• Classes allow you to bundle variables andcode together in reusable objects• Classes can inherit from other classes (butnot the ‘notes*’ classes)• Classes can help build complex systemsquickly and easilyThursday, 22 March 12
  25. 25. Advanced: Classes• Example class: define ‘Person’class Personpublic personName as NotesNamepublic UNID as String ‘ UNID to doc in NABsub new(doc as NotesDocument)set personName = new NotesName( _doc.getItemValue(“FullName”)(0) )set UNID = doc.UniversalIDend subend classThursday, 22 March 12
  26. 26. Advanced: Classesdim P as new Person(personDoc)print “Person: “ + P.personName.Common + _has document ID: “ + P.UNID• Example class: Using ‘Person’ classThursday, 22 March 12
  27. 27. • Create another class that encapsulates‘Person’class Peoplepublic people list as Personpublic count as longsub new(nabView as NotesView)dim doc as NotesDocumentset doc = nabView.getFirstDocument()while not doc is nothingdim P as new Person(doc)set people(P.personName.Abbreviated) = Pcount = count + 1set doc = nabView.getNextDocument(doc)wendend subend classThursday, 22 March 12
  28. 28. Advanced: Classes• Using ‘People’dim folks as new People(nabView)forall thisPerson in folks.peopleprint “Person: “ + thisPerson.personName.Common + _has document ID: “ + thisPerson.UNIDend forallThursday, 22 March 12
  29. 29. Advanced: Classes• Lets add logging functionality to theseclasses by creating a new ‘layer’.Class logsub new()end subpublic sub logMsg(msg as String)print msgend subend classThursday, 22 March 12
  30. 30. class Person as logpublic personName as NotesNamepublic UNID as String ‘ UNID to doc in NABsub new(doc as NotesDocument)set personName = new NotesName( _doc.getItemValue(“FullName”)(0) )set UNID = doc.UniversalIDlogMsg(“created new person: “ + P.personName.Common)end subend class• We can ‘inherit’ ALL functionality from ‘log’by creating ‘Person’ as a subclass of log.Advanced: ClassesThursday, 22 March 12
  31. 31. Advanced: Classes• You can only ‘inherit’ from one class at atime (other languages have mechanisms formore)• Every class you inherit from gets to run itsconstructor in the sequence you definedinheritance• This allows you to quickly segment largeproblems and delegate workThursday, 22 March 12
  32. 32. Advanced: Calling C-API• Not all Lotus Notes API calls are defined inLotusScript. Sometimes you want toexecute these.• You can define ANY library/DLL function inLotusScript and call it• Its dangerous...Thursday, 22 March 12
  33. 33. • You have to define EXACTLY the functionusing the correct sized primitive variabletypes (such as integer, etc)• If you get any part of it wrong, you willcrash the client. Badly.• Its Platform-specific. So you have to rewritethis for every single platform you supportAdvanced: Calling C-APIThursday, 22 March 12
  34. 34. • Example: NSFGetServerLatency• Find out how many milliseconds it takes toping a Domino server.• Defined as:Advanced: Calling C-APISTATUS LNPUBLIC NSFGetServerLatency(char far *ServerName,DWORD Timeout,DWORD far *retClientToServerMS,DWORD far *retServerToClientMS,WORD far *ServerVersion);Thursday, 22 March 12
  35. 35. • We can define this in LotusScript using:Advanced: Calling C-API This is a constant for our windows-based Library file:Const LIB_W32 = "nnotes.dll" Declare our function for windowsDeclare Function W32_NSFGetServerLatency _Lib LIB_W32 Alias {NSFGetServerLatency} (_Byval ServerName As Lmbcs String, _Byval Timeout As Long, _retClientToServerMS As Long, _retServerToClientMS As Long, _ServerVersion As Integer) As IntegerThursday, 22 March 12
  36. 36. • And we can use this (on a 32-bit windowsclient or server at least) by:Advanced: Calling C-API A function to get network latency time...Public Function getServerLatency (strServer As String) As LongDim nnServer As New NotesName(strServer)Dim ToServer As Long, fromServer As LongDim ver As IntegerDim timeout As Longtimeout = 1000 1000ms == 1 secondCall W32_NSFGetServerLatency(nnServer.Canonical,_timeout, toServer, fromServer, ver) Return both directional latencies added togethergetServerLatency = fromServer + ToServerEnd FunctionThursday, 22 March 12
  37. 37. • C-API can get to functionality that wouldbe impossible to implement in LotusScriptalone• It requires FAR more testing than anythingelse - use it as a last resort• Good reference: http://www.ls2capi.comAdvanced: Calling C-APIThursday, 22 March 12
  38. 38. Advanced: Execute• ‘Evaluate’ in LotusScript allows you to evaluate@Formula language:myString = Evaluate(|@Unique|)• Execute allows you to execute LotusScriptcode• You can write code that writes codeThursday, 22 March 12
  39. 39. Advanced: ExecuteDim executeString as StringexecuteString = |print “Hello world”dim s as new NotesSessiondim db as NotesDatabaseset db = s.currentDatabaseprint “Current Database name is: “ + db.Title|execute (executeString)• ExampleThursday, 22 March 12
  40. 40. Advanced: Execute• I use it to dynamically calculate C-APIfunction signatures• http://www.hadsl.com/HADSL.nsf/Documents/LS2CAPI+-+Calling+Notes+C-API+from+LotusScript• It can also be used for evil...Thursday, 22 March 12
  41. 41. Advanced:TriggerHappy• Imagine we wish to profile ALL our agentsin ALL our databases,ALL the time.• We could monitor each database to seewhen a profile document with form name$BEProfileR7 is saved• Save it in a central database...Thursday, 22 March 12
  42. 42. Advanced:TriggerHappy• Damien Katz (now of CouchDb, ex-Iris)wrote a server addin called ‘TriggerHappy’,available on OpenNtf.• It allows you to define lotusscript whichgets executed on ANY database event at aserver level.• RunningWithScissors++Thursday, 22 March 12
  43. 43. Advanced:TriggerHappy• Its detailed (with some code) on my blogat:• http://www.billbuchan.com/imported-20091119232548/2010/2/2/universal-agent-profiling-in-domino.html• We ran it in our TEST environment formonths without issue• It also tracked Web services as well asLotusScript and Domino agentsThursday, 22 March 12
  44. 44. Agenda• What is LotusScript? Where is it going?• LotusScript Basics• LotusScript Advanced• Web ServicesThursday, 22 March 12
  45. 45. Web Services: Introduction• Web services are a language and platformindependent way of wiring applicationstogether• Fundamentally they’re usually web servicehttp calls passing back and forth XMLencoded informationThursday, 22 March 12
  46. 46. • Lotus Domino 7 (now out of support!)provided a simple lotusscript based Webservices provider• Lotus Domino nd8 provides a consumerand a providerWeb Services: IntroductionThursday, 22 March 12
  47. 47. Web Services:Experience• They’re fast. 10+ calls per second. Muchfaster than I expected• But if you want performance, implementxPages REST based web serviceproviders - 5x faster• Reliable• Look and feel like an agentThursday, 22 March 12
  48. 48. Web Services: Example• A single function that returns a single stringThursday, 22 March 12
  49. 49. Web Services:Testing• Download SoapUi from http://www.soapui.orgThursday, 22 March 12
  50. 50. Web Services:Authentication• Two general types of DominoAuthentication:• Session based - uses cookies back andforth• Username and Password based -username and password is sent with eachtransactionThursday, 22 March 12
  51. 51. • Client Example:• We use Flex as a client• It automatically inherits cookies from theweb page its launched from• Launch it from an Authenticated page• Keep the session active by pinging every10 minutesWeb Services:AuthenticationThursday, 22 March 12
  52. 52. • Server Example:• We use a windows-based service toperform work• We encrypt a username/password pair inthe registry, and use username/passwordauthentication• It wakens up every 5 minutes and callshomeWeb Services:AuthenticationThursday, 22 March 12
  53. 53. Web Services: Complex• You can pass back simple types. Or classes.• Lotuscript limitation - you cannot return anarray• So how can I return an array?Thursday, 22 March 12
  54. 54. • Define a class which contains an ArrayWeb Services: ComplexThursday, 22 March 12
  55. 55. SoapUI says...Thursday, 22 March 12
  56. 56. Web Services:Thoughts• Web service clients are not under yourcontrol• Decide how complicated your client canhandle• More granular == more likely to change• Choose wiselyThursday, 22 March 12
  57. 57. Resources• The LS to C-API programming manual• http://www.ls2capi• Calling C-API from LotusScript resource:• http://www.hadsl.com/HADSL.nsf/Documents/LS2CAPI+-+Calling+Notes+C-API+from+LotusScript• Steve McConnell, Code Complete 2 (MSPress, 2004).• http://www.amazon.com/gp/product/0735619670Thursday, 22 March 12
  58. 58. The End?• This presentation, like all my others, isavailable at• http://www.hadsl.comThursday, 22 March 12