SlideShare une entreprise Scribd logo
1  sur  61
Télécharger pour lire hors ligne
Leveraging
LotusScript for
Database
Connectivity

Bill Buchan
HADSL
          © 2007 Wellesley Information Services. All rights reserved.
Why Are We Here?
•   What is the target audience?
       Lotus Notes developers who use server-based agents
•   What is this talk about?
       Lotus Notes is often perceived as a data “silo” …
          Difficult to get data into
          And difficult to get data out of
       … this is not the case
       This presentation explores a multitude of ways of interfacing
        Notes databases with enterprise relational databases




                                                              2
Who Am I?
•   Bill Buchan
•   Dual Principal Certified Lotus Professional (PCLP) in v3,
    v4, v5, v6, v7
•   10+ years senior development for Enterprise customers
       Learn from my pain!
•   5+ years code auditing
•   CEO of HADSL
       Developing best-practice tools




                                                      3
What We’ll Cover …
•   Overview
•   LSX
•   LS:DO
•   DCR
•   Wrap-up




                     4
Overview
•   This session:
       Is mostly about code
       Lots of take-home code examples
       Is a deep-dive in terms of theory




                                            5
Connections: Overview
•   “Lotus Notes cannot share its data with other
    databases”
       Absolutely not
       Support for this dates back over 10 years!
•   Multiple methods
       This presentation leads you through some of the more
        popular ones
       Highlights the pros and cons of each




                                                           6
Connections: Overview (cont.)
                           LSX    LS:DO   DCR   JNDI/XML
Performance                High    Low    Med     High
ODBC Connection Required   No      Yes    Yes        No
Native Client Required     Yes     No     No         Yes
Platform Independent       Yes     Yes    Yes        Yes
LotusScript Only           Yes     Yes    Yes        No
Supported                  Yes     No     Yes        Yes
Runs on Client             Yes     Yes    Yes        Yes
Runs on Server             Yes     Yes    No         Yes

                                                 7
Tips: General
•   In all of these examples, I shall hard-code user names
    and passwords for simplicity
       This is NOT a good production best practice!
       Use encryption keys, profile documents, etc., to soft-code
        these in production
•   Any attempt by LotusScript to access data outside the
    current database may result in error
       Error handling is therefore mandatory
       Logging of scheduled agents is mandatory




                                                              8
What We’ll Cover …
•   Overview
•   LSX
•   LS:DO
•   DCR
•   Wrap-up




                     9
Overview: LSX
•   LotusScript-based
       Such a small learning curve
•   Relies on native client support
       So you have to install your database client and/or drivers
•   Is fast
       This doesn’t have to use ODBC
          But ODBC is used for MS SQL and Access
          Remember, ODBC v2 doesn’t like Unicode
       This technology is used in the Lotus Enterprise Integrator
          Formerly “Notespump”
       Good for bulk transfer-style applications


                                                              10
Methodology
•   We shall attempt to:
       Test this against a local Access database using ODBC
       Test this against an Oracle database
•   Our data looks like:




•   And for Access, we need an ODBC connection




                                                           11
Demo: Read Table to Log
•   Let’s get a feel for what we are doing
•   In this demonstration, we will:
       Connect, using ODBC, to an Access database
       Collect all records in a CUSTOMERS table
       Pull ALL fields from all records
       Write all this information to a Notes log




                                                     12
Demo




            Demo

       Read Table to Log




                           13
Architecture Design Goals
•   When we write LSX applications, we should:
       Write as little code as possible
       Create comprehensive error handling
       Create logs of both success and failure
       Try not to hard-code the database structure
       Try and reuse and componentize
          After all, we might change databases later!
       Ensure that our top-level logic is:
          Focused on the business rules for data transfer
          Is maintainable
              After all, this will change!




                                                             14
Architecture Design Overview
•   In order to access data, we must:
       Connect to the database provider
          And then connect to the data itself

•   Object-oriented LotusScript lends itself to this model
       We shall create a:
          baseClass: This handles logging
          baseConnectionClass: This handles the connection to the
           data source
          baseConnection<DB>Class: These are database-specific
           classes
          Operation classes
              These should NOT be database specific



                                                           15
Architecture Design Results
•   This means that we separate:
       Logging
       Basic connection
       Operation
•   Thus, reusing lots of code
•   All database-specific code is held in a single library
       Can be easily “swapped” for another
       Platform and database differences can exist during our
        operations
          Test on the platform, version, and database that you will
           implement on



                                                              16
Class Inheritance and Code Use

Logic for Connection                BaseClass           Logging, Error Handling
        Code


            BaseConnectionClass

                                                  ReadTableClass



                       BaseConnectionODBCClass
                                                                   Operations Class

BaseConnectionOracleClass          ODBC-Specific Code



 Oracle-Specific Code                                       Example agent uses a
                                                              specific database
                                                            connection and one or
                                                             more helper function
                                                                   classes

                                     Agent

                                                                                  17
Connecting to Oracle
•   Now, let’s try connecting to Oracle
       We need to:
          Install the Oracle client
          Connect it to the Oracle database server




                                                      18
Some Oracle Tips
•   Setting up an Oracle server is not trivial
       Oracle is an enterprise-strength database system
       As big, complex, and difficult as a dozen mother-in-laws
          So give yourself time!
•   Some tips:
       The Connection string in Oracle looks like:
          CUSTOMERS_oracle02.marykirk.local
       This is:
          The name of the application — in our case “Customers”
          And then the network host address
               Either as a Domain Name System (DNS) host address
                or as an Internet Protocol (IP) address



                                                             19
More Oracle Tips
•   Try to use some Oracle tools to validate that you have:
       A proper connection
       Sufficient access to the application
       Sufficient access to the tables
•   Remember, you can use DCR to validate connections




                                                     20
Network Architecture
•   If you run Lotus Connector (LC) LSX code on the server:
       The server must have:
          A connection to Oracle
          The Oracle Client software drivers

•   If you run LC LSX code on the Notes client:
       The client must have:
          A connection to Oracle
          The Oracle Client software

•   Installing Oracle Client on all workstations is not trivial!
       Consider using LC LSX on the servers only




                                                         21
The Base Class
•   Our base class       Class baseClass

    contains all            ‘ returns true if this class is valid
    “Infrastructure”        Public Property Get Valid As Boolean

    support, such as:       ‘ Our constructor. Sets up logging
       Logging             Sub new()

       Error trapping      ‘ Class destructor ensures proper closure of Log
                            Sub delete()


                            ‘ Log a message
                            Public Function logEvent(msg As String) As Integer

                            ‘ Handle run-time errors
                            Private Function raiseError() As String
                         End Class



                                                                      22
Class baseConnectorClass
' This class extends our BaseClass and adds the capability to open and close a connection
' Note that this is never used directly – and is overridden by our database-specific classes.
‘ This provides the business logic framework for our database specific connection classes
Class baseConnectorClass As BaseClass

    ‘ Expose some properties
    Private Function getServer As String
    Private Function getUserName As String
    Private Function getPassword As String
    Private Function getTable As String
    Public Function getSession As LCSession
    Public Function getConnection As LCConnection

    ' The base constructor for this class. Note that it doesnt actually
    ' do any connection work - it just sets up the base variables
    Sub new(srv As String, un As String, pw As String, tb As String), baseClass()

    ‘ And the destructor. This ensures that the connection object is closed
    Sub delete()
End Class



                                                                                            23
Class baseODBCConnectorClass
•   All of our business logic is held in baseConnectorClass
        We need to put the database-specific code in only this class
        In this case, it is all implemented in the constructor
•   If we change the business logic later on:
        We have to change only baseConnectorClass


    ' This class extends our BaseConnectorClass and adds the
    ‘ capabilty to open and close an ODBC Connection
    Class baseODBCConnectorClass As BaseConnectorClass

       ‘ Supply a new constructor for this class
       Sub new(srv As String, un As String, pw As String, tb As String)
    End sub




                                                                          24
Insulating Database Connections from Business Logic
  •   One main goal is to insulate our database-specific
      connection information from our business logic
          It makes it easier to switch databases in the future, if
           necessary
  •   In this database, I hold all database-specific information
      in a profile document
Set docProfile = dbThis.GetProfileDocument("Profile")

Dim Connection As Variant

Select Case docProfile.Database(0)
Case "ODBC"
    Set connection = New baseODBCConnectorClass _
    (docProfile.System(0), "", "", "")
Case "Oracle"
    Set connection = New baseOracleConnectorClass _
    (docProfile.System(0), docProfile.UserName(0), docProfile.Password(0), docProfile.MetaData(0))
End Select
                                                                                     25
Class fieldClass
•   fieldClass                    Class FieldClass

       Helps us define which        ‘ Our two members – a name and a field
        fields we want returned      Public FieldName As String
        from our data object         Public Field As LCField

       Used to extract data         ‘ get the value of this field
                                     Property Get Value As Variant

                                     ‘ Construct this field class
                                     Sub new(fName As String, F As LCField)

                                  End Class




                                                                 26
Class baseODBCConnectorClass — Constructor
•   This pseudo-code           Set Me.lc_Session = New LCSession()

    shows the steps            If ( Me.lc_Session.Status <> LCSUCCESS ) Then

    towards connecting               ‘ Bale out of the function…


    to our LC LSX              ‘ Check to see that the odbc2 LSX Support is available.
                               If (lc_Session.LookupConnector ("odbc2")) Then
    target data server               …

•   Differences from an        ‘ Now set up our Connection

    ODBC connection            Set me.lc_Connection = New LCConnection ( "odbc2" )


       The connection token   ‘ Set up our data source name
                               Me.lc_Connection.Server = Me.getServer()
        is “oracle8”
       The username and       ‘ And finally connect
                               Me.lc_Connection.Connect
        password are
        specified              ‘ Check to see that the connection has worked
                               If (Me.lc_Connection.isConnected = False) Then
                                    …


                                                                          27
ReadTableClass
•   ReadTableClass                     Class ReadTableClass As baseClass

       Allows us to read the result      ‘ Our constructor. Pass in our
        of an SQL Query                   ‘ database connection object
                                          Sub new(newConn As Variant)
       Returns each table row as a
        LIST of FieldClass items          ' set up our read operation
                                          ‘ by passing in an SQL statemement
                                          Public Function getRecords( _
                                               strSelection As String) As Long

                                          ‘ Call this till it returns false, return
                                          ‘ each row of the table as a list
                                          ‘ of resulting fields
                                          Public Function getNextRecord( _
                                                index As Long, returnedFields _
                                                List As FieldClass) As Integer

                                       End Class


                                                                         28
Using ReadTableClass
•   Our controlling code          ‘ set up our database connection
                                  Set connection = New _
       Set up a database             baseODBCConnectorClass( _
        connection                    “CUSTOMERS”, "", "", "")



       Create a ReadTableClass   ‘ set up our ReadTableClass object
                                  Dim rc As New ReadTableClass(connection)
        object
                                  ‘ Check to see its valid
       Check to see whether      If Not rc.Valid Then
        it’s valid                    …

                                  ‘ Do our SQL thing
       Run some SQL              If (rc.getRecords( _
                                       "SELECT * from CUSTOMERS")) Then

       Process the results          While rc.getNextRecord(index, returnedValues)
                                          …



                                                                      29
Processing the Results from ReadTableClass
•   It’s a case of:                             ------------------ New Record retrieved ----------
                                                ID                        1
        Retrieving each ROW of data            Name                      Lotus
                                                Contact                   Mike R.hodin
        Iterating through the LIST of          Address                   Lotus House
         fieldClass items and                   City
                                                State
                                                                          Westford
                                                                          MA
         processing them                        ZIP                       90210
                                                Country                   USA
•   Agent “Read Tables to Log”                  dateFirstContact          01/01/1990 00:00:00
                                                CreditLimit               5000000.0000
    just prints them                            Employees                 1000
                                                …



Forall thisF In returnedValues
   Call rc.logEvent(" " + thisF.fieldName + Space(30-Len(thisF.fieldName)) + _
         Chr(9) +" [" + Cstr(thisF.Field.DataType) + "]" + Chr(9) + _
         Implode(thisF.Field.Text, ", "))
End Forall


                                                                                      30
Demo: Read Table to Documents
•   Let’s use the same underlying code:
       Synchronize this information with Notes data
          Use the ID field to match up SQL entries with Notes entries
          For simplicity, we shall just overwrite the Notes data with
           the SQL data
       Note we are not requesting specific fields
          We write ALL field information to a Notes database
          We use the same field name in SQL and Notes
              This might not be good in production
              Consider pre-fixing the Notes field names to avoid
               name collisions



                                                             31
Demo




          Demo

         Read Table
       to Documents




                      32
Let’s Write to SQL
•   In this case, we need to define which fields we shall
    update
       This information is used to define:
          The SQL target field
          Which field in Notes we pull data from
          The data type
               This had better match the SQL data type!
       Again, we want the operations class to do all the hard work!




                                                              33
insertTablesClass
•   Our class allows us to:         Class InsertTableClass As baseClass

       Define a series of field        ' Our constructor. Pass in the Connector.
        names we shall write            Sub new(newConn As Variant)

        data to                         ' Call this for each field we wish to append,
       Pass a variant array of         ‘ passing in a name and a type
                                        Public Function appendField( _
        values (in the same order            fieldName As String, fieldType As Long) _
        as our fields were                   As Integer

        appended)                       ' Commit to inserting these records.
•   This is still pretty hard           ' This returns the number of records successfully
                                        ‘ inserted, NOT true or false.
    work                                Public Function insertRecord( _
                                              values() As Variant) As Integer
       We have to track all
        fields, etc.                End Class




                                                                          34
insertFieldClass
•   insertFieldClass              Class insertFieldClass
                                      ‘ Our constructor. Pass in our InsertTableClass
       Helps define the              Sub new(newIT As Variant)

        fields, field types,          ‘ Append a field name and an LSX field type
        and values to                 Public Function appendField( _
        transfer from the                  strName As String, Ltype As Long) As Integer

        Notes document to             ‘ Call this once you have set all your field names
        the SQL table                 Public Function setUpFields() As Integer

       For simplicity, in this       ' Using our fieldList, save the field values
        code instance we are          ‘ from this document to to our InsertTableClass
                                      Public Function saveFieldsFromDocument( _
        assuming that the                  doc As NotesDocument) As Integer
        field names are
        identical in Notes        End Class

        and SQL


                                                                                35
insertTableClass and insertFieldClass Usage
•   Define a new               ‘ Create a new InsertTable Class
    InsertTableClass           Dim it As New InsertTableClass(Connection)



                               ‘ And create a InsertFieldClass, associating
•   Define a new               ‘ it with our table Class.
    InsertFieldClass           Dim ic As New InsertFieldClass(IT)

                               ‘ Define the fields
                               Call ic.appendField("ID",       LCTYPE_NUMERIC)
•   Define our fields          Call ic.appendField("Name",     LCTYPE_TEXT)
                                    …

                               ‘ And “freeze” it there.
                               Call ic. setUpFields()
•   Freeze the definition
                               ‘ And for one or more Documents, push the
                               ‘ Data across.
•   Push the data                   Call ic.saveFieldsFromDocument(doc)




                                                                         36
Demo




         Demo

       Insert Rows
         into SQL




                     37
Performance
•   Creating LCField items is expensive
       We define our LCFields before inserting data
       Instead of creating new LCField items within the loop for
        each iteration, we create them ONCE outside the loop and
        reuse them
       Adds slightly to the complexity
       Hence the requirement for insertFieldsClass




                                                             38
What We’ll Cover …
•   Overview
•   LSX
•   LS:DO
•   DCR
•   Wrap-up




                     39
Introducing LotusScript Data Object (LS:DO)
•   LS:DO was the first data interface
       And is reportedly no longer supported
       You may find some code that still relies on this
•   LS:DO uses ODBC v2 drivers to access data
       You cannot access Unicode data
          This was introduced in ODBC v3.5
       The client must have an ODBC definition for the target data
        source on his machine, if you are running client-based code
•   Let’s dive straight into a demo …




                                                             40
Demo




         Demo

       Read Table
       Definition




                    41
Using LS:DO
•   Create a new connection              Const SQL_TABLE = "CUSTOMERS"
                                         Const SQL_QUERY =
                                            "SELECT * FROM CUSTOMERS"

•   Create a query and link it to our    Set Connection = New ODBCConnection
    connection                           Connection.ConnectTo(SQL_TABLE)

                                         If Not Connection.IsConnected Then
•   Create a result set and connect it       …

    to our query                         Dim Query As New ODBCQuery
                                         Set Query.Connection = Connection

•   Set the SQL query                    Dim Result As New ODBCResultSet
                                         Set Result.Query = Query

•   Execute the query                    Query.SQL = SQL_QUERY

                                         Result.Execute


                                                                   42
LS:DO Result Set Processing
•      The ODBCResultSet Object now contains all the results
           You can extract field information
           You can extract actual values
           This code extracts field name and size information
    If Not Result.IsResultSetAvailable Then
         Messagebox "I failed to get results from SQL Query: “ + _
          SQL_QUERY, 48, "Failed to get Results"
         Exit Sub
    End If

    Dim fields List As String
    Dim i As Integer
    For i = 1 To Result.NumColumns
         Print "Field: " + padString( result.FieldName(i), 30) + _
         "Size: " + padString(Cstr(Result.FieldSize(i)), 5)

        fields(result.FieldName(i)) = result.FieldName(i)
    Next

                                                                     43
LS:DO Result Set Processing (cont.)
•   To extract the result rows themselves, use:
       Result.getNextRow                                          ID
                                                                   Name
                                                                                        1
                                                                                        Lotus

       Result.IsEndOfData                                         Contact
                                                                   Address
                                                                                        Mike R.hodin
                                                                                        Lotus House
                                                                   City                 Westford
                                                                   State                MA
                                                                   ZIP                  90210
                                                                   Country              USA
                                                                   dateFirstContact     01/01/1990
                                                                   CreditLimit          5000000
                                                                   Employees            1000




         While Not result.IsEndOfData
             Forall thisField In fields
                 Print " " & padString( "" + thisField, 30 ) & Chr(9) & Result.GetValue(thisField)
             End Forall

            Call Result.NextRow()
         Wend




                                                                                        44
LS:DO Tips
•   LS:DO supports transaction processing
       You could — if your SQL data source allowed — switch on
        Transaction mode
          odbcConnection.IsSupported(DB_SUPP_TRANSACTIONS)
       You could then perform multiple updates
       Commit them all at once
          odbcConnection.CommitTransactions




                                                       45
LS:DO Summary
•   LS:DO was a fairly simple, robust ODBC connection
       You might have some code that relies on it
•   I would advise you to:
       Identify any code that relies on LS:DO
       Refactor that code to use LSX




                                                     46
What We’ll Cover …
•   Overview
•   LSX
•   LS:DO
•   DCR
•   Wrap-up




                     47
Introducing DCR
•   Data Connection Resources (DCR)
       New in Domino 6
       Allows you to perform real-time, user-based SQL database
        access
       Very useful for front-end applications
•   However:
       It requires constant access to the target database
       It requires Domino Enterprise Connection Services (DECS)
           Running on the server on which your application is hosted
       It pools all SQL database access via the DECS server




                                                             48
Create a New Shared Resource — Data Connection
•   Set a name and alias
•   Set the data connection type
•   Enter username and password, if required
•   Choose the data source
•   And choose the object
•   Use Browse metadata
    to validate the connection




                                                 49
Link the Data Source to Your Form
•   On the Form Properties — advanced tab, click Browse
       Choose the data connection and the metadata object




                                                             50
Link the Fields to the Data
•   On the field properties:
       Check “External data source”
       At the bottom, use the Browse
        button to select the data source,
        metadata
•   One field needs to be defined as
    the key field
•   Remember to check “Store data
    locally” if you want to see this
    data on views!



                                            51
DCR: What Would I Use It For?
•   Very useful for:
       Applications that are permanently connected
       Applications that require instant lookup of external data
•   You could use Notes information and …
       Perform lookups to populate the document
       Update status information on user request




                                                               52
Form Manipulation
•   Bear in mind that all this logic is held on the Form
    design element
       You could use one Form to populate/refresh data
       And allow users to work another Form
          Which just displays the data on the document




                                                          53
Demo: DCR
•   In this demo, I will:
       Demonstrate data being updated in Notes and pushed to SQL
       Demonstrate data being updated in SQL and pushed to Notes
       Show you the DCR common element, as well as the Field
        definition




                                                          54
Demo




        Demo

       DCR demo




                  55
What We’ll Cover …
•   Overview
•   LSX
•   LS:DO
•   DCR
•   Wrap-up




                     56
Resources
•   Constantin Florea, Notes and Domino Connectivity: A
    Collection of Examples (IBM Redpaper, March 2001).
       www.redbooks.ibm.com/redpapers/pdfs/redp0115.pdf
       Check out the abstract here:
          www.redbooks.ibm.com/abstracts/redp0115.html?Open

•   Brian Benz and Rocky Oliver, Lotus Notes and Domino 6
    Programming Bible (Wiley, 2003).
       www.amazon.com/gp/product/0764526111




                                                       57
Resources (cont.)
•   Object-Oriented LotusScript:
       www.hadsl.com/hadsl.nsf/Documents/Object+Orientated
        +Programming+in+LotusScript+(The+View)!OpenDocument
•   The Notes FAQ!
       www.keysolutions.com/NotesFAQ/
•   Notes.Net (of course)
       www.notes.net




                                                      58
7 Key Points to Take Home
•   Domino can easily interact with other data sources
•   LS:DO, whilst powerful and easy to use – is no longer
    supported
       Consider refactoring this
•   LSX performs bulk updates between Domino and other
    data sources
       Simple, fast, efficient
•   DCR allows real-time update in user context
       And centralizes data lookup via the server




                                                     59
7 Key Points to Take Home (cont.)
•   Consider that the target data source will change
•   Logging and error trapping
       Mandatory
       Ensure that you know of issues before your users
       Monitor this interface
•   This interface code will change often
       Write for maintainability!




                                                           60
Your Turn!




             How to contact me:
                Bill Buchan
              Bill@hadsl.com
                                  61

Contenu connexe

Tendances

RepreZen DSL: Pushing the limits of language usability with XText
RepreZen DSL: Pushing the limits of language usability with XTextRepreZen DSL: Pushing the limits of language usability with XText
RepreZen DSL: Pushing the limits of language usability with XText
Tatiana Tanya Fesenko
 
Dev buchan leveraging the notes c api
Dev buchan leveraging the notes c apiDev buchan leveraging the notes c api
Dev buchan leveraging the notes c api
Bill Buchan
 
ORM, JPA, & Hibernate Overview
ORM, JPA, & Hibernate OverviewORM, JPA, & Hibernate Overview
ORM, JPA, & Hibernate Overview
Brett Meyer
 
Hpts 2011 flexible_oltp
Hpts 2011 flexible_oltpHpts 2011 flexible_oltp
Hpts 2011 flexible_oltp
Jags Ramnarayan
 

Tendances (20)

RAPID - Building a highly usable API Design language with XText
RAPID - Building a highly usable API Design language with XTextRAPID - Building a highly usable API Design language with XText
RAPID - Building a highly usable API Design language with XText
 
RepreZen DSL: Pushing the limits of language usability with XText
RepreZen DSL: Pushing the limits of language usability with XTextRepreZen DSL: Pushing the limits of language usability with XText
RepreZen DSL: Pushing the limits of language usability with XText
 
Dev buchan leveraging the notes c api
Dev buchan leveraging the notes c apiDev buchan leveraging the notes c api
Dev buchan leveraging the notes c api
 
JavaScript Frameworks and Java EE – A Great Match
JavaScript Frameworks and Java EE – A Great MatchJavaScript Frameworks and Java EE – A Great Match
JavaScript Frameworks and Java EE – A Great Match
 
Performance tuning with zend framework
Performance tuning with zend frameworkPerformance tuning with zend framework
Performance tuning with zend framework
 
Django è pronto per l'Enterprise
Django è pronto per l'EnterpriseDjango è pronto per l'Enterprise
Django è pronto per l'Enterprise
 
Architectural Patterns and Software Architectures: Client-Server, Multi-Tier,...
Architectural Patterns and Software Architectures: Client-Server, Multi-Tier,...Architectural Patterns and Software Architectures: Client-Server, Multi-Tier,...
Architectural Patterns and Software Architectures: Client-Server, Multi-Tier,...
 
Hibernate performance tuning
Hibernate performance tuningHibernate performance tuning
Hibernate performance tuning
 
ORM, JPA, & Hibernate Overview
ORM, JPA, & Hibernate OverviewORM, JPA, & Hibernate Overview
ORM, JPA, & Hibernate Overview
 
SmartDB Office Hours: Connection Pool Sizing Concepts
SmartDB Office Hours: Connection Pool Sizing ConceptsSmartDB Office Hours: Connection Pool Sizing Concepts
SmartDB Office Hours: Connection Pool Sizing Concepts
 
Presenting Data – An Alternative to the View Control
Presenting Data – An Alternative to the View ControlPresenting Data – An Alternative to the View Control
Presenting Data – An Alternative to the View Control
 
Hibernate 3
Hibernate 3Hibernate 3
Hibernate 3
 
Browser tools that make web development easier
Browser tools that make web development easierBrowser tools that make web development easier
Browser tools that make web development easier
 
Move Your XPages Applications to the Fast Lane
Move Your XPages Applications to the Fast LaneMove Your XPages Applications to the Fast Lane
Move Your XPages Applications to the Fast Lane
 
SHOW104: Practical Java
SHOW104: Practical JavaSHOW104: Practical Java
SHOW104: Practical Java
 
Advance java1.1
Advance java1.1Advance java1.1
Advance java1.1
 
CloverETL and IBM Infosphere MDM partners and users
CloverETL and IBM Infosphere MDM partners and usersCloverETL and IBM Infosphere MDM partners and users
CloverETL and IBM Infosphere MDM partners and users
 
Hibernate ORM: Tips, Tricks, and Performance Techniques
Hibernate ORM: Tips, Tricks, and Performance TechniquesHibernate ORM: Tips, Tricks, and Performance Techniques
Hibernate ORM: Tips, Tricks, and Performance Techniques
 
Transformations: Smart Application Migration to XPages
Transformations: Smart Application Migration to XPagesTransformations: Smart Application Migration to XPages
Transformations: Smart Application Migration to XPages
 
Hpts 2011 flexible_oltp
Hpts 2011 flexible_oltpHpts 2011 flexible_oltp
Hpts 2011 flexible_oltp
 

En vedette

The View - 30 proven Lotuscript tips
The View - 30 proven Lotuscript tipsThe View - 30 proven Lotuscript tips
The View - 30 proven Lotuscript tips
Bill Buchan
 
Dev buchan best practices
Dev buchan best practicesDev buchan best practices
Dev buchan best practices
Bill Buchan
 

En vedette (11)

The View - 30 proven Lotuscript tips
The View - 30 proven Lotuscript tipsThe View - 30 proven Lotuscript tips
The View - 30 proven Lotuscript tips
 
Dev buchan best practices
Dev buchan best practicesDev buchan best practices
Dev buchan best practices
 
Wysoka Dostępność Windows Server 2008 w kontekscie umów SLA
Wysoka Dostępność Windows Server 2008 w kontekscie umów SLAWysoka Dostępność Windows Server 2008 w kontekscie umów SLA
Wysoka Dostępność Windows Server 2008 w kontekscie umów SLA
 
Umiem, potrafię, jestem...
Umiem, potrafię, jestem...Umiem, potrafię, jestem...
Umiem, potrafię, jestem...
 
Active directory - Klasa III (01.10.2015)
Active directory - Klasa III (01.10.2015)Active directory - Klasa III (01.10.2015)
Active directory - Klasa III (01.10.2015)
 
Uprawnienia W Sql Server 2005
Uprawnienia W Sql Server 2005Uprawnienia W Sql Server 2005
Uprawnienia W Sql Server 2005
 
Najlepszy w zawodzie
Najlepszy w zawodzie Najlepszy w zawodzie
Najlepszy w zawodzie
 
