Using TologResultsSet

The org.tm4j.tologx.TologResultsSet interface defines a JDBC-like results set interface. Results are organised as a list of rows, each consisting of one column for each variable specified in the "select ... from" part of the original query (or all of the variables in the query if "select * from" was used). The interface provides methods to:

  1. determine the size of the results set (getNumRows()),
  2. determine how many columns each row in the results set has (getNumCols()),
  3. determine which variable value is reported in a given column (getVar(int columnNumber)), and
  4. get a single row in the results set (getRow(int rowNumber)).
Note that this last method returns a java.util.List object which is an in-order list of the values on the row, so to get the value of a particular cell of the row, you need to call the get(int ix) method of the List object with the column number of interest. Both column and row numbering used by the TologResultsSet is zero-based.

From TM4J 0.9.5, the new tolog query engine may return any kind of object in a results set. It is the responsibility of the code using the results set to perform the appropriate cast on the items in the List returned by a call to getRow(int). Where the "select...from" statement contains a count() clause, the corresponding results set item will be an Integer instance. In all other cases, the type of the result value will depend on the predicates that the variable appeared in. For example, if the query:

select $A, $B, count($C) from reports-to($A:boss, $B:minion), 
                              works-for($B:chief, $C:indian) ?
    

is evaluated, then the results set will contain three columns. Column 0 will contain the values of $A which match the query - the values will be Topic objects. Column 1 will contain the values of $B which match the query - the values will be Topic objects. Column 2 will contain the count of the number of distint topics which matched $C for a given $A, $B pair and the values will be Integer objects.

The following code shows how a TologResultsSet can be iterated over to extract (and in this case print) the results that it contains.

Example 8.3. Using the TologResultsSet

/**
 * This method dumps the results in the TologResultsSet 
 * <code>results</code> to the standard output stream.
 * There is one line in the output for each row in the results set.
 */
public void dumpResults(TologResultsSet results)
{
  for (int i = 0; i < results.getNumRows(); i++)
  {
    List row = results.getRow(i);
    StringBuffer buf = new StringBuffer();
    for(int j = 0; j < results.getNumCols(); j++)
    {
      if (j > 0) buf.append(", ");
      buf.append(results.getVar(j));
      buf.append(" = ");
      buf.append(row.get(j) instanceof TopicMapObject ? 
        ((TopicMapObject)row.get(j)).getID() : row.get(j).toString());
    }
    System.out.println(buf.toString());
  }
}

A TologResultsSet object can also be converted into a topic map. This is especially useful in generating subsets of a larger topic map through the use of Tolog queries. The actual generation of the topic map is handled by the org.tm4j.topicmap.utils.TopicMapFragment class which is used to extract the topics and other topic map objects necessary to give the results set some context. To convert a tolog results set into a topic map, you need to follow these steps.

Warning

The TologFragmentBuilder implementation is restricted to only handling results sets containing Topic objects. DO NOT use this class to process results sets that contain other kinds of object!

  1. [OPTIONAL] Create the target TopicMap

    Create the TopicMap instance into which the results should be copied. You may, of course, reuse an existing TopicMap object if you desire.

    Warning

    At the present time, the TopicMapFragment code will not allow the copying of objects with IDs which match those already in the target topic map. This means that unless you are always copying from the same source TopicMap, you may end up with some unexpected results. The real purpose of the TopicMapFragment class is to allow a single operation (query or other form of selection) on a single TopicMap to be represented as another TopicMap object.

  2. Create the TopicMapFragment helper

    Create a TopicMapFragment instance to manage the copying of the results. This instance should be instantiated with the TopicMap object created in the previous step and an integer value representing the amount of context to be copied for each topic and association in the results set. See the section called “TopicMapFragment” for more information about the context size.

  3. Create and initialise the TologFragmentBuilder helper

    Create an instance of the org.tm4j.tologx.TologFragmentBuilderImpl class and initialise its properties. The properties are initialised through calls to the setXXX() methods provided by the org.tm4j.tologx.TologFragmentBuilder interface. Table 8.1, “Properties of the TologFragmentBuilder Interface” lists the configuration properties currently supported by the builder.

  4. Export the TologResultsSet to the target TopicMap

    Invoke the exportResultsSet() method, passing in the TologResultsSet object to be exported as the only parameter.

The TologFragmentBuilder interface provides a number of configuration properties. One of these properties, the fragment property must be set before a call to exportResultsSet() is made.

