Example: Using record-level access classes to read records by key

Note: Read the Code example disclaimer for important legal information.
///////////////////////////////////////////////////////////////////////////////
//
// Record-Level Access example.  This program uses the record-level
// access classes to read records by key from a file on the server.
// The user will be prompted for the server name to which to run and
// the library in which to create file QCUSTCDTKY.
//
// Command syntax:
//    java RLKeyedFileExample
//
// This program will copy the records from the iSeries Access for Windows sample 
// database file (QCUSTCDT in library QIWS) to file QCUSTCDTKY which has
// the same format as QIWS/QCUSTCDT but has set the CUSNUM field as the key
// for the file.
//
// This source is an example of IBM Toolbox for Java "Record-level access".
//
///////////////////////////////////////////////////////////////////////////////


import java.io.*;
import java.util.*;
import java.math.*;
import com.ibm.as400.access.*;

public class RLKeyedFileExample
{
  public static void main(String[] parameters)
  {

    // Created a reader to get input from the user
    BufferedReader inputStream = new BufferedReader(new InputStreamReader(System.in),1);

    // Declare variables to hold the system name, library, file and member names
    String systemName = "";
    String library = "";

    // Get the system name from the user
    System.out.println();
    try
    {
      System.out.print("System name: ");
      systemName = inputStream.readLine();

      System.out.print("Library in which to create file QCUSTCDTKY: ");
      library = inputStream.readLine();
    }
    catch(Exception e)
    {
      System.out.println("Error obtaining user input.");
      e.printStackTrace();
      System.exit(0);
    }

    // Create AS400 object and connect for the record level access service.
    AS400 system = new AS400(systemName);
    try
    {
      system.connectService(AS400.RECORDACCESS);
    }
    catch(Exception e)
    {
      System.out.println("Unable to connect for record level access.");
      System.out.println("Check the readme file for special instructions regarding record
                         level access");
      e.printStackTrace();
      System.exit(0);
    }

    RecordFormat qcustcdtFormat = null;
    try
    {
      // Create the RecordFormat object for creating the file.  The record format for the new
      // file will be the same as the record format for file QIWS/QCUSTCDT.  However we will
      // make the CUSNUM field a key field.
      AS400FileRecordDescription recordDescription = 
        new AS400FileRecordDescription(system, "/QSYS.LIB/QIWS.LIB/QCUSTCDT.FILE");

      // There is only one record format for the file, so take the first (and only) element
      // of the RecordFormat array returned as the RecordFormat for the file.
      System.out.println("Retrieving record format of QIWS/QCUSTCDT...");
      qcustcdtFormat = recordDescription.retrieveRecordFormat()[0];
      // Indicate that CUSNUM is a key field
      qcustcdtFormat.addKeyFieldDescription("CUSNUM");
    }
    catch(Exception e)
    {
      System.out.println("Unable to retrieve record format from QIWS/QCUSTCDT");
      e.printStackTrace();
      System.exit(0);
    }

    // Create the keyed file object that represents the
    // file we will create on the server.  We use a QSYSObectPathName object
    // to get the name of the file into the correct format.
    QSYSObjectPathName fileName = new QSYSObjectPathName(library,
                                                         "QCUSTCDTKY",
                                                         "*FILE",
                                                         "MBR");
    KeyedFile file = new KeyedFile(system, fileName.getPath());

    try
    {
      System.out.println("Creating file " + library + "/QCUSTCDTKY...");
      // Create the file using the qcustcdtFormat object
      file.create(qcustcdtFormat, "Keyed QCUSTCDT file");

      // Populate the file with the records contained in QIWS/QCUSTCDT
      copyRecords(system, library);

      // Open the file for read-only access.  Because we will be randomly
      // accessing the file, specify a blocking factor of 1.  The
      // commit lock level parameter will be ignored since commitment
      // control has not been started.
      file.open(AS400File.READ_ONLY,
                1,
                AS400File.COMMIT_LOCK_LEVEL_NONE);

      // Assume that we want to display the information for customers
      // 192837, 392859 and 938472
      // The CUSNUM field is a zoned decimal field of length 6 with
      // no decimal positions.  Therefore, the key field value is
      // represented with a BigDecimal.
      BigDecimal[] keyValues = {new BigDecimal(192837),
                                new BigDecimal(392859),
                                new BigDecimal(938472)};

      // Create the key for reading the records.  The key for a KeyedFile
      // is specified with an Object[]
      Object[] key = new Object[1];

      Record data = null;
      for (int i = 0; i < keyValues.length; i++)
      {
        // Setup the key for reading
        key[0] = keyValues[i];

        // Read the record for customer number keyValues[i]
        data = file.read(key);
        if (data != null)
        {
          // Display the record only if balance due is greater than
          // zero.  In that case display the customer name and
          // the balance due.  The following code pulls fields out
          // of the record by field name.  As the field is retrieved
          // from the record it is converted from the server format to
          // Java format.
          if (((BigDecimal)data.getField("BALDUE")).floatValue() > 0.0)
          {
            System.out.print((String) data.getField("INIT") + "  ");
            System.out.print((String) data.getField("LSTNAM") + "  ");
            System.out.println((BigDecimal) data.getField("BALDUE"));
          }
        }
      }

      // All done with the file
      file.close();

      // Get rid of the file from the user's system
      file.delete();
    }
    catch(Exception e)
    {
      System.out.println("Unable to create/read from QTEMP/QCUSTCDT");
      e.printStackTrace();
      try
      {
        file.close();
        // Get rid of the file from the user's system
        file.delete();
      }
      catch(Exception x)
      {
      }
    }

    // All done with record level access; disconnect from the
    // record-level access server.
    system.disconnectService(AS400.RECORDACCESS);
    System.exit(0);
  }

  public static void copyRecords(AS400 system, String library)
  {
    // Use the CommandCall class to run the CPYF command to copy the records
    // in QIWS/QCUSTCDT to QTEMP/QCUSTCDT
    CommandCall c = new CommandCall(system, "CPYF FROMFILE(QIWS/QCUSTCDT) TOFILE("
                                    + library + "/QCUSTCDTKY) MBROPT(*REPLACE)");
    try
    {
      System.out.println("Copying records from QIWS/QCUSTCDT to "
                         + library + "/QCUSTCDTKY...");
      c.run();
      AS400Message[] msgs = c.getMessageList();
      if (!msgs[0].getID().equals("CPC2955"))
      {
        System.out.println("Unable to populate " + library + "/QCUSTCDTKY");
        for (int i = 0; i < msgs.length; i++)
        {
          System.out.println(msgs[i]);
        }
        System.exit(0);
      }
    }
    catch(Exception e)
    {
      System.out.println("Unable to populate " + library + "/QCUSTCDTKY");
      System.exit(0);
    }
  }
}