Data Navigation Sample

This sample extends the framework code to demonstrate the capabilities of metadata examination of Recordsets. Since ADO/WFC’s Field objects contain both metadata and field values, the metadata for a given Field may be accessed from any position within the Recordset. There is no requirement, as in JDBC, for separate DatabaseMetadata or ResultsetMetadata-style objects. The metadata is always available.

The following code shows the procedure for extracting basic metadata information from the Fields collection of a Recordset, after the Recordset has been opened and populated.

public boolean run()
{
   Recordset rs = new Recordset();
   rs.setCursorType (AdoEnums.adOpenStatic);
   rs.setCursorLocation (AdoEnums.adUseClientBatch);
   rs.setLockType (AdoEnums.adLockBatchOptimistic);
   rs.open("select * from authors", 
     "server=aServer;driver=sql server;uid=aUID;pwd=aPWD;database=pubs");

   rs.moveFirst();
   
   Fields fields = rs.getFields();
   int cFields = fields.getCount();

   for( int iField = 0; iField < cFields; iField++ )
   {
      useField( fields.getItem( iField ) );
   }

   for( int iField = 0; iField < cFields; iField++ )
   {
      System.out.print( fields.getItem( iField ).getName() + "\t" );
   }
   System.out.println("");

   rs.moveFirst();
   while( !rs.getEOF() )
   {
      for( int iField = 0; iField < cFields; iField++ )
      {
         System.out.print( getString( fields.getItem( iField ) ) + "\t" );
      }
      System.out.println("");

      rs.moveNext();
   }

   rs.close();
   rs.release();
   return true;
}

String getString (Field fld)
{
   if (fld.isNull())
      return "NULL";
   else
      return fld.getObject().toString();
}

void useField (Field fld)
{
   AdoProperties props = fld.getProperties();
   int cProps = props.getCount();
   for( int iProp = 0; iProp < cProps; iProp++ )
   {
      AdoProperty p = props.getItem( iProp );
      System.out.println("[" + p.getName() + " = " + p.getString() + "]");
   }

   System.out.println ("ActualSize = " + fld.getActualSize());
   System.out.println ("Attributes = " + fld.getAttributes());
   System.out.println ("DefinedSize = " + fld.getDefinedSize());
   System.out.println ("Name = " + fld.getName());
   System.out.println ("Type = " + fld.getType());
   System.out.println ("Precision = " + fld.getPrecision());
   System.out.println ("NumericScale = " + fld.getNumericScale());

}

This sample begins by using the basic ADO/WFC constants to configure the Recordset’s properties prior to opening the cursor:

rs.setCursorType (AdoEnums.adOpenStatic);
rs.setCursorLocation (AdoEnums.adUseClientBatch);
rs.setLockType (AdoEnums.adLockBatchOptimistic);

The Recordset is now ready to execute the query. After populating the client-side, batch-mode cursor, the application extracts the Fields collection, which contains the navigation mechanism for accessing individual row data values, as well as the Field metadata. The Fields collection provides a method for determining the number of Field objects it contains. This varies with the “shape” of the Recordset. Having established the dimension or shape of the Recordset, the application proceeds to extract the AdoProperty objects associated with each Field.

The useField method is the heart of the sample. This method retrieves the values of each AdoProperty of the Field, which are then written to the System console window. The code prints the core AdoProperties for Field objects: actual size, name, data type, precision, and numeric scale. The useField method demonstrates how you can easily access the metadata of a Recordset.

Having displayed the Recordset’s metadata, displaying the data values in each row is a simple matter of iterating over the Recordset from the first row until recordset.EOF is encountered:

rs.moveFirst();
while( !rs.getEOF() )
   {
      for( int iField = 0; iField < cFields; iField++ )
      {
         System.out.print( getString( fields.getItem( iField ) ) + "\t");
      }
      System.out.println("");

      rs.moveNext();
   }

Each Field in the given row is traversed and the row is accessed with the getItem accessor method. The value is then converted to a String object and written to the System console window. When the end of the current row is reached, the Recordset position is advanced to the next row by the moveNext method. The process repeats until the end of the Recordset is reached, and the program then terminates normally.