# ARQ - Application API

The application API is in the package `com.hp.hpl.jena.query`.

Other packages contain various parts of the system (execution engine, parsers, testing etc). Most applications will only need to use the main package. Only applications wishing to programmatically build queries or modify the behaviour of the query engine need to use the others packages directly.

## Key Classes

The package `com.hp.hpl.jena.query` is the main application package.

- `Query` - a class that represents the application query. It is a container for all the details of the query. Objects of class Query are normally created by calling one of the methods of `QueryFactory` methods which provide access to the various parsers.
- `QueryExecution` - represents one execution of a query.
- `QueryExecutionFactory` - a place to get `QueryExecution` instances
- `DatasetFactory` - a place to make datasets, including making a `DataSource` (an updatable `Dataset`)
- For SELECT queries:
  - `QuerySolution` - A single solution to the query
  - `ResultSet` - All the QuerySolutions. An iterator.
  - `ResultSetFormatter` - turn a ResultSet into various forms; into text, into an RDF graph (Model, in Jena terminology) or as plain XML

## SELECT queries

The basic steps in making a SELECT query are outlined in the example below. A query is created from a string using the `QueryFactory`. The query and model or RDF dataset to be queried are then passed to `QueryExecutionFactory` to produce an instance of a query execution. Result are handled in a loop and finally the query execution is closed.

      import com.hp.hpl.jena.query.* ;

      Model model = ... ;
      String queryString = " .... " ;
      Query query = QueryFactory.create(queryString) ;
      QueryExecution qexec = QueryExecutionFactory.create(query, model) ;
      try {
        ResultSet results = qexec.execSelect() ;
        for ( ; results.hasNext() ; )
        {
          QuerySolution soln = results.nextSolution() ;
          RDFNode x = soln.get("varName") ;       // Get a result variable by name.
          Resource r = soln.getResource("VarR") ; // Get a result variable - must be a resource
          Literal l = soln.getLiteral("VarL") ;   // Get a result variable - must be a literal
        }
      } finally { qexec.close() ; }

It is important to cleanly close the query execution when finished. System resources connected to persistent storage may need to be released.

The step of creating a query and then a query execution can be reduced to one step in some common cases:

      import com.hp.hpl.jena.query.* ;

      Model model = ... ;
      String queryString = " .... " ;
      QueryExecution qexec = QueryExecutionFactory.create(queryString, model) ;
      try {
       ResultSet results = qexec.execSelect() ;
        . . .
      } finally { qexec.close() ; }

### Example: formatting a result set

Instead of a loop to deal with each row in the result set, the application can call an operation of the ResultSetFormatter. This is what the command line applications do.

Example: processing results to produce a simple text presentation:

        ResultSetFormatter fmt = new ResultSetFormatter(results, query) ;
        fmt.printAll(System.out) ;

or simply:

     ResultSetFormatter.out(System.out, results, query) ;

### Example: Processing results

The results are objects from the Jena RDF API and API calls, which do not modify the model, can be mixed with query results processing:

      for ( ; results.hasNext() ; )
      {
          // Access variables: soln.get("x") ;
          RDFNode n = soln.get("x") ; // "x" is a variable in the query
          // If you need to test the thing returned
          if ( n.isLiteral() )
              ((Literal)n).getLexicalForm() ;
          if ( n.isResource() )
          {
             Resource r = (Resource)n ;
              if ( ! r.isAnon() )
              {
                ... r.getURI() ...
              }
          }
      }

Updates to the model must be carried out after the query execution has finished. Typically, this involves collecting results of interest in a local datastructure and looping over that structure after the query execution has finished and been closed.

## CONSTRUCT Queries

`CONSTRUCT` queries return a single RDF graph. As usual, the query execution should be closed after use.

    Query query = QueryFactory.create(queryString) ;
    QueryExecution qexec = QueryExecutionFactory.create(query, model) ;
    Model resultModel = qexec.execConstruct() ;
    qexec.close() ;

## DESCRIBE Queries

`DESCRIBE` queries return a single RDF graph. Different handlers for the `DESCRIBE` operation can be loaded by added by the application.

    Query query = QueryFactory.create(queryString) ;
    QueryExecution qexec = QueryExecutionFactory.create(query, model) ;
    Model resultModel = qexec.execDescribe() ;
    qexec.close() ;

## ASK Queries

The operation Query.execAsk() returns a boolean value indicating whether the query pattern matched the graph or dataset or not.

    Query query = QueryFactory.create(queryString) ;
    QueryExecution qexec = QueryExecutionFactory.create(query, model) ;
    boolean result = qexec.execAsk() ;
    qexec.close() ;

## Formatting XML results

The `ResultSetFormatter` class has methods to write out the SPARQL Query Results XML Format. See ResultSetFormatter.outputAsXML method.

## Datasets

The examples above are all queries on a single model. A SPARQL query is made on a dataset, which is a default graph and zero or more named graphs. Datasets can be constructed using the `DatasetFactory`:

    String dftGraphURI = "file:default-graph.ttl" ;
    List namedGraphURIs = new ArrayList() ;
    namedGraphURIs.add("file:named-1.ttl") ;
    namedGraphURIs.add("file:named-2.ttl") ;

    Query query = QueryFactory.create(queryString) ;

    Dataset dataset = DatsetFactory.create(dftGraphURI, namedGraphURIs) ;
    QueryExecution qExec = QueryExecutionFactory.create(query, dataset) ;
    try { ... }
    finally { qExec.close() ; }

Already existing models can also be used: A `DataSource` is an updatable dataset:

    DataSource dataSource = DatsetFactory.create() ;
    dataSource.setDefaultModel(model) ;
    dataSource.addNamedModel("http://example/named-1", modelX) ;
    dataSource.addNamedModel("http://example/named-2", modelY) ;
    QueryExecution qExec = QueryExecutionFactory.create(query, dataSource) ;

ARQ Documentation Page