Application Techniques



Using a setResultSet DSO

How to create and use a data source object to return a java.SQL.ResultSet.

About this technique

Details

Category

Data Access Techniques> Data source objects

Description

You'll learn about:

You can run this technique code from:

NOTE   First make sure that database is running on your localhost SilverStream Server

Related reading

See the chapter on using data source business objects in the Programmer's Guide

Objects and data flow   Top of page

This technique (Form and View from Tab-delimited file) shows how to use a DSO to obtain data from an object that implements java.SQL.ResultSet.

The frmDsoSqlResultSet form contains a subform called subfrmTabDelimitedfile, and a view, each displayed within a TabControl. This technique describes how the subfrm is populated, using the DSO called DSOTabDelimitedOrderFile.

The setResultSet implementation described in this technique includes these objects:

subfrmTabDelimitedFileForm

A SilverStream form containing an AgcData control called dataOrderFile. The dataOrderFile object is bound to the DSO called DSOTabDelimitedOrderFile.

DSOTabDelimitedOrderFile

A SilverStream data source object. It instantiates the utility object, called ObjTabDelimitedSQLFile, that implements the java.sql. ResultSet and java.sql.ResultSetMetaData interfaces.

boinvGetApplicationRootDirectory

The functionality of this class is outside the scope of DSOs, thus is not described in this technique.

ObjTabDelimitedSQLFile

A utility class that implements the java.sql.ResultSet and java.sql.ResultSetMetaData interfaces. It obtains the data from the external data source, formats it in the appropriate row and column format, and populates the server-side data buffer for download to the client.

This utility object is located in the com/sqlFile package.

The following diagram illustrates the flow of data among these objects.

  1. The subfrmTabDelimitedfile form calls the invokeQuery() method to invoke the DSOTabDelimitedOrderFile.

    It passes a hashtable that includes the string "File" as the key and a filename as the value. The filename is actually obtained by a call to an AgiInvokedListener object called boinvGetApplicationRootDirectory, which is outside of the scope of this description.

  2. The DSOTabDelimitedOrderFile DSO instantiates the utility class called ObjTabSelimitedSQLFile (which is the java.sql.ResultSet object).

  3. The DSO then calls setResultSet() to specify the java.sql.ResultSet object to use.

  4. The DSOTabDelimitedOrderFile calls setResult() to pass data back to the form. It can be any useful piece of information. In this case, it returns the string "Success" if the DSO can be started, or an exception if not.

  5. subfrmTabDelimitedfile initiates the download of data using the goToFirst() method on the AgcData.

Invoking the DSO and displaying data   Top of page

The form displays read-only orders to the user. The user can navigate the data set using the buttons provided. It is bound to the DSO through an AgcData control called dataOrderFile.

The form's Loaded event calls a custom method, called retrieveOrders(). The retrieveOrders() method creates and populates a hashtable that includes the key value pair "File", sfileName which it passes on the invokeQuery() method call. To display data when the form is loaded, the form must also issue a call to the AgcData.gotoFirst() method.

Code for the retrieveOrders() method   Top of page

  public void retrieveOrders() 
  { 
      String sFileName = getFileName(); 
      if (sFileName == null) 
         return; 
      try 
      { 
        // Set up Orders parameters: 
        //filename of order file to be retrieved and displayed 
        Hashtable hshFile = new Hashtable(); 
         hshFile.put ("file", sFileName); 
         // Cast hshfile to a String and call the DSO on the AgcData 
           String sQueryResult = (String) 
                dataOrderFile.invokeQuery(hshFile);   
        if (sQueryResult == null)  
         return; 
        if (!sQueryResult.equals("Success")) 
        { 
             agDialog.showMessage("File Error", sQueryResult +  
            " Likely cause is failure to find file " + sFileName); 
              return; 
        } 
      // The query for the order file worked. Download the first row 
      dataOrderFile.gotoFirst (); 
      } 
      catch (Exception excpError) 
      { 
         agDialog.displayError(excpError); 
      } 
  } 

Instantiating and setting the Java ResultSet   Top of page

The DSOTabDelimitedFile is bound to the form's AgcData control. The DSO defines these columns:

Code for the invokeQuery event   Top of page

This code instantiates ObjTabDelimitedSQLFile, a the utility object that implements the result set. Use the evt.setResultSet() to get a handle to the java.sql.ResultSet object. This example uses the executeQuery() method and passes the sFilename and sQueryParm variables. The executeQuery() method is implemented by the ObjTabDelimitedSQLFile (the java.sql.ResultSet object).

  public void invokeQuery(AgoDataSourceEvent evt) throws Exception 
  { 
    // Instantiate the business object that implements the  
    // SQL.resultSet 
    ObjTabDelimitedSQLFile fileData = new ObjTabDelimitedSQLFile(); 
    // get the data from the hashtable passed to the DSO from the 
    // calling form. 
    Hashtable hshParm = (Hashtable) evt.getParameter(); 
    String sFilename = (String) hshParm.get ("file"); 
    String sQueryParm = (String) hshParm.get ("queryparm"); 
    try 
    { 
      // specify the result set 
      evt.setResultSet (fileData.executeQuery(sFilename, 
          sQueryParm)); 
       evt.setResult ("Success"); 
    } 
    catch (Exception e) 
    { 
      System.out.println (e.toString()); 
     // Return some information to the calling form. 
     evt.setResult (e); 
     throw new Exception(e.getMessage()); 
    } 
  } 

Implementing the Java ResultSet   Top of page

The ObjTabDelimitedSQLFile is the utility class that implements the java.sql.ResultSet and java.sql.ResultSetMetaData interfaces.

The ObjTabSelimitedSQLFile reads from a text file called SampleOrders.txt. It is located in the samples subdirectory. The first record of the text file contains the column names. The remaining records contain the data. The data rows are delimited by the tab character:

Customer ID

Quantity

Product

Vendor

ANTH

43

Hard Drive

Seagate

ANTH

23

32M Simms

AST

ANTH

15

Floppies qty12

3M

ATLF

32

200MH PCs

IBM

ATLF

81

300MH PCs

Compaq

MAMAM

14

SQL Anywhere

Sybase

MAMAM

71

Norton Utilities

Symantec

BERTO

31

Notes

IBM

MAMAM

99

Virus+

McAfee

CHEVY

23

Unicenter

Computer Associates

BERTO

22

Problem tracking

Onyx

BERTO

11

ERP

SAP

The ObjTabSelimitedSQLFile needs to get the column name information and also the rows. It declares the following variables in the General Declarations section.

  // Save the total column count 
  int m_columnCount = 0;    
  // An array to store the column names 
  String[] m_columnNames;  
  // String tokenizer  
  StringTokenizer m_stringTokenizer; 
  // A buffered reader 
  BufferedReader m_bufferedReader; 
  // The vector Conn result data 
  Vector m_vctData;  
  // only return rows for this customer 
  String m_sQueryParm;                                                                         

Code for the executeQuery() method   Top of page

In the UserCode section, the executeQuery() method uses a file reader, a buffered reader and a StringTokenizer to get the column names from the first row:

  public java.sql.ResultSet executeQuery(String psFileName, String psQueryParm) throws Exception 
    { 
      try 
      { 
        String sFileName = psFileName; 
        m_sQueryParm = psQueryParm; 
        FileReader fileReader = new FileReader (sFileName); 
        m_bufferedReader = new BufferedReader(fileReader); 
        m_stringTokenizer = new StringTokenizer 
            (m_bufferedReader.readLine(), "\t"); 
        m_columnCount = m_stringTokenizer.countTokens(); 
        m_columnNames = new String[m_columnCount]; 
        for (int iCount=0; iCount < m_columnCount; iCount++) 
        {     
          m_columnNames[iCount] = m_stringTokenizer.nextToken(); 
        } 
      } 
      catch (Exception excpError) 
      { 
      System.out.println (excpError.toString()); 
      throw new Exception(excpError.toString() + "\r\nDetail:  " +   
         excpError.getMessage()); 
      } 
     
     return this; 
    } 

Code for the next() method   Top of page

The next() method processes the rows in the file.

  public boolean next() throws java.sql.SQLException 
    { 
      try 
      { 
        String newLine; 
         
        while (true) 
          { 
            // Read a row from the file (up to a newline) 
            newLine = m_bufferedReader.readLine(); 
             
            if (newLine == null)     
            // End of File? We're done. 
              return false; 
               
            if (newLine.length() <= 0)   
            // Nothing in the line, we're done. 
              return false; 
               
            // Get the tab delimited columns into a StringTokenizer 
            m_stringTokenizer = new StringTokenizer (newLine, "\t"); 
             
            // If the first column doesn't equal the current query 
            // parameter, continue the loop. 
            // This will read another row and start over.  
            // A null query parameter means get the 
            // whole result set. 
            String sToken = m_stringTokenizer.nextToken(); 
            if (m_sQueryParm != null && 
                       !m_sQueryParm.equals(sToken)) 
              continue;         
            // Got a good one! Need to get the tokenizer again, 
            // since we already consumed the first column to do the 
           // test. Then break out of the loop. 
            else 
              { 
                m_stringTokenizer = new StringTokenizer  
                    (newLine, "\t"); 
                break; 
              } 
          } 
          // The row meets the selection criteria. Create a vector 
          // and populate it with columns. 
          m_vctData = new Vector(); 
          for (int iCount = 0; iCount < m_columnCount; iCount++) 
            {   
            m_vctData.addElement (m_stringTokenizer.nextToken()); 
            } 
          return true; 
      } 
      catch (Exception excpError) 
      { 
        System.out.println (excpError.toString());   
        return false; 
      } 
    } 





Copyright © 2000, SilverStream Software, Inc. All rights reserved.