Konkurs fotograficzny - "Zrozumieć niepełnosprawność"
Konkurs fotograficzny - "Zrozumieć niepełnosprawność"Konkurs fotograficzny - "Zrozumieć niepełnosprawność"
Konkurs fotograficzny - "Zrozumieć niepełnosprawność"
 
Prezentacja SKISR
Prezentacja SKISRPrezentacja SKISR
Prezentacja SKISR
 
Certyfikaty od podszewki w oparciu o PKI w windows 2008 MTS 2011
Certyfikaty od podszewki w oparciu o PKI w windows 2008 MTS 2011Certyfikaty od podszewki w oparciu o PKI w windows 2008 MTS 2011
Certyfikaty od podszewki w oparciu o PKI w windows 2008 MTS 2011
 
Lata 40.
Lata 40.Lata 40.
Lata 40.
 

Similaire à The View - Leveraging Lotuscript for Database Connectivity

Dev buchan leveraging
Dev buchan leveragingDev buchan leveraging
Dev buchan leveraging
Bill Buchan
 
NoSQL and CouchDB: the view from MOO
NoSQL and CouchDB: the view from MOONoSQL and CouchDB: the view from MOO
NoSQL and CouchDB: the view from MOO
James Hollingworth
 
Dbms & prog lang
Dbms & prog langDbms & prog lang
Dbms & prog lang
Tech_MX
 

Similaire à The View - Leveraging Lotuscript for Database Connectivity (20)

Dev buchan leveraging
Dev buchan leveragingDev buchan leveraging
Dev buchan leveraging
 
Framing the Argument: How to Scale Faster with NoSQL
Framing the Argument: How to Scale Faster with NoSQLFraming the Argument: How to Scale Faster with NoSQL
Framing the Argument: How to Scale Faster with NoSQL
 
NoSQL and CouchDB: the view from MOO
NoSQL and CouchDB: the view from MOONoSQL and CouchDB: the view from MOO
NoSQL and CouchDB: the view from MOO
 
Building FoundationDB
Building FoundationDBBuilding FoundationDB
Building FoundationDB
 
SOA with Zend Framework
SOA with Zend FrameworkSOA with Zend Framework
SOA with Zend Framework
 
Introduction to Microservices with Docker and Kubernetes
Introduction to Microservices with Docker and KubernetesIntroduction to Microservices with Docker and Kubernetes
Introduction to Microservices with Docker and Kubernetes
 
DB2 and PHP in Depth on IBM i
DB2 and PHP in Depth on IBM iDB2 and PHP in Depth on IBM i
DB2 and PHP in Depth on IBM i
 
Dropping ACID: Wrapping Your Mind Around NoSQL Databases
Dropping ACID: Wrapping Your Mind Around NoSQL DatabasesDropping ACID: Wrapping Your Mind Around NoSQL Databases
Dropping ACID: Wrapping Your Mind Around NoSQL Databases
 
Exploiting NoSQL Like Never Before
Exploiting NoSQL Like Never BeforeExploiting NoSQL Like Never Before
Exploiting NoSQL Like Never Before
 
Software Architecture and Architectors: useless VS valuable
Software Architecture and Architectors: useless VS valuableSoftware Architecture and Architectors: useless VS valuable
Software Architecture and Architectors: useless VS valuable
 
Azure - Data Platform
Azure - Data PlatformAzure - Data Platform
Azure - Data Platform
 
Uklug 2014 connections dev faq
Uklug 2014  connections dev faqUklug 2014  connections dev faq
Uklug 2014 connections dev faq
 
java.pptx
java.pptxjava.pptx
java.pptx
 
Succeding with the Apache SOA stack
Succeding with the Apache SOA stackSucceding with the Apache SOA stack
Succeding with the Apache SOA stack
 
Virtualization and Containers
Virtualization and ContainersVirtualization and Containers
Virtualization and Containers
 
Migre sus bases de datos Oracle a la nube
Migre sus bases de datos Oracle a la nube Migre sus bases de datos Oracle a la nube
Migre sus bases de datos Oracle a la nube
 
Architectural Decisions: Smoothly and Consistently
Architectural Decisions: Smoothly and ConsistentlyArchitectural Decisions: Smoothly and Consistently
Architectural Decisions: Smoothly and Consistently
 
Architectural Decisions: Smoothly and Consistently
Architectural Decisions: Smoothly and ConsistentlyArchitectural Decisions: Smoothly and Consistently
Architectural Decisions: Smoothly and Consistently
 
Dbms & prog lang
Dbms & prog langDbms & prog lang
Dbms & prog lang
 
SQL Server: Now It's Everywhere You Want to Be
SQL Server: Now It's Everywhere You Want to BeSQL Server: Now It's Everywhere You Want to Be
SQL Server: Now It's Everywhere You Want to Be
 

Plus de Bill Buchan

Dev buchan leveraging the notes c api
Dev buchan leveraging the notes c apiDev buchan leveraging the notes c api
Dev buchan leveraging the notes c api
Bill Buchan
 
Dev buchan everything you need to know about agent design
Dev buchan everything you need to know about agent designDev buchan everything you need to know about agent design
Dev buchan everything you need to know about agent design
Bill Buchan
 
Dev buchan 30 proven tips
Dev buchan 30 proven tipsDev buchan 30 proven tips
Dev buchan 30 proven tips
Bill Buchan
 
Entwicker camp2007 calling-the-c-api-from-lotusscript
Entwicker camp2007 calling-the-c-api-from-lotusscriptEntwicker camp2007 calling-the-c-api-from-lotusscript
Entwicker camp2007 calling-the-c-api-from-lotusscript
Bill Buchan
 
Entwicker camp2007 blackberry-workshop
Entwicker camp2007 blackberry-workshopEntwicker camp2007 blackberry-workshop
Entwicker camp2007 blackberry-workshop
Bill Buchan
 
Admin2012 buchan web_services-v101
Admin2012 buchan web_services-v101Admin2012 buchan web_services-v101
Admin2012 buchan web_services-v101
Bill Buchan
 

Plus de Bill Buchan (20)

Dummies guide to WISPS
Dummies guide to WISPSDummies guide to WISPS
Dummies guide to WISPS
 
WISP for Dummies
WISP for DummiesWISP for Dummies
WISP for Dummies
 
WISP Worst Practices
WISP Worst PracticesWISP Worst Practices
WISP Worst Practices
 
Marykirk raft race presentation night 2014
Marykirk raft race presentation night 2014Marykirk raft race presentation night 2014
Marykirk raft race presentation night 2014
 
Dev buchan leveraging the notes c api
Dev buchan leveraging the notes c apiDev buchan leveraging the notes c api
Dev buchan leveraging the notes c api
 
Dev buchan everything you need to know about agent design
Dev buchan everything you need to know about agent designDev buchan everything you need to know about agent design
Dev buchan everything you need to know about agent design
 
Dev buchan 30 proven tips
Dev buchan 30 proven tipsDev buchan 30 proven tips
Dev buchan 30 proven tips
 
Entwicker camp2007 calling-the-c-api-from-lotusscript
Entwicker camp2007 calling-the-c-api-from-lotusscriptEntwicker camp2007 calling-the-c-api-from-lotusscript
Entwicker camp2007 calling-the-c-api-from-lotusscript
 
Entwicker camp2007 blackberry-workshop
Entwicker camp2007 blackberry-workshopEntwicker camp2007 blackberry-workshop
Entwicker camp2007 blackberry-workshop
 
Bp301
Bp301Bp301
Bp301
 
Ad507
Ad507Ad507
Ad507
 
Ad505 dev blast
Ad505 dev blastAd505 dev blast
Ad505 dev blast
 
Admin2012 buchan web_services-v101
Admin2012 buchan web_services-v101Admin2012 buchan web_services-v101
Admin2012 buchan web_services-v101
 
Reporting on your domino environment v1
Reporting on your domino environment v1Reporting on your domino environment v1
Reporting on your domino environment v1
 
12 Step Guide to Lotuscript
12 Step Guide to Lotuscript12 Step Guide to Lotuscript
12 Step Guide to Lotuscript
 
Everything you ever wanted to know about lotus script
Everything you ever wanted to know about lotus scriptEverything you ever wanted to know about lotus script
Everything you ever wanted to know about lotus script
 
Admin camp 2011-domino-sso-with-ad
Admin camp 2011-domino-sso-with-adAdmin camp 2011-domino-sso-with-ad
Admin camp 2011-domino-sso-with-ad
 
Softsphere 08 web services bootcamp
Softsphere 08 web services bootcampSoftsphere 08 web services bootcamp
Softsphere 08 web services bootcamp
 
Connections Lotusphere Worst Practices 2013
Connections Lotusphere Worst Practices 2013Connections Lotusphere Worst Practices 2013
Connections Lotusphere Worst Practices 2013
 
Lotusphere 2009 The 11 Commandments
Lotusphere 2009 The 11 CommandmentsLotusphere 2009 The 11 Commandments
Lotusphere 2009 The 11 Commandments
 

The View - Leveraging Lotuscript for Database Connectivity

  • 1. Leveraging LotusScript for Database Connectivity Bill Buchan HADSL © 2007 Wellesley Information Services. All rights reserved.
  • 2. Why Are We Here? • What is the target audience?  Lotus Notes developers who use server-based agents • What is this talk about?  Lotus Notes is often perceived as a data “silo” …  Difficult to get data into  And difficult to get data out of  … this is not the case  This presentation explores a multitude of ways of interfacing Notes databases with enterprise relational databases 2
  • 3. Who Am I? • Bill Buchan • Dual Principal Certified Lotus Professional (PCLP) in v3, v4, v5, v6, v7 • 10+ years senior development for Enterprise customers  Learn from my pain! • 5+ years code auditing • CEO of HADSL  Developing best-practice tools 3
  • 4. What We’ll Cover … • Overview • LSX • LS:DO • DCR • Wrap-up 4
  • 5. Overview • This session:  Is mostly about code  Lots of take-home code examples  Is a deep-dive in terms of theory 5
  • 6. Connections: Overview • “Lotus Notes cannot share its data with other databases”  Absolutely not  Support for this dates back over 10 years! • Multiple methods  This presentation leads you through some of the more popular ones  Highlights the pros and cons of each 6
  • 7. Connections: Overview (cont.) LSX LS:DO DCR JNDI/XML Performance High Low Med High ODBC Connection Required No Yes Yes No Native Client Required Yes No No Yes Platform Independent Yes Yes Yes Yes LotusScript Only Yes Yes Yes No Supported Yes No Yes Yes Runs on Client Yes Yes Yes Yes Runs on Server Yes Yes No Yes 7
  • 8. Tips: General • In all of these examples, I shall hard-code user names and passwords for simplicity  This is NOT a good production best practice!  Use encryption keys, profile documents, etc., to soft-code these in production • Any attempt by LotusScript to access data outside the current database may result in error  Error handling is therefore mandatory  Logging of scheduled agents is mandatory 8
  • 9. What We’ll Cover … • Overview • LSX • LS:DO • DCR • Wrap-up 9
  • 10. Overview: LSX • LotusScript-based  Such a small learning curve • Relies on native client support  So you have to install your database client and/or drivers • Is fast  This doesn’t have to use ODBC  But ODBC is used for MS SQL and Access  Remember, ODBC v2 doesn’t like Unicode  This technology is used in the Lotus Enterprise Integrator  Formerly “Notespump”  Good for bulk transfer-style applications 10
  • 11. Methodology • We shall attempt to:  Test this against a local Access database using ODBC  Test this against an Oracle database • Our data looks like: • And for Access, we need an ODBC connection 11
  • 12. Demo: Read Table to Log • Let’s get a feel for what we are doing • In this demonstration, we will:  Connect, using ODBC, to an Access database  Collect all records in a CUSTOMERS table  Pull ALL fields from all records  Write all this information to a Notes log 12
  • 13. Demo Demo Read Table to Log 13
  • 14. Architecture Design Goals • When we write LSX applications, we should:  Write as little code as possible  Create comprehensive error handling  Create logs of both success and failure  Try not to hard-code the database structure  Try and reuse and componentize  After all, we might change databases later!  Ensure that our top-level logic is:  Focused on the business rules for data transfer  Is maintainable  After all, this will change! 14
  • 15. Architecture Design Overview • In order to access data, we must:  Connect to the database provider  And then connect to the data itself • Object-oriented LotusScript lends itself to this model  We shall create a:  baseClass: This handles logging  baseConnectionClass: This handles the connection to the data source  baseConnection<DB>Class: These are database-specific classes  Operation classes  These should NOT be database specific 15
  • 16. Architecture Design Results • This means that we separate:  Logging  Basic connection  Operation • Thus, reusing lots of code • All database-specific code is held in a single library  Can be easily “swapped” for another  Platform and database differences can exist during our operations  Test on the platform, version, and database that you will implement on 16
  • 17. Class Inheritance and Code Use Logic for Connection BaseClass Logging, Error Handling Code BaseConnectionClass ReadTableClass BaseConnectionODBCClass Operations Class BaseConnectionOracleClass ODBC-Specific Code Oracle-Specific Code Example agent uses a specific database connection and one or more helper function classes Agent 17
  • 18. Connecting to Oracle • Now, let’s try connecting to Oracle  We need to:  Install the Oracle client  Connect it to the Oracle database server 18
  • 19. Some Oracle Tips • Setting up an Oracle server is not trivial  Oracle is an enterprise-strength database system  As big, complex, and difficult as a dozen mother-in-laws  So give yourself time! • Some tips:  The Connection string in Oracle looks like:  CUSTOMERS_oracle02.marykirk.local  This is:  The name of the application — in our case “Customers”  And then the network host address  Either as a Domain Name System (DNS) host address or as an Internet Protocol (IP) address 19
  • 20. More Oracle Tips • Try to use some Oracle tools to validate that you have:  A proper connection  Sufficient access to the application  Sufficient access to the tables • Remember, you can use DCR to validate connections 20
  • 21. Network Architecture • If you run Lotus Connector (LC) LSX code on the server:  The server must have:  A connection to Oracle  The Oracle Client software drivers • If you run LC LSX code on the Notes client:  The client must have:  A connection to Oracle  The Oracle Client software • Installing Oracle Client on all workstations is not trivial!  Consider using LC LSX on the servers only 21
  • 22. The Base Class • Our base class Class baseClass contains all ‘ returns true if this class is valid “Infrastructure” Public Property Get Valid As Boolean support, such as: ‘ Our constructor. Sets up logging  Logging Sub new()  Error trapping ‘ Class destructor ensures proper closure of Log Sub delete() ‘ Log a message Public Function logEvent(msg As String) As Integer ‘ Handle run-time errors Private Function raiseError() As String End Class 22
  • 23. Class baseConnectorClass ' This class extends our BaseClass and adds the capability to open and close a connection ' Note that this is never used directly – and is overridden by our database-specific classes. ‘ This provides the business logic framework for our database specific connection classes Class baseConnectorClass As BaseClass ‘ Expose some properties Private Function getServer As String Private Function getUserName As String Private Function getPassword As String Private Function getTable As String Public Function getSession As LCSession Public Function getConnection As LCConnection ' The base constructor for this class. Note that it doesnt actually ' do any connection work - it just sets up the base variables Sub new(srv As String, un As String, pw As String, tb As String), baseClass() ‘ And the destructor. This ensures that the connection object is closed Sub delete() End Class 23
  • 24. Class baseODBCConnectorClass • All of our business logic is held in baseConnectorClass  We need to put the database-specific code in only this class  In this case, it is all implemented in the constructor • If we change the business logic later on:  We have to change only baseConnectorClass ' This class extends our BaseConnectorClass and adds the ‘ capabilty to open and close an ODBC Connection Class baseODBCConnectorClass As BaseConnectorClass ‘ Supply a new constructor for this class Sub new(srv As String, un As String, pw As String, tb As String) End sub 24
  • 25. Insulating Database Connections from Business Logic • One main goal is to insulate our database-specific connection information from our business logic  It makes it easier to switch databases in the future, if necessary • In this database, I hold all database-specific information in a profile document Set docProfile = dbThis.GetProfileDocument("Profile") Dim Connection As Variant Select Case docProfile.Database(0) Case "ODBC" Set connection = New baseODBCConnectorClass _ (docProfile.System(0), "", "", "") Case "Oracle" Set connection = New baseOracleConnectorClass _ (docProfile.System(0), docProfile.UserName(0), docProfile.Password(0), docProfile.MetaData(0)) End Select 25
  • 26. Class fieldClass • fieldClass Class FieldClass  Helps us define which ‘ Our two members – a name and a field fields we want returned Public FieldName As String from our data object Public Field As LCField  Used to extract data ‘ get the value of this field Property Get Value As Variant ‘ Construct this field class Sub new(fName As String, F As LCField) End Class 26
  • 27. Class baseODBCConnectorClass — Constructor • This pseudo-code Set Me.lc_Session = New LCSession() shows the steps If ( Me.lc_Session.Status <> LCSUCCESS ) Then towards connecting ‘ Bale out of the function… to our LC LSX ‘ Check to see that the odbc2 LSX Support is available. If (lc_Session.LookupConnector ("odbc2")) Then target data server … • Differences from an ‘ Now set up our Connection ODBC connection Set me.lc_Connection = New LCConnection ( "odbc2" )  The connection token ‘ Set up our data source name Me.lc_Connection.Server = Me.getServer() is “oracle8”  The username and ‘ And finally connect Me.lc_Connection.Connect password are specified ‘ Check to see that the connection has worked If (Me.lc_Connection.isConnected = False) Then … 27
  • 28. ReadTableClass • ReadTableClass Class ReadTableClass As baseClass  Allows us to read the result ‘ Our constructor. Pass in our of an SQL Query ‘ database connection object Sub new(newConn As Variant)  Returns each table row as a LIST of FieldClass items ' set up our read operation ‘ by passing in an SQL statemement Public Function getRecords( _ strSelection As String) As Long ‘ Call this till it returns false, return ‘ each row of the table as a list ‘ of resulting fields Public Function getNextRecord( _ index As Long, returnedFields _ List As FieldClass) As Integer End Class 28
  • 29. Using ReadTableClass • Our controlling code ‘ set up our database connection Set connection = New _  Set up a database baseODBCConnectorClass( _ connection “CUSTOMERS”, "", "", "")  Create a ReadTableClass ‘ set up our ReadTableClass object Dim rc As New ReadTableClass(connection) object ‘ Check to see its valid  Check to see whether If Not rc.Valid Then it’s valid … ‘ Do our SQL thing  Run some SQL If (rc.getRecords( _ "SELECT * from CUSTOMERS")) Then  Process the results While rc.getNextRecord(index, returnedValues) … 29
  • 30. Processing the Results from ReadTableClass • It’s a case of: ------------------ New Record retrieved ---------- ID 1  Retrieving each ROW of data Name Lotus Contact Mike R.hodin  Iterating through the LIST of Address Lotus House fieldClass items and City State Westford MA processing them ZIP 90210 Country USA • Agent “Read Tables to Log” dateFirstContact 01/01/1990 00:00:00 CreditLimit 5000000.0000 just prints them Employees 1000 … Forall thisF In returnedValues Call rc.logEvent(" " + thisF.fieldName + Space(30-Len(thisF.fieldName)) + _ Chr(9) +" [" + Cstr(thisF.Field.DataType) + "]" + Chr(9) + _ Implode(thisF.Field.Text, ", ")) End Forall 30
  • 31. Demo: Read Table to Documents • Let’s use the same underlying code:  Synchronize this information with Notes data  Use the ID field to match up SQL entries with Notes entries  For simplicity, we shall just overwrite the Notes data with the SQL data  Note we are not requesting specific fields  We write ALL field information to a Notes database  We use the same field name in SQL and Notes  This might not be good in production  Consider pre-fixing the Notes field names to avoid name collisions 31
  • 32. Demo Demo Read Table to Documents 32
  • 33. Let’s Write to SQL • In this case, we need to define which fields we shall update  This information is used to define:  The SQL target field  Which field in Notes we pull data from  The data type  This had better match the SQL data type!  Again, we want the operations class to do all the hard work! 33
  • 34. insertTablesClass • Our class allows us to: Class InsertTableClass As baseClass  Define a series of field ' Our constructor. Pass in the Connector. names we shall write Sub new(newConn As Variant) data to ' Call this for each field we wish to append,  Pass a variant array of ‘ passing in a name and a type Public Function appendField( _ values (in the same order fieldName As String, fieldType As Long) _ as our fields were As Integer appended) ' Commit to inserting these records. • This is still pretty hard ' This returns the number of records successfully ‘ inserted, NOT true or false. work Public Function insertRecord( _ values() As Variant) As Integer  We have to track all fields, etc. End Class 34
  • 35. insertFieldClass • insertFieldClass Class insertFieldClass ‘ Our constructor. Pass in our InsertTableClass  Helps define the Sub new(newIT As Variant) fields, field types, ‘ Append a field name and an LSX field type and values to Public Function appendField( _ transfer from the strName As String, Ltype As Long) As Integer Notes document to ‘ Call this once you have set all your field names the SQL table Public Function setUpFields() As Integer  For simplicity, in this ' Using our fieldList, save the field values code instance we are ‘ from this document to to our InsertTableClass Public Function saveFieldsFromDocument( _ assuming that the doc As NotesDocument) As Integer field names are identical in Notes End Class and SQL 35
  • 36. insertTableClass and insertFieldClass Usage • Define a new ‘ Create a new InsertTable Class InsertTableClass Dim it As New InsertTableClass(Connection) ‘ And create a InsertFieldClass, associating • Define a new ‘ it with our table Class. InsertFieldClass Dim ic As New InsertFieldClass(IT) ‘ Define the fields Call ic.appendField("ID", LCTYPE_NUMERIC) • Define our fields Call ic.appendField("Name", LCTYPE_TEXT) … ‘ And “freeze” it there. Call ic. setUpFields() • Freeze the definition ‘ And for one or more Documents, push the ‘ Data across. • Push the data Call ic.saveFieldsFromDocument(doc) 36
  • 37. Demo Demo Insert Rows into SQL 37
  • 38. Performance • Creating LCField items is expensive  We define our LCFields before inserting data  Instead of creating new LCField items within the loop for each iteration, we create them ONCE outside the loop and reuse them  Adds slightly to the complexity  Hence the requirement for insertFieldsClass 38
  • 39. What We’ll Cover … • Overview • LSX • LS:DO • DCR • Wrap-up 39
  • 40. Introducing LotusScript Data Object (LS:DO) • LS:DO was the first data interface  And is reportedly no longer supported  You may find some code that still relies on this • LS:DO uses ODBC v2 drivers to access data  You cannot access Unicode data  This was introduced in ODBC v3.5  The client must have an ODBC definition for the target data source on his machine, if you are running client-based code • Let’s dive straight into a demo … 40
  • 41. Demo Demo Read Table Definition 41
  • 42. Using LS:DO • Create a new connection Const SQL_TABLE = "CUSTOMERS" Const SQL_QUERY = "SELECT * FROM CUSTOMERS" • Create a query and link it to our Set Connection = New ODBCConnection connection Connection.ConnectTo(SQL_TABLE) If Not Connection.IsConnected Then • Create a result set and connect it … to our query Dim Query As New ODBCQuery Set Query.Connection = Connection • Set the SQL query Dim Result As New ODBCResultSet Set Result.Query = Query • Execute the query Query.SQL = SQL_QUERY Result.Execute 42
  • 43. LS:DO Result Set Processing • The ODBCResultSet Object now contains all the results  You can extract field information  You can extract actual values  This code extracts field name and size information If Not Result.IsResultSetAvailable Then Messagebox "I failed to get results from SQL Query: “ + _ SQL_QUERY, 48, "Failed to get Results" Exit Sub End If Dim fields List As String Dim i As Integer For i = 1 To Result.NumColumns Print "Field: " + padString( result.FieldName(i), 30) + _ "Size: " + padString(Cstr(Result.FieldSize(i)), 5) fields(result.FieldName(i)) = result.FieldName(i) Next 43
  • 44. LS:DO Result Set Processing (cont.) • To extract the result rows themselves, use:  Result.getNextRow ID Name 1 Lotus  Result.IsEndOfData Contact Address Mike R.hodin Lotus House City Westford State MA ZIP 90210 Country USA dateFirstContact 01/01/1990 CreditLimit 5000000 Employees 1000 While Not result.IsEndOfData Forall thisField In fields Print " " & padString( "" + thisField, 30 ) & Chr(9) & Result.GetValue(thisField) End Forall Call Result.NextRow() Wend 44
  • 45. LS:DO Tips • LS:DO supports transaction processing  You could — if your SQL data source allowed — switch on Transaction mode  odbcConnection.IsSupported(DB_SUPP_TRANSACTIONS)  You could then perform multiple updates  Commit them all at once  odbcConnection.CommitTransactions 45
  • 46. LS:DO Summary • LS:DO was a fairly simple, robust ODBC connection  You might have some code that relies on it • I would advise you to:  Identify any code that relies on LS:DO  Refactor that code to use LSX 46
  • 47. What We’ll Cover … • Overview • LSX • LS:DO • DCR • Wrap-up 47
  • 48. Introducing DCR • Data Connection Resources (DCR)  New in Domino 6  Allows you to perform real-time, user-based SQL database access  Very useful for front-end applications • However:  It requires constant access to the target database  It requires Domino Enterprise Connection Services (DECS)  Running on the server on which your application is hosted  It pools all SQL database access via the DECS server 48
  • 49. Create a New Shared Resource — Data Connection • Set a name and alias • Set the data connection type • Enter username and password, if required • Choose the data source • And choose the object • Use Browse metadata to validate the connection 49
  • 50. Link the Data Source to Your Form • On the Form Properties — advanced tab, click Browse  Choose the data connection and the metadata object 50
  • 51. Link the Fields to the Data • On the field properties:  Check “External data source”  At the bottom, use the Browse button to select the data source, metadata • One field needs to be defined as the key field • Remember to check “Store data locally” if you want to see this data on views! 51
  • 52. DCR: What Would I Use It For? • Very useful for:  Applications that are permanently connected  Applications that require instant lookup of external data • You could use Notes information and …  Perform lookups to populate the document  Update status information on user request 52
  • 53. Form Manipulation • Bear in mind that all this logic is held on the Form design element  You could use one Form to populate/refresh data  And allow users to work another Form  Which just displays the data on the document 53
  • 54. Demo: DCR • In this demo, I will:  Demonstrate data being updated in Notes and pushed to SQL  Demonstrate data being updated in SQL and pushed to Notes  Show you the DCR common element, as well as the Field definition 54
  • 55. Demo Demo DCR demo 55
  • 56. What We’ll Cover … • Overview • LSX • LS:DO • DCR • Wrap-up 56
  • 57. Resources • Constantin Florea, Notes and Domino Connectivity: A Collection of Examples (IBM Redpaper, March 2001).  www.redbooks.ibm.com/redpapers/pdfs/redp0115.pdf  Check out the abstract here:  www.redbooks.ibm.com/abstracts/redp0115.html?Open • Brian Benz and Rocky Oliver, Lotus Notes and Domino 6 Programming Bible (Wiley, 2003).  www.amazon.com/gp/product/0764526111 57
  • 58. Resources (cont.) • Object-Oriented LotusScript:  www.hadsl.com/hadsl.nsf/Documents/Object+Orientated +Programming+in+LotusScript+(The+View)!OpenDocument • The Notes FAQ!  www.keysolutions.com/NotesFAQ/ • Notes.Net (of course)  www.notes.net 58
  • 59. 7 Key Points to Take Home • Domino can easily interact with other data sources • LS:DO, whilst powerful and easy to use – is no longer supported  Consider refactoring this • LSX performs bulk updates between Domino and other data sources  Simple, fast, efficient • DCR allows real-time update in user context  And centralizes data lookup via the server 59
  • 60. 7 Key Points to Take Home (cont.) • Consider that the target data source will change • Logging and error trapping  Mandatory  Ensure that you know of issues before your users  Monitor this interface • This interface code will change often  Write for maintainability! 60
  • 61. Your Turn! How to contact me: Bill Buchan Bill@hadsl.com 61