Note

If you use the constructor of the TologFragmentBuilderImpl class which takes the TopicMapFragment as a parameter, then the fragment property will be set in the course of that constructor and does not need to be set again.

By default, the TologFragmentBuilder will build a TopicMapFragment which contains each of the topics in the results set. If a topic appears more than once in a results set, it will be copied to the TopicMapFragment just once. However, using the other properties of the TologFragmentBuilder interface, it is possible to control the creation of additional "structural" topics and associations which represent the results set itself. If the property convertRowInformation is set to true, then a topic will be generated for each column in the results set and an association will be generated for each row. Each row association will contain one member per column. The member will be typed using the topic which represents that column and will have a single role playing topic which will be the actual value found in that column on the specific row. The row associations will be typed by a topic with a base name and subject indicator which may be set by setting the appropriate properties of the TologFragmentBuilder. In addition, each topic generated for the columns in the results set will have a name and subject indicator generated for it by concatenating a fixed prefix string with the name of the column as it appears in the TologResultsSet. The table below lists all of the properties supported by the TologFragmentBuilder interface and their effects on the generation of the TopicMap.

Table 8.1. Properties of the TologFragmentBuilder Interface

Property NameProperty TypeDescription
convertRowInformationbooleanSpecifies whether or not associations should be exported for the rows in the results set.
fragmentTopicMapFragmentThe TopicMapFragment which manages the copying of the results set objects. This property MUST be set before attempting to export the results set.
generateVarTopicNamesbooleanIf convertRowInformation is true, then this option controls whether or not the extra topics generated to identify the columns of the results set should be generated with BaseNames. If convertRowInformation is false, then this option has no effect.
generateVarTopicSubjectIndicatorsbooleanIf convertRowInformation is true, then this option controls whether or not the extra topics generated to identify the columns of the results set should be generated with subject indicators for identity purposes. If convertRowInformation is false, then this option has no effect.
rowAssociationTypeNameStringIf convertRowInformation is true, then the value of this option will be used as the name string for the base name of the topic which types the associations made for each row in the results set. If convertRowInformation is false, then this option has no effect.
varTopicNamePrefixStringIf convertRowInformation is true and generateVarTopicNames is true, then the value of this option will be prepended to the column name retrieved from the TologResulstsSet and the concatenated string will be used as the base name for the topic which represents that column in the results set.
varTopicSubjectIndicatorPrefixStringIf convertRowInformation and generateVarTopicSubjectIndicators are both true, then the value of this option will be prepended to the column name retrieved from the TologResulstsSet and the concatenated string will be used as a URI notation locator address applied as a subject indicator for the generated topic which represents that column in the results set. It is the responsibility of the caller to provide a string value which when concatenated with the column name can be interpreted as a valid URI.

Example 8.4. Using the TologFragmentBuilder

The following code sample shows how the TologFragmentBuilder can be used. The complete listing for the application can be found in examples/src/tolog/TologQueryExample.java.

/**
 * This method exports the contents of a TologResultsSet into a topic map
 * as a topic map fragment.
 * @param results the results to be exported
 * @param resultsTopicMap the target topic map to create the fragment in.
 */
private void extractResults(TologResultsSet results, TopicMap resultsTopicMap)
{
  try
  {
    // Create the TopicMapFragment helper object
    // We use a radius of 1 to get the typing and scoping topics to be 
    // exported with their  names, occurrences and so on.
    TopicMapFragment frag = new TopicMapFragment(resultsTopicMap, 1);

    // Create the TologFragmentBuilder helper object
    // We are using the construct which specifies the TopicMapFragment 
    // helper as a parameter, so there is no need to call the setFragment() 
    // method after the TologFragmentBuilder is initialised.
    TologFragmentBuilder builder = new TologFragmentBuilderImpl(frag);

    // Set export options

    // We want additional associations/topics to be generated to represent
    // the results set rows and columns.
    builder.setConvertRowInformation(true);

    // We want the topics representing the columns to be generated
    // with base names.
    builder.setGenerateVarTopicNames(true);
	    
    // Each topic representing a results set column will have the name
    // "Result Variable x" where x is the column name.
    builder.setVarTopicNamePrefix("Result Variable ");

    // Do the export
    builder.exportResultsSet(results);
    
  }
  catch(TologFragmentBuilderException ex)
  {
    throw new RuntimeException(
                  "Error creating topic map fragment from results set.");
  }
}