SilverStream
Application Server 3.5

com.sssw.rt.util
Interface AgiDataSource


public interface AgiDataSource

A low-level API for accessing and updating row-based data sources within data source triggered business objects. Normally clients will use the higher-level AgiRowCursor and AgiRowSetManager interfaces.

The AgiDataSource interface is used internally by SilverStream row-set managers (such as TableDataStore), and is documented with the intent of allowing 3rd parties to write data sources that can supplement the DataSet-based data sources used in the SilverStream Server. The intent is that this interface can be implemented using direct calls, HTTP requests, or CORBA.

An application will rarely or never call an object that implements AgiDataSource directly. Instead, a data source business object will create and return an AgiDataSource object that the programmer has implemented, and the internal SilverStream row-management classes will use it to obtain data from the external data source.

See Also:
AgiDataRow, AgiDataUpdateRequest

Method Summary
 void checkException()
          Check to see whether there's a bufferred-up exception on the specified data source.
 void close()
          Close the data source and free any resources associated with the current query.
 AgiBandDescriptor getBandDescriptor()
          Get a "band description" for this data source, describing the contents of the data rows used in it.
 Enumeration getNextRows(int count)
          Get the next chunk of rows from the result set of this data source.
 AgiDataUpdateRequest prepareUpdateRequest()
          Prepare an update request to be executed against this data source.
 boolean readOnly()
          Return true if and only if the data source is marked as "read-only" -- no updates are allowed.
 void reQuery()
          Re-execute the current query on the data source, closing the query if any.
 void reQueryIfClosed()
          Re-execute the current query on the data source if and only if the previous query has been closed.
 void setDataRowFactory(AgiDataRowFactory rowFactory)
          Set the row factory to be used by this data source for constructing data rows.
 void startNewQuery(String queryString, String orderBy, int fetchAheadCount)
          Start a new query on the data source, closing the old query if any.
 

Method Detail

setDataRowFactory

public void setDataRowFactory(AgiDataRowFactory rowFactory)
Set the row factory to be used by this data source for constructing data rows. In particular, the row factory is used by the data source when constructing rows returned from the getNextRows() call. This method must be called by the user of the data source before calling any data source method that can return rows (such as getNextRow() or prepareUpdateRequest().
Parameters:
rowFactory - Factory object to be used for constructing rows
Example:

Most implementations will simply save the supplied row factory in a class-private variable for later use.

 public void setDataRowFactory(AgiDataRowFactory rowFactory)
 {
     m_rowFactory = rowFactory;
 }
 

close

public void close()
Close the data source and free any resources associated with the current query. The close method should protect itself against the possibility that it might be called more than once.

The data source can still be restarted by a AgiDataSource.reQueryIfClosed().

Example:
 public void close()
 {
     if (m_resultSet != null) {
         try { m_resultSet.close(); } catch (SQLException ex) {}
         m_resultSet = null;
     }
     if (m_statement != null) {
         try { m_statement.close(); } catch (SQLException ex) {}
         m_statement = null;
     }
     if (m_conn != null) {
         m_db.releaseConnection(m_conn);
         m_conn = null;
     }
 }
 

startNewQuery

public void startNewQuery(String queryString,
                          String orderBy,
                          int fetchAheadCount)
                   throws AgoApiException
Start a new query on the data source, closing the old query if any.
Parameters:
queryString - the new query string; may be null to mean "use previous query". Supply an empty query string to mean "no user-defined query terms". This is typically an expression in the SilverStream expression syntax.
orderBy - The new order-by string; may be null to mean "use previous order". Supply an empty order-by string to mean "no user-defined order terms". This is typically an expression in the SilverStream expression syntax.
fetchAheadCount - Number of rows server is to fetch ahead; -1 to mean "use server default" (may be 0)
Throws:
AgoApiException - if the data source was closed or other error occurs
Example:

In this example, we assume the query and order-by arguments are SQL where and order by clauses.

 public void startNewQuery(String queryString, String orderBy, int fetchAheadCount)
 throws AgoApiException
 {
 if (queryString != null)
     m_queryString = queryString;
 if (orderBy != null)
     m_orderBy = orderBy;
 reQuery();
 }
 

reQuery

public void reQuery()
             throws AgoApiException
Re-execute the current query on the data source, closing the query if any.
Throws:
AgoApiException - If the data source was closed or other error occurs
Example:
 public void reQuery()
 throws AgoApiException
 {
 try {
     close();
     String query = "select ID, Name from Names";
     if (m_queryString != null && m_queryString.length() > 0)
         query += " where " + m_queryString;
     if (m_orderBy != null && m_orderBy.length() > 0)
         query += " order by " + m_orderBy;
     m_conn = m_db.getConnection(true);
     m_statement = m_conn.prepareStatement(query);
     m_resultSet = m_statement.executeQuery();
  } catch (SQLException ex) {
     throw new AgoSystemDatabaseException(ex, "Query failed");
 }
 }
 

reQueryIfClosed

public void reQueryIfClosed()
                     throws AgoApiException
Re-execute the current query on the data source if and only if the previous query has been closed.
Throws:
AgoApiException - If an error occurs.
Example:
 public void reQueryIfClosed()
 throws AgoApiException
 {
 if (m_resultSet == null) {
     reQuery();
 }
 

getBandDescriptor

public AgiBandDescriptor getBandDescriptor()
Get a "band description" for this data source, describing the contents of the data rows used in it. The band descriptor describes the number of columns, the name and type of each column, and so forth.
Returns:
the band descriptor for this data source.
Example:
 public AgiBandDescriptor getBandDescriptor()
 {
 return new MyBandDescriptor();
 }
 

readOnly

public boolean readOnly()
                 throws AgoApiException
Return true if and only if the data source is marked as "read-only" -- no updates are allowed.
Returns:
true if the data source is read-only, false otherwise.
Example:
 public boolean readOnly()
 throws AgoApiException
 {
 return false;
 }
 

getNextRows

public Enumeration getNextRows(int count)
                        throws AgoEndOfRowsException,
                               AgoApiException
Get the next chunk of rows from the result set of this data source.
Parameters:
count - number of rows to be returned
Returns:
Enumeration of rows (AgiDataRow); null if no more rows are currently available. May return fewer than count rows.
Throws:
AgoEndOfRowsException - if the last row from the query has been received.
AgoApiException - If an error occurs.
Usage:
This does NOT start the query if it has not already been started or the result set was closed -- use reQueryIfClosed() first to do that if needed.

The rows are constructed by calling the data row factory specified by the call to setDataRowFactory().

Note that this call can return an empty enumeration, indicating that no more rows are currently available but that more rows may be available later.

Example:

In this example, we return at most one row, irrespective of how many the caller asks for. The row enumeration class is not shown.

 public Enumeration getNextRows(int count)
 throws AgoEndOfRowsException, AgoApiException
 {
 ASSERT(m_rowFactory != null);
 if (m_resultSet == null)
     throw new AgoEndOfRowsException(null);
 try {
     if (!m_resultSet.next()) {
         close();
         return null;
     }
     AgiDataRow row = m_rowFactory.createDataRow(null);
     row.setData(0, m_resultSet.getObject(1));
     row.setData(1, m_resultSet.getObject(2));
     return new SingleRowEnumeration(row);
 } catch (SQLException ex) {
     throw new AgoSystemDatabaseException(ex, "Error getting next row");
 }
 }
 

prepareUpdateRequest

public AgiDataUpdateRequest prepareUpdateRequest()
                                          throws AgoApiException
Prepare an update request to be executed against this data source. The update request can then be "filled" with rows to be inserted, deleted, updated, or published, and then executed. If the update request is not executed, it should be closed.
Returns:
new, empty update request
Throws:
AgoApiException - if an error occurs
Example:
 public AgiDataUpdateRequest prepareUpdateRequest()
 throws AgoApiException
 {
 return new MyDataUpdateRequest(m_db, m_rowFactory);
 }
 

checkException

public void checkException()
                    throws AgoApiException
Check to see whether there's a bufferred-up exception on the specified data source. This can happen because the data source can run asynchronously.
Throws:
AgoApiException - if an exception was bufferred for later delivery
Usage:
This method must be implemented when you write an AgiDataSource. However if the data source does not run asynchronously, this method should probably do nothing, because other methods in the AgiDataSource can throw exceptions.
Example:
 public void checkException()
 throws AgoApiException
 {
 if (m_bufferredException != null)
     throw m_bufferredException;
 }
 

SilverStream
Application Server 3.5