|
|||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Objectorg.geotools.data.jdbc.JDBCDataStore
Abstract helper class for JDBC DataStore implementations.
This class provides a default implementation of a JDBC data store. Support for vendor specific JDBC data stores can be easily added to Geotools by subclassing this class and overriding the hooks provided.
At a minimum subclasses should implement the following methods:
buildAttributeType(ResultSet)
- This
should be overriden to construct an attribute type that represents any
column types not supported by the default implementation, such as geometry
columns.
createGeometryAttributeReader
- Should be overriden to provide an
AttributeReader that is capable of reading geometries in the format of the
database.
Additionally subclasses can optionally override the following:
determindeFidColumnName
- Used to
determine the FID column name. The default uses the primary key, but
subclasses can alter this as needed.
allowTable
- Used to determine whether a table
name should be exposed asa feature type.
determineSRID
- Used to determine the
SpatialReference ID of a geometry column in a table.
buildSQLQuery()
- Sub classes can override this to build a custom SQL
query.
Nested Class Summary | |
static class |
JDBCDataStore.FeatureTypeInfo
Stores information about known FeatureTypes. |
protected class |
JDBCDataStore.JDBCFeatureWriter
|
static class |
JDBCDataStore.QueryData
Provides an encapsulation of the connection, statement and result set of a JDBC query. |
Field Summary | |
FeatureListenerManager |
listenerManager
Manages listener lists for FeatureSource implementations |
protected static java.util.Map |
TYPE_MAPPINGS
Maps SQL types to Java classes. |
Constructor Summary | |
JDBCDataStore(ConnectionPool connectionPool)
|
|
JDBCDataStore(ConnectionPool connectionPool,
java.lang.String databaseSchemaName)
|
|
JDBCDataStore(ConnectionPool connectionPool,
java.lang.String databaseSchemaName,
java.lang.String namespace)
|
Method Summary | |
protected boolean |
allowTable(java.lang.String tablename)
Provides a hook for sub classes to filter out specific tables in the data store that are not to be used as geospatial tables. |
protected java.lang.String[] |
attributeNames(FeatureType featureType,
Filter filter)
Gets the list of attribute names required for both featureType and filter |
protected AttributeReader[] |
buildAttributeReaders(AttributeType[] attrTypes,
JDBCDataStore.QueryData queryData)
Builds the AttributeReaders from the QueryData and the array of attribute types. |
protected AttributeType |
buildAttributeType(java.sql.ResultSet rs)
Constructs an AttributeType from a row in a ResultSet. |
protected AttributeWriter[] |
buildAttributeWriters(AttributeType[] attrTypes,
JDBCDataStore.QueryData queryData)
|
protected static void |
close(java.sql.Connection conn,
Transaction transaction,
java.sql.SQLException sqlException)
A utility method for closing a Connection. |
protected static void |
close(java.sql.ResultSet rs)
A utility method for closing a ResultSet. |
protected static void |
close(java.sql.Statement statement)
A utility method for closing a Statement. |
protected FeatureReader |
createFeatureReader(FeatureType schema,
Filter postFilter,
JDBCDataStore.QueryData queryData)
Create a new FeatureReader based on attributeReaders. |
protected JDBCDataStore.JDBCFeatureWriter |
createFeatureWriter(FeatureReader fReader,
AttributeWriter writer,
JDBCDataStore.QueryData queryData)
|
protected abstract AttributeReader |
createGeometryReader(AttributeType attrType,
JDBCDataStore.QueryData queryData,
int index)
Hook to create the geometry reader for a vendor specific data source. |
protected abstract AttributeWriter |
createGeometryWriter(AttributeType attrType,
JDBCDataStore.QueryData queryData,
int index)
|
protected LockingManager |
createLockingManager()
Allows subclass to create LockingManager to support their needs. |
protected AttributeReader |
createResultSetReader(AttributeType[] attrType,
JDBCDataStore.QueryData queryData,
int startIndex,
int endIndex)
|
protected AttributeWriter |
createResultSetWriter(AttributeType[] attrType,
JDBCDataStore.QueryData queryData,
int startIndex,
int endIndex)
|
void |
createSchema(FeatureType featureType)
Create a new featureType. |
protected java.lang.String |
determineFidColumnName(java.lang.String typeName)
Provides the default implementation of determining the FID column. |
protected int |
determineSRID(java.lang.String tableName,
java.lang.String geometryColumnName)
Provides a hook for subclasses to determine the SRID of a geometry column. |
protected JDBCDataStore.QueryData |
executeQuery(java.lang.String tableName,
java.lang.String sqlQuery,
Transaction transaction,
int concurrency)
Executes the SQL Query. |
protected AttributeType[] |
getAttributeTypes(java.lang.String typeName,
java.lang.String[] propertyNames)
|
protected java.sql.Connection |
getConnection(Transaction transaction)
Gets a connection from the connection pool. |
FeatureReader |
getFeatureReader(FeatureType requestType,
Filter filter,
Transaction transaction)
This is a public entry point to the DataStore. |
FeatureReader |
getFeatureReader(Query query,
Transaction trans)
The top level method for getting a FeatureReader. |
FeatureSource |
getFeatureSource(java.lang.String typeName)
Default implementation based on getFeatureReader and getFeatureWriter. |
protected JDBCDataStore.FeatureTypeInfo |
getFeatureTypeInfo(java.lang.String featureTypeName)
Retreives the FeatureTypeInfo object for a FeatureType. |
FeatureWriter |
getFeatureWriter(java.lang.String typeName,
Filter filter,
Transaction transaction)
Aquire FetureWriter for modification of contents specifed by filter. |
FeatureWriter |
getFeatureWriter(java.lang.String typeName,
Transaction transaction)
Retrieve a FeatureWriter over entire dataset. |
FeatureWriter |
getFeatureWriterAppend(java.lang.String typeName,
Transaction transaction)
Retrieve a FeatureWriter for creating new content. |
LockingManager |
getLockingManager()
Locking manager used for this DataStore. |
java.lang.String |
getNameSpace()
Gets the namespace of the data store. |
FeatureType |
getSchema(java.lang.String typeName)
Retrieve FeatureType metadata by typeName . |
SQLBuilder |
getSqlBuilder(java.lang.String typeName)
Hook for subclass to return a different sql builder. |
java.lang.String[] |
getTypeNames()
Retrieves a list of of the available FeatureTypes |
FeatureSource |
getView(Query query)
|
void |
updateSchema(java.lang.String typeName,
FeatureType featureType)
Used to provide support for changing the DataStore Schema. |
Methods inherited from class java.lang.Object |
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
Field Detail |
protected static final java.util.Map TYPE_MAPPINGS
These mappings were taken from http://java.sun.com/j2se/1.3/docs/guide/jdbc/getstart/mapping.html#997737
public FeatureListenerManager listenerManager
Constructor Detail |
public JDBCDataStore(ConnectionPool connectionPool) throws java.io.IOException
public JDBCDataStore(ConnectionPool connectionPool, java.lang.String databaseSchemaName) throws java.io.IOException
public JDBCDataStore(ConnectionPool connectionPool, java.lang.String databaseSchemaName, java.lang.String namespace) throws java.io.IOException
Method Detail |
protected LockingManager createLockingManager()
public java.lang.String[] getTypeNames()
DataStore
This is simply a list of the FeatureType names as aquiring the actual FeatureType schemas may be expensive.
getTypeNames
in interface DataStore
public FeatureType getSchema(java.lang.String typeName) throws java.io.IOException
DataStore
typeName
.
Retrieves the Schema information as a FeatureType object.
getSchema
in interface DataStore
typeName
- typeName of requested FeatureType
java.io.IOException
- If typeName cannot be foundpublic void createSchema(FeatureType featureType) throws java.io.IOException
Not currently supported - subclass may implement.
createSchema
in interface DataStore
featureType
-
java.io.IOException
java.lang.UnsupportedOperationException
- DOCUMENT ME!DataStore.createSchema(org.geotools.feature.FeatureType)
public void updateSchema(java.lang.String typeName, FeatureType featureType) throws java.io.IOException
Specifically this is intended to address updating the metadata Coordinate System information.
If we can figure out the Catalog API for metadata we will not have to use such a heavy handed approach.
Subclasses are free to implement various levels of support:
updateSchema
in interface DataStore
typeName
-
java.io.IOException
DataStore.updateSchema(java.lang.String, org.geotools.feature.FeatureType)
public FeatureSource getView(Query query) throws java.io.IOException, SchemaException
java.io.IOException
SchemaException
public FeatureSource getFeatureSource(java.lang.String typeName) throws java.io.IOException
We should be able to optimize this to only get the RowSet once
getFeatureSource
in interface DataStore
typeName
-
java.io.IOException
DataStore.getFeatureSource(java.lang.String)
public FeatureReader getFeatureReader(FeatureType requestType, Filter filter, Transaction transaction) throws java.io.IOException
We have given some though to changing this api to be based on query.
Currently the is is the only way to retype your features to different name spaces.
(non-Javadoc)
getFeatureReader
in interface DataStore
requestType
- Describes the form of the returned Featuresfilter
- Constraints used to limit the resultstransaction
- Transaction this query opperates against
java.io.IOException
DataStore.getFeatureReader(org.geotools.feature.FeatureType,
org.geotools.filter.Filter, org.geotools.data.Transaction)
protected java.lang.String[] attributeNames(FeatureType featureType, Filter filter) throws java.io.IOException
featureType
- DOCUMENT ME!filter
- DOCUMENT ME!
java.io.IOException
- DOCUMENT ME!public FeatureReader getFeatureReader(Query query, Transaction trans) throws java.io.IOException
Chris- I've gone with the Query object aswell. It just seems to make more sense. This is pretty well split up across methods. The hooks for DB specific AttributeReaders are createResultSetReader and createGeometryReader.
JG- I have implemented getFeatureReader( FeatureType, Filter, Transasction) ontop of this method, it will Retype as required
query
- trans
-
java.io.IOException
- DOCUMENT ME!
DataSourceException
protected FeatureReader createFeatureReader(FeatureType schema, Filter postFilter, JDBCDataStore.QueryData queryData) throws java.io.IOException
The provided schema
describes the attributes in the
queryData ResultSet. This schema should cover the requirements of
filter
.
Retyping to the users requested Schema will not happen in this method.
schema
- postFilter
- Filter for post processing, or null
if
not requried.queryData
- Holds a ResultSet for attribute Readers
java.io.IOException
DataSourceException
- DOCUMENT ME!protected final AttributeReader[] buildAttributeReaders(AttributeType[] attrTypes, JDBCDataStore.QueryData queryData) throws java.io.IOException
Subclasses can provide custom attribute readers for the basic types by overriding createResultSetReader(). createResultSetReader has parameters that define a range of columns in the Result to read. The default implementation of this method creates a RangedResultSetAttributeReader instance.
Subclasses must provide a geometry attribute reader by implementing createGeometryReader(). This must provide an AttributeReader capable of reading a geometry at a single column. This will be called when isGeometry() on a attribute returns true.
TODO: Should this be final??
attrTypes
- The attribute types to create a list of
AttributeReaders for.queryData
- The Query result resources for the readers.
java.io.IOException
- If an error occurs building the readers. It seems
to make sense that if we can't get readers for all the
attribute we shoudl bomb out. (??)protected final JDBCDataStore.QueryData executeQuery(java.lang.String tableName, java.lang.String sqlQuery, Transaction transaction, int concurrency) throws java.io.IOException
This is private in the expectation that subclasses should not need to change this behaviour.
Jody with a question here - I have stopped this method from closing connection shared by a Transaction. It sill seems like we are leaving connections open by using this method. I have also stopped QueryData from doing the same thing.
Answer from Sean: Resources for successful queries are closed when close is called on the AttributeReaders constructed with the QueryData. We can't close them here since they need to be open to read from the ResultSet.
Jody AttributeReader question: I looked at the code and Attribute Readers do not close with respect to Transactions (they need to as we can issue a Reader against a Transaction. I have changed the JDBCDataStore.close method to force us to keep track of these things.
SG: I've marked this as final since I don't think it shoudl be overriden, but Im not sure
tableName
- DOCUMENT ME!sqlQuery
- The SQL query to execute.transaction
- The Transaction is included here for handling
transaction connections at a later stage. It is not currently
used.concurrency
- DOCUMENT ME!
java.io.IOException
- DOCUMENT ME!
DataSourceException
- If an error occurs performing the query.public SQLBuilder getSqlBuilder(java.lang.String typeName) throws java.io.IOException
typeName
- The typename for the sql builder.
java.io.IOException
- if anything goes wrong.protected AttributeReader createResultSetReader(AttributeType[] attrType, JDBCDataStore.QueryData queryData, int startIndex, int endIndex)
protected AttributeWriter createResultSetWriter(AttributeType[] attrType, JDBCDataStore.QueryData queryData, int startIndex, int endIndex)
protected abstract AttributeReader createGeometryReader(AttributeType attrType, JDBCDataStore.QueryData queryData, int index) throws java.io.IOException
attrType
- The AttributeType to read.queryData
- The data containing the result of the query.index
- The index within the result set to read the data from.
DataSourceException
- If an error occurs building the
AttributeReader.
java.io.IOException
protected abstract AttributeWriter createGeometryWriter(AttributeType attrType, JDBCDataStore.QueryData queryData, int index) throws java.io.IOException
java.io.IOException
protected final java.sql.Connection getConnection(Transaction transaction) throws java.io.IOException
transaction
- DOCUMENT ME!
java.io.IOException
- DOCUMENT ME!
DataSourceException
- If the connection is not an
OracleConnection.protected static void close(java.sql.Connection conn, Transaction transaction, java.sql.SQLException sqlException)
Connections are maintained by a Transaction and we will need to manage them with respect to their Transaction.
Jody here - I am forcing this to be explicit, by requiring you give the Transaction context when you close a connection seems to be the only way to hunt all the cases down. AttributeReaders based on QueryData rely on
I considered accepting an error flag to control Transaction rollback, but I really only want to capture SQLException that force transaction rollback.
conn
- The Connection to close. This can be null since it makes it
easy to close connections in a finally block.transaction
- Context for the connection, we will only close the
connection for Transaction.AUTO_COMMITsqlException
- Error status, null
for no errorprotected static void close(java.sql.ResultSet rs)
rs
- The ResultSet to close. This can be null since it makes it
easy to close result sets in a finally block.protected static void close(java.sql.Statement statement)
statement
- The statement to close. This can be null since it makes
it easy to close statements in a finally block.protected boolean allowTable(java.lang.String tablename)
tablename
- A table name to check.
protected AttributeType buildAttributeType(java.sql.ResultSet rs) throws java.sql.SQLException, DataSourceException
The default implementation construct an AttributeType using the default JDBC type mappings defined in JDBCDataStore. These type mappings only handle native Java classes and SQL standard column types, so to handle Geometry columns, sub classes should override this to check if a column is a geometry column, if it is a geometry column the appropriate determination of the geometry type can be performed. Otherwise, overriding methods should call super.buildAttributeType.
Note: Overriding methods must never move the current row pointer in the result set.
rs
- The ResultSet containing the result of a
DatabaseMetaData.getColumns call.
java.sql.SQLException
- If an error occurs processing the ResultSet.
DataSourceException
- Provided for overriding classes to wrap
exceptions caused by other operations they may perform to
determine additional types. This will only be thrown by the
default implementation if a type is present that is not present
in the TYPE_MAPPINGS.protected int determineSRID(java.lang.String tableName, java.lang.String geometryColumnName) throws java.io.IOException
This allows SRIDs to be determined in a Vendor specific way and to be cached by the default implementation. To retreive these srids, get the FeatureTypeInfo object for the table and call getSRID(geometryColumnName). This will allow storage of SRIDs for multiple geometry columns in each table.
If no SRID can be found, subclasses should return -1. The default implementation always returns -1.
tableName
- The name of the table to get the SRID for.geometryColumnName
- The name of the geometry column within the
table to get SRID for.
java.io.IOException
- DOCUMENT ME!protected java.lang.String determineFidColumnName(java.lang.String typeName) throws java.io.IOException
The default implementation of determining the FID column name is to use the primary key as the FID column. If no primary key is present, null will be returned. Sub classes can override this behaviour to define primary keys for vendor specific cases.
There is an unresolved issue as to what to do when there are multiple primary keys. Maybe a restriction that table much have a single column primary key is appropriate.
This should not be called by subclasses to retreive the FID column name. Instead, subclasses should call getFeatureTypeInfo(String) to get the FeatureTypeInfo for a feature type and get the fidColumn name from the fidColumn name memeber.
typeName
- The name of the table to get a primary key for.
java.io.IOException
- This will only occur if there is an error getting a
connection to the Database.public java.lang.String getNameSpace()
protected final JDBCDataStore.FeatureTypeInfo getFeatureTypeInfo(java.lang.String featureTypeName) throws java.io.IOException
This allows subclasses to get access to the information about a feature type, this includes the schema and the fidColumnName.
featureTypeName
- The name of the feature type to get the info for.
java.io.IOException
- If an error occurs creating the FeatureTypeInfo.public FeatureWriter getFeatureWriter(java.lang.String typeName, Transaction transaction) throws java.io.IOException
Quick notes: This FeatureWriter is often used to add new content, or perform summary calculations over the entire dataset.
Subclass may wish to implement an optimized featureWriter for these operations.
It should provide Feature for next() even when hasNext() is
false
.
Subclasses are responsible for checking with the lockingManger unless they are providing their own locking support.
getFeatureWriter
in interface DataStore
typeName
- transaction
-
java.io.IOException
java.lang.UnsupportedOperationException
- DOCUMENT ME!org.geotools.data.DataStore#getFeatureWriter(java.lang.String,
boolean, org.geotools.data.Transaction)
public FeatureWriter getFeatureWriterAppend(java.lang.String typeName, Transaction transaction) throws java.io.IOException
Subclass may wish to implement an optimized featureWriter for this operation. One based on prepaired statemnts is a possibility, as we do not require a ResultSet.
To allow new content the FeatureWriter should provide Feature for next()
even when hasNext() is false
.
Subclasses are responsible for checking with the lockingManger unless they are providing their own locking support.
getFeatureWriterAppend
in interface DataStore
typeName
- transaction
-
java.io.IOException
java.lang.UnsupportedOperationException
- DOCUMENT ME!org.geotools.data.DataStore#getFeatureWriter(java.lang.String,
boolean, org.geotools.data.Transaction)
public FeatureWriter getFeatureWriter(java.lang.String typeName, Filter filter, Transaction transaction) throws java.io.IOException
Quick notes: This FeatureWriter is often used to remove contents specified by the provided filter, or perform summary calculations.
It is not used to provide new content and should return null
for next() when hasNext() returns false
.
Subclasses are responsible for checking with the lockingManger unless they are providing their own locking support.
getFeatureWriter
in interface DataStore
typeName
- filter
- transaction
-
java.io.IOException
- If typeName could not be located
java.lang.NullPointerException
- If the provided filter is null
DataSourceException
- See IOExceptionDataStore.getFeatureWriter(java.lang.String,
org.geotools.filter.Filter, org.geotools.data.Transaction)
protected JDBCDataStore.JDBCFeatureWriter createFeatureWriter(FeatureReader fReader, AttributeWriter writer, JDBCDataStore.QueryData queryData) throws java.io.IOException
java.io.IOException
protected final AttributeWriter[] buildAttributeWriters(AttributeType[] attrTypes, JDBCDataStore.QueryData queryData) throws java.io.IOException
java.io.IOException
protected AttributeType[] getAttributeTypes(java.lang.String typeName, java.lang.String[] propertyNames) throws java.io.IOException, SchemaException
java.io.IOException
SchemaException
public LockingManager getLockingManager()
By default AbstractDataStore makes use of InProcessLockingManager.
getLockingManager
in interface DataStore
DataStore.getLockingManager()
|
|||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |