com.revusky.oreo.jdbc
Class JDBCBackedRecordSet

java.lang.Object
  |
  +--com.revusky.oreo.AbstractDataSource
        |
        +--com.revusky.oreo.AbstractMutableDataSource
              |
              +--com.revusky.oreo.jdbc.JDBCBackedRecordSet
All Implemented Interfaces:
DataListener, DataSource, java.util.EventListener, MutableDataSource, java.rmi.Remote

public class JDBCBackedRecordSet
extends AbstractMutableDataSource
implements DataListener

A class that is essentially a facade in front of an external relational database. This is just one of various possible ways to implement this. This implementation allows for an in-memory cache of adjustable size. This container is probably fairly efficient for a web app whose profile is that there are a lot of reads and relatively few writes to the external RDBMS. That is probably more the rule than the exception. There are 2 PROPERTY parameters that must be configured in the XML:

These should be self-explanatory. They are needed so that this class can talk to a database via JDBC. A tiny gotcha in terms of configuring the JDBC_URL parameter is that the ampersand (&) must be written via the XML entity: &
There are several optional PROPERTY parameters as well: The first of the above properties determines how big an in-memory record cache to maintain. The algorithm is pretty simplistic. The cache is simply allowed to grow (no attempt is made to maintain most-recently-used info) and when it goes beyond the maximum size, it gets wiped and starts building up again. The second optional parameter indicates the frequency with which to wipe the in-memory cache. (The default is never.) This is specified in seconds. If you were to specify a value of 3600, for example, this means, that the cache will never live beyond one hour. What this would mean practically is that, if you did a bulk update of the backing RDBMS externally, it would take a maximum of one hour before the webapp reflected the new data. Of course, if you wanted it to do so immediately, you could always have an administrative function that called the wipeCache() method on the data source object.
The DEFAULT_RECORD property can be optionally specified to indicate a default record type for this container. In particular, if an instance of this class is homogeneous, i.e. only contains one record type, then it may be nice to specify this, since it frees you of the need to specify the type parameter in calls to get() for example.
The CREATE_TABLES_IF_NECESSARY property takes a list of record types for which to create tables if they do not already exist in the underlying database. This is a good bootstrap feature, though I should mention that this has not been tested against a broad range of databases. Also, you must have the right to create tables on the DB in question.
The DOUBLE_QUOTE_LITERAL property, if set to "Y", means that you represent a literal quote character as '' as opposed to the default \'

Author:
Jonathan Revusky

Constructor Summary
JDBCBackedRecordSet()
           
 
Method Summary
 void delete(Record rec)
          Delete a record
 Record get(java.lang.String type, java.lang.Object key)
           
protected  JDBCConnection getConnection()
           
 void handleEvent(DataEvent event)
          handle the event when the MutableDataSource we are listening to has modified data
 void init(java.util.Properties props)
          A method that initializes a DataSource with a set of initialization properties.
 void insert(Record rec)
          Adds a new record to the managed pool.
 java.util.List keys(java.lang.String type)
           
 void playEvent(DataEvent event)
          "play" an event This will be mostly used in restarting an app and reconstructing the state of the data from logs.
 java.util.List select(RecordFilter filter)
          Fetches a list of records matching filter.
protected  java.lang.Object uniqueKey(Record rec)
           
 void update(Record oldRec, Record newRec)
          Replaces an existing version of a record with a new updated version.
 void wipeCache()
          If this data source is backed by some external mechanism, like an RDBMS, wipes the in-memory cache, if one is being maintained.
 
Methods inherited from class com.revusky.oreo.AbstractMutableDataSource
addDataListener, fireDataEvent, freeze, freeze, getRecords, markStale, normalizeKey, removeDataListener
 
Methods inherited from class com.revusky.oreo.AbstractDataSource
close, get, getName, keys
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 
Methods inherited from interface com.revusky.oreo.DataSource
close, get, getName, keys
 

Constructor Detail

JDBCBackedRecordSet

public JDBCBackedRecordSet()
                    throws java.io.IOException
Method Detail

handleEvent

public void handleEvent(DataEvent event)
                 throws java.io.IOException
Description copied from interface: DataListener
handle the event when the MutableDataSource we are listening to has modified data
Specified by:
handleEvent in interface DataListener

init

public void init(java.util.Properties props)
          throws java.io.IOException
Description copied from interface: DataSource
A method that initializes a DataSource with a set of initialization properties. This is called internally within Oreo and should not be called by application code. As an implementor, you should make sure that this method is only called once, for example, throw a RuntimeException if an attempt is made to call this on a DataSource a second time.
Overrides:
init in class AbstractDataSource

delete

public void delete(Record rec)
            throws java.io.IOException
Description copied from interface: MutableDataSource
Delete a record
Following copied from interface: com.revusky.oreo.MutableDataSource
Parameters:
the - record to delete.

insert

public void insert(Record rec)
            throws java.io.IOException
Description copied from interface: MutableDataSource
Adds a new record to the managed pool.
Following copied from interface: com.revusky.oreo.MutableDataSource
Parameters:
rec - the record to add
Throws:
DuplicateRecordException - if another record already exists with same primary key as 'rec'.
java.io.IOException - if the record cannot be initialized (i.e. has missing fields or invalid field values, etc.), or in case of a low-level error.

update

public void update(Record oldRec,
                   Record newRec)
            throws java.io.IOException
Description copied from interface: MutableDataSource
Replaces an existing version of a record with a new updated version. Some implementations may use the oldRec parameter to guarantee that there are no concurrency issues. In such case, it would throw a ConcurrentModificationException
Following copied from interface: com.revusky.oreo.MutableDataSource
Parameters:
oldRec - the record to replace.
newRec - the new record.
Throws:
java.io.IOException - thrown in case of any other database or communication error.

keys

public java.util.List keys(java.lang.String type)
                    throws java.io.IOException
Following copied from interface: com.revusky.oreo.DataSource
Parameters:
type - the record type we are interested, under some circumstances, this may be null.
Returns:
a list of all valid lookup keys that correspond to a given record type.

get

public Record get(java.lang.String type,
                  java.lang.Object key)
           throws java.io.IOException
Following copied from interface: com.revusky.oreo.DataSource
Parameters:
type - the type of the record, if this is null, then any type will do.
key - the lookup key
Returns:
a Record of the given type, with the given lookup key. If the data source allows multiple records, only returns the first one found. Use getRecords() in that situation. returns null if none is found.

wipeCache

public void wipeCache()
Description copied from interface: DataSource
If this data source is backed by some external mechanism, like an RDBMS, wipes the in-memory cache, if one is being maintained. Otherwise, it does nothing.
Overrides:
wipeCache in class AbstractDataSource

select

public java.util.List select(RecordFilter filter)
                      throws java.io.IOException
Description copied from interface: MutableDataSource
Fetches a list of records matching filter. If filter is null, returns all the records in the container.
Following copied from interface: com.revusky.oreo.MutableDataSource
Parameters:
filter - the record filter, or null.
Returns:
a List of all the records that are an instance of a given class. If no records match the filter, an empty List.

playEvent

public void playEvent(DataEvent event)
               throws java.io.IOException
Description copied from interface: MutableDataSource
"play" an event This will be mostly used in restarting an app and reconstructing the state of the data from logs. Note that data listeners are not notified.

getConnection

protected JDBCConnection getConnection()

uniqueKey

protected java.lang.Object uniqueKey(Record rec)
                              throws java.io.IOException