|
|||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object org.geotools.data.jdbc.JDBC1DataStore
Abstract class for JDBC based 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. getGeometryAttributeIO(AttributeType, QueryData)
- Should be overriden to
provide a way to read/write geometries into the format of the database Additionally subclasses can optionally override the following:
buildFIDMapperFactory(JDBCDataStoreConfig)
method, and eventually disallow
user overrides by throwing an UnsupportedOperationException
in the
setFidMapperFactory()
method.
allowTable
- Used to determine whether a
table name should be exposed as a 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.
getResultSetType
if the standard
result set type is not satisfactory/does not work with a normal FORWARD_ONLY
resultset type getConcurrency
to set the level of
concurrency for the result set used to read/write the database Additionally subclasses may want to set the value of:
Field Summary | |
protected boolean |
allowWriteOnVolatileFIDs
When true, writes are allowed also on tables with volatile FID mappers. |
protected JDBCDataStoreConfig |
config
|
FeatureListenerManager |
listenerManager
Manages listener lists for FeatureSource implementations |
protected static java.util.logging.Logger |
LOGGER
The logger for the filter module. |
protected java.lang.String |
sqlNameEscape
The character(s) to surround schema, table and column names an SQL query to support mixed-case and non-English names |
protected static java.util.Map |
TYPE_MAPPINGS
Maps SQL types to Java classes. |
protected FeatureTypeHandler |
typeHandler
|
Constructor Summary | |
JDBC1DataStore(JDBCDataStoreConfig config)
Construct a JDBCDataStore with ConnectionPool and associated configuration. |
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. |
boolean |
allSameOrder(java.lang.String[] requestedNames,
FeatureType ft)
returns true if the requested names list all the attributes in the correct order. |
protected java.lang.String[] |
attributeNames(FeatureType featureType,
Filter filter)
Gets the list of attribute names required for both featureType and filter |
protected AttributeType |
buildAttributeType(java.sql.ResultSet rs)
Constructs an AttributeType from a row in a ResultSet. |
protected FIDMapperFactory |
buildFIDMapperFactory(JDBCDataStoreConfig config)
|
protected FeatureType |
buildSchema(java.lang.String typeName,
FIDMapper mapper)
Builds the schema for a table in the database. |
protected abstract java.sql.Connection |
createConnection()
Create a connection for your JDBC1 database |
protected FeatureReader |
createFeatureReader(FeatureType schema,
Filter postFilter,
QueryData queryData)
Create a new FeatureReader based on attributeReaders. |
protected JDBCFeatureWriter |
createFeatureWriter(FeatureReader reader,
QueryData queryData)
|
protected LockingManager |
createLockingManager()
Allows subclass to create LockingManager to support their needs. |
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 QueryData |
executeQuery(FeatureTypeInfo featureTypeInfo,
java.lang.String tableName,
java.lang.String sqlQuery,
Transaction transaction,
boolean forWrite)
Executes the SQL Query. |
protected AttributeIO |
getAttributeIO(AttributeType type)
Returns the basic AttributeIO that can read and write all of the simple data types |
protected AttributeType[] |
getAttributeTypes(java.lang.String typeName,
java.lang.String[] propertyNames)
Gets the attribute types from from a given type. |
protected int |
getConcurrency(boolean forWrite)
|
protected java.sql.Connection |
getConnection(Transaction transaction)
Gets a connection for the provided transaction. |
com.vividsolutions.jts.geom.Envelope |
getEnvelope(java.lang.String typeName)
Retrieve approx bounds of all Features. |
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 FeatureTypeHandler |
getFeatureTypeHandler(JDBCDataStoreConfig config)
DOCUMENT ME! |
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. |
FIDMapper |
getFIDMapper(java.lang.String tableName)
|
FIDMapperFactory |
getFIDMapperFactory()
Returns the FIDMapperFactory used for this data store |
protected abstract AttributeIO |
getGeometryAttributeIO(AttributeType type,
QueryData queryData)
Hook to create the geometry attribute IO for a vendor specific data source. |
protected JDBCFeatureReader |
getJDBCFeatureReader(QueryData queryData)
|
LockingManager |
getLockingManager()
Locking manager used for this DataStore. |
java.net.URI |
getNameSpace()
Gets the namespace of the data store. |
protected int |
getResultSetType(boolean forWrite)
|
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 |
getSqlNameEscape()
Gets the SQL name escape string. |
java.lang.String[] |
getTypeNames()
Retrieves a list of of the available FeatureTypes. |
FeatureSource |
getView(Query query)
Access a FeatureSource for Query providing a high-level API. |
protected void |
setAutoCommit(boolean forWrite,
java.sql.Connection conn)
This method should be overridden to do nothing by DataStores where setting autoCommit causes funky behaviour (ie. anytime autoCommit is changed, every thing up to that point is committed...this isn't good at this stage) |
void |
setFIDMapper(java.lang.String featureTypeName,
FIDMapper fidMapper)
Sets the FIDMapper for a specific type name |
void |
setFIDMapperFactory(FIDMapperFactory fmFactory)
Allows to override the default FIDMapperFactory. |
protected void |
setSqlNameEscape(java.lang.String sqlNameEscape)
Sets the SQL name escape string. |
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.logging.Logger LOGGER
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
protected final JDBCDataStoreConfig config
protected FeatureTypeHandler typeHandler
protected java.lang.String sqlNameEscape
protected boolean allowWriteOnVolatileFIDs
FIDMapper.isVolatile()
Constructor Detail |
public JDBC1DataStore(JDBCDataStoreConfig config) throws java.io.IOException
config
-
java.io.IOException
Method Detail |
public java.lang.String getSqlNameEscape()
The value of this string is prefixed and appended to table schema names, table names and column names in an SQL statement to support mixed-case and non-English names.
protected void setSqlNameEscape(java.lang.String sqlNameEscape)
The value of this string is prefixed and appended to table schema names, table names and column names in an SQL statement to support mixed-case and non-English names.
This value is typically only set once when the DataStore implementation class is constructed.
sqlNameEscape
- the name escape characterprotected FeatureTypeHandler getFeatureTypeHandler(JDBCDataStoreConfig config) throws java.io.IOException
config
-
java.io.IOException
- DOCUMENT ME!protected FIDMapperFactory buildFIDMapperFactory(JDBCDataStoreConfig config)
public FIDMapper getFIDMapper(java.lang.String tableName) throws java.io.IOException
java.io.IOException
protected LockingManager createLockingManager()
public java.lang.String[] getTypeNames() throws java.io.IOException
DataStore
This is simply a list of the FeatureType names as aquiring the actual FeatureType schemas may be expensive.
Warning: this list may not be unique - the types may be in separate namespaces.
If you need to worry about such things please consider the use of the Catalog and CatalogEntry interface - many DataStores support this. getTypeNames is really a convience method for a Catalog.iterator() where the name of each entry is returned.
getTypeNames
in interface DataStore
java.io.IOException
org.geotools.data.DataStore#getFeatureTypes()
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 foundDataStore.getSchema(java.lang.String)
public 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
- Creating new schemas is not supported.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
DataStore
The provided Query does not need to completely cover the existing schema for Query.getTypeName(). The result will mostly likely only be a FeatureSource and probably wont' allow write access by the FeatureStore method.
By using Query we allow support for reprojection, in addition to overriding the CoordinateSystem used by the native FeatureType.
We may wish to limit this method to only support Queries using Filter.ALL.
Update - GeoServer has an elegatent implementation of this functionality that we could steal. GeoServerFeatureSource, GeoServerFeatureStore and GeoServerFeatureLocking serve as a working prototype.
getView
in interface DataStore
SchemaException
- If fetureType is not covered by existing schema
java.io.IOException
- If FeatureSource is not availablepublic 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)
java.io.IOException
org.geotools.data.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
- The FeatureType to get attribute names for.filter
- The filter which needs attributes to filter.
java.io.IOException
- If we can't get the schema.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
getFeatureReader
in interface DataStore
query
- The Query to get a FeatureReader for.trans
- The transaction this read operation is being performed in.
java.io.IOException
- If an error occurs executing the query.
DataSourceException
protected FeatureReader createFeatureReader(FeatureType schema, Filter postFilter, 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
protected JDBCFeatureReader getJDBCFeatureReader(QueryData queryData) throws java.io.IOException
java.io.IOException
protected AttributeIO getAttributeIO(AttributeType type)
type
-
protected abstract AttributeIO getGeometryAttributeIO(AttributeType type, QueryData queryData) throws java.io.IOException
type
- The AttributeType to read.queryData
- The connection holder
java.io.IOException
- DOCUMENT ME!protected QueryData executeQuery(FeatureTypeInfo featureTypeInfo, java.lang.String tableName, java.lang.String sqlQuery, Transaction transaction, boolean forWrite) 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
featureTypeInfo
- tableName
- 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.forWrite
-
java.io.IOException
DataSourceException
- If an error occurs performing the query.protected void setAutoCommit(boolean forWrite, java.sql.Connection conn) throws java.sql.SQLException
forWrite
- conn
-
java.sql.SQLException
protected int getResultSetType(boolean forWrite)
protected int getConcurrency(boolean forWrite)
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 java.sql.Connection getConnection(Transaction transaction) throws java.io.IOException
transaction
-
java.io.IOException
DataSourceException
- If the connection can not be obtained.protected abstract java.sql.Connection createConnection() throws java.sql.SQLException
java.sql.SQLException
protected boolean allowTable(java.lang.String tablename)
tablename
- A table name to check.
protected FeatureType buildSchema(java.lang.String typeName, FIDMapper mapper) throws java.io.IOException
This works by retrieving the column information for the table from the DatabaseMetaData object. It then iterates over the information for each column, calling buildAttributeType(ResultSet) to construct an AttributeType for each column. The list of attribute types is then turned into a FeatureType that defines the schema.
It is not intended that this method is overriden. It should provide the required functionality for most sub-classes. To add AttributeType construction for vendor specific SQL types, such as geometries, override the buildAttributeType(ResultSet) method.
This may become final later. In fact Ill make it private because I don't think It will need to be overriden.
typeName
- The name of the table to construct a feature type for.mapper
- The name of the column holding the fid.
java.io.IOException
DataSourceException
- This can occur if there is an SQL error or an error
constructing the FeatureType.buildAttributeType(ResultSet)
protected AttributeType buildAttributeType(java.sql.ResultSet rs) throws java.io.IOException
The default implementation constructs 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.io.IOException
- If an error occurs processing the ResultSet.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
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.net.URI getNameSpace()
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
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
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
DataStore.getFeatureWriter(java.lang.String,
org.geotools.filter.Filter, org.geotools.data.Transaction)
protected JDBCFeatureWriter createFeatureWriter(FeatureReader reader, QueryData queryData) throws java.io.IOException
java.io.IOException
protected final AttributeType[] getAttributeTypes(java.lang.String typeName, java.lang.String[] propertyNames) throws java.io.IOException, SchemaException
typeName
- The name of the feature type to get the AttributeTypes for.propertyNames
- The list of propertyNames to get AttributeTypes for.
java.io.IOException
- If we can't get the schema.
SchemaException
- if query contains a propertyName that is not a part of this
type's schema.public LockingManager getLockingManager()
By default AbstractDataStore makes use of InProcessLockingManager.
getLockingManager
in interface DataStore
DataStore.getLockingManager()
public void setFIDMapper(java.lang.String featureTypeName, FIDMapper fidMapper)
featureTypeName
- fidMapper
- public FIDMapperFactory getFIDMapperFactory()
public void setFIDMapperFactory(FIDMapperFactory fmFactory) throws java.lang.UnsupportedOperationException
Warning: the ovveride may not be supported by all data stores, in this case an exception will be thrown
fmFactory
-
java.lang.UnsupportedOperationException
- -
if the datastore does not allow the factory overridepublic boolean allSameOrder(java.lang.String[] requestedNames, FeatureType ft)
requestedNames
- ft
-
public com.vividsolutions.jts.geom.Envelope getEnvelope(java.lang.String typeName)
This result is suitable for a quick map display, illustrating the data. This value is often stored as metadata in databases such as oraclespatial.
|
|||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |