Class Database<G>
- Type Parameters:
G
- the type of geometry objects. Depends on the backing implementation (ESRI, JTS, Java2D…).
- Direct Known Subclasses:
Postgres
ResultSet.getInt(int)
and wraps the result in an Integer
if it was not null) or can be a more
complex process (e.g. decode a geometry Well-Known Binary). This class does not perform the conversions directly,
but instead provides a converter object for each specified SQL type.
This base class provides mapping for common types (text, numbers, temporal objects, etc.) and for geometry types as specified in OpenGIS® Implementation Standard for Geographic information — Simple feature access — Part 2: SQL option. Subclasses can override some functions if a particular database software (e.g. PostGIS) provides specialized methods or have non-standard behavior for some data types.
Specializations
Subclasses may be defined for some database engines. Methods that can be overridden are:getMapping(Column)
for adding column types to recognize.createInfoStatements(Connection)
for more info about spatial information.addIgnoredTables(Map)
for specifying more tables to ignore.
Multi-threading
This class is safe for concurrent use by many threads. This class does not hold JDBC resources such asConnection
. Those resources are created temporarily when needed by InfoStatements
.
Schema updates
Current implementation does not track changes in the database schema. if the database schema changes, then a newDatabase
instance shall be created.- Since:
- 1.1
- Version:
- 1.2
-
Field Summary
FieldsModifier and TypeFieldDescriptionCache of Coordinate Reference Systems created for a given SRID.(package private) final WeakHashMap<org.opengis.referencing.crs.CoordinateReferenceSystem,
Integer> Cache of SRID for a given Coordinate Reference System.(package private) String
Catalog and schema of the "GEOMETRY_COLUMNS" and "SPATIAL_REF_SYS" tables, or null or empty string if none.private SelectionClauseWriter
The converter from filters/expressions to theWHERE
part of SQL statement.(package private) final Geometries<G>
The factory to use for creating geometric objects.private boolean
true
if this database contains at least one geometry column.private boolean
true
if this database contains at least one raster column.private final boolean
WhetherTypes.TINYINT
is a signed integer.private boolean
Whether the database contains "GEOMETRY_COLUMNS" and/or "SPATIAL_REF_SYS" tables.final StoreListeners
Where to send warnings.(package private) String
Catalog and schema of the "GEOMETRY_COLUMNS" and "SPATIAL_REF_SYS" tables, or null or empty string if none.protected final DataSource
Provider of (pooled) connections to the database.(package private) final boolean
Whether catalog or schema are supported.(package private) final boolean
Whether catalog or schema are supported.private Table[]
All tables known to thisDatabase
in declaration order.private final FeatureNaming<Table>
All tables known to thisDatabase
.static final String
The SQL wildcard for any characters. -
Constructor Summary
ConstructorsModifierConstructorDescriptionprotected
Database
(DataSource source, DatabaseMetaData metadata, Geometries<G> geomLibrary, StoreListeners listeners) Creates a new handler for a spatial database. -
Method Summary
Modifier and TypeMethodDescriptionprotected void
addIgnoredTables
(Map<String, Boolean> ignoredTables) Adds to the given map a list of tables to ignore when searching for feature tables.private void
analyze
(SQLStore store, Connection connection, org.opengis.util.GenericName[] tableNames, ResourceDefinition[] queries, SchemaModifier customizer) Creates a model about the specified tables in the database.final void
appendFunctionCall
(SQLBuilder sql, String function) Appends a call to a function defined in the spatial schema.(package private) final void
appendTo
(TreeTable.Node parent) Creates a tree representation of this database for debugging purpose.static Database<?>
create
(SQLStore store, DataSource source, Connection connection, GeometryLibrary geomLibrary, org.opengis.util.GenericName[] tableNames, ResourceDefinition[] queries, SchemaModifier customizer, StoreListeners listeners) Creates a new handler for a spatial database.protected InfoStatements
createInfoStatements
(Connection connection) Prepares a cache of statements about spatial information using the given connection.final FeatureSet
Returns the table for the given name.protected final ValueGetter<?>
forGeometry
(Column columnDefinition) Returns a function for getting values from a geometry or geography column.protected int
getArrayComponentType
(Column columnDefinition) Returns the type of components in SQL arrays stored in a column.protected BinaryEncoding
getBinaryEncoding
(Column columnDefinition) Returns an identifier of the way binary data are encoded by the JDBC driver.protected ValueGetter<Object>
Returns a mapping forTypes.JAVA_OBJECT
or unrecognized types.protected org.opengis.geometry.Envelope
getEstimatedExtent
(TableReference table, Column[] columns, boolean recall) Computes an estimation of the envelope of all geometry columns in the given table.protected SelectionClauseWriter
Returns the converter from filters/expressions to theWHERE
part of SQL statement.(package private) final SelectionClauseWriter
Returns the converter from filters/expressions to theWHERE
part of SQL statement without the functions that are unsupported by the database software.protected ValueGetter<?>
getMapping
(Column columnDefinition) Returns a function for getting values from a column having the given definition.private static String[]
getTableTypes
(DatabaseMetaData metadata) Returns the "TABLE" and "VIEW" keywords for table types, with unsupported keywords omitted.final boolean
Returnstrue
if this database contains at least one geometry column.final boolean
Returnstrue
if this database contains at least one raster column.private boolean
Returnstrue
if the database contains at least one specified tables associated toBoolean.TRUE
.final boolean
Returnstrue
if this database is a spatial database.final void
listTables
(DatabaseMetaData metadata, MetadataBuilder builder) Stores information about tables in the given metadata.protected final void
Sets the logger, class and method names of the given record, then logs it.final List<FeatureSet>
tables()
Returns all tables in declaration order.toString()
Formats a graphical representation of this database for debugging purpose.
-
Field Details
-
WILDCARD
The SQL wildcard for any characters. A string containing only this wildcard means "any value" and can sometimes be replaced bynull
.- See Also:
-
source
Provider of (pooled) connections to the database. -
geomLibrary
The factory to use for creating geometric objects. For example, the geometry implementations may be ESRI, JTS or Java2D objects. -
isByteSigned
private final boolean isByteSignedWhetherTypes.TINYINT
is a signed integer. Both conventions (-128 … 127 range and 0 … 255 range) are found on the web. If unspecified, we conservatively assume unsigned bytes. All other integer types are presumed signed. -
tablesByNames
All tables known to thisDatabase
. Populated in the constructor, and shall not be modified after construction for preserving thread-safety. -
tables
All tables known to thisDatabase
in declaration order. This array contains only the tables specified at initialization time, not the dependencies. This field is initialized by#analyze(SQLStore, Connection, ResourceDefinition...)
and shall not be modified after that point. -
isSpatial
private boolean isSpatialWhether the database contains "GEOMETRY_COLUMNS" and/or "SPATIAL_REF_SYS" tables. May also be set totrue
if some database-specific tables are found such as"geography_columns"
and"raster_columns"
in PostGIS. This field is initialized byanalyze(…)
and shall not be modified after that point.- See Also:
-
hasGeometry
private boolean hasGeometrytrue
if this database contains at least one geometry column. This field is initialized byanalyze(…)
and shall not be modified after that point.- See Also:
-
hasRaster
private boolean hasRastertrue
if this database contains at least one raster column. This field is initialized byanalyze(…)
and shall not be modified after that point.- See Also:
-
catalogOfSpatialTables
String catalogOfSpatialTablesCatalog and schema of the "GEOMETRY_COLUMNS" and "SPATIAL_REF_SYS" tables, or null or empty string if none. -
schemaOfSpatialTables
String schemaOfSpatialTablesCatalog and schema of the "GEOMETRY_COLUMNS" and "SPATIAL_REF_SYS" tables, or null or empty string if none. -
supportsCatalogs
final boolean supportsCatalogsWhether catalog or schema are supported. -
supportsSchemas
final boolean supportsSchemasWhether catalog or schema are supported. -
filterToSQL
The converter from filters/expressions to theWHERE
part of SQL statement. This is initialized when first needed, then kept unmodified for the database lifetime. Subclasses may provide a specialized instance if their database supports an extended syntax for some filters or expressions.- See Also:
-
listeners
Where to send warnings.- See Also:
-
cacheOfCRS
Cache of Coordinate Reference Systems created for a given SRID. SRID are primary keys in the "SPATIAL_REF_SYS" table. They are not EPSG codes, even if the numerical values are often the same.This mapping depend on the content of "SPATIAL_REF_SYS" table. For that reason, a distinct cache exists for each database.
-
cacheOfSRID
Cache of SRID for a given Coordinate Reference System. This is the converse ofcacheOfCRS
. Accesses to this map must be synchronized on the map itself.
-
-
Constructor Details
-
Database
protected Database(DataSource source, DatabaseMetaData metadata, Geometries<G> geomLibrary, StoreListeners listeners) throws SQLException Creates a new handler for a spatial database.- Parameters:
source
- provider of (pooled) connections to the database.metadata
- metadata about the database.geomLibrary
- the factory to use for creating geometric objects.listeners
- where to send warnings.- Throws:
SQLException
- if an error occurred while reading database metadata.
-
-
Method Details
-
create
public static Database<?> create(SQLStore store, DataSource source, Connection connection, GeometryLibrary geomLibrary, org.opengis.util.GenericName[] tableNames, ResourceDefinition[] queries, SchemaModifier customizer, StoreListeners listeners) throws Exception Creates a new handler for a spatial database.- Parameters:
store
- the data store for which we are creating a model. Used only in case of error.source
- provider of (pooled) connections to the database.connection
- connection to the database. Sometimes the caller already has a connection at hand.geomLibrary
- the factory to use for creating geometric objects.tableNames
- qualified name of the tables. Specified by users at construction time.queries
- additional resources associated to SQL queries. Specified by users at construction time.customizer
- user-specified modification to the features, ornull
if none.listeners
- where to send warnings.- Returns:
- handler for the spatial database.
- Throws:
SQLException
- if a database error occurred while reading metadata.DataStoreException
- if a logical error occurred while analyzing the database structure.Exception
-
analyze
private void analyze(SQLStore store, Connection connection, org.opengis.util.GenericName[] tableNames, ResourceDefinition[] queries, SchemaModifier customizer) throws Exception Creates a model about the specified tables in the database. This method shall be invoked exactly once afterDatabase
construction. It requires a list of tables to include in the model, but this list should not include the dependencies; this method will follow foreigner keys automatically.The table names shall be qualified names of 1, 2 or 3 components. The components are
<catalog>.<schema pattern>.<table pattern>
where:<catalog>
, if present, shall be the name of a catalog as it is stored in the database.<schema pattern>
, if present, shall be the pattern of a schema. The pattern can use'_'
and'%'
wildcards characters.<table pattern>
(mandatory) shall be the pattern of a table. The pattern can use'_'
and'%'
wildcards characters.
- Parameters:
store
- the data store for which we are creating a model. Used only in case of error.connection
- connection to the database. Sometimes the caller already has a connection at hand.tableNames
- qualified name of the tables. Specified by users at construction time.queries
- additional resources associated to SQL queries. Specified by users at construction time.customizer
- user-specified modification to the features, ornull
if none.- Throws:
SQLException
- if a database error occurred while reading metadata.DataStoreException
- if a logical error occurred while analyzing the database structure.Exception
-
getTableTypes
Returns the "TABLE" and "VIEW" keywords for table types, with unsupported keywords omitted.- Throws:
SQLException
-
hasTable
private boolean hasTable(DatabaseMetaData metadata, String[] tableTypes, Map<String, Boolean> tables) throws SQLExceptionReturnstrue
if the database contains at least one specified tables associated toBoolean.TRUE
. This method updatesschemaOfSpatialTables
andcatalogOfSpatialTables
for the tables found. If many occurrences of the same table are found, this method searches for a common pair of catalog and schema names. All tables should be in the same (catalog, schema) pair. If this is not the case, no (catalog,schema) will be used and the search for the tables will rely on the database "search path".- Parameters:
metadata
- value ofconnection.getMetaData()
.tableTypes
- value ofgetTableTypes(DatabaseMetaData)
.tables
- name of the table to search.- Returns:
- whether the given table has been found.
- Throws:
SQLException
-
listTables
public final void listTables(DatabaseMetaData metadata, MetadataBuilder builder) throws SQLException Stores information about tables in the given metadata. Only tables explicitly requested by the user are listed.- Parameters:
metadata
- information about the database.builder
- where to add information about the tables.- Throws:
SQLException
- if an error occurred while fetching table information.
-
tables
Returns all tables in declaration order. The list contains only the tables explicitly requested at construction time.- Returns:
- all tables in an unmodifiable list.
-
findTable
Returns the table for the given name. The given name may be one of the tables specified at construction time, or one of its dependencies.- Parameters:
store
- the data store for which we are fetching a table. Used only in case of error.name
- name of the table to fetch.- Returns:
- the table (never null).
- Throws:
IllegalNameException
- if no table of the given name is found or if the name is ambiguous.
-
appendFunctionCall
Appends a call to a function defined in the spatial schema. The function name will be prefixed by catalog and schema name if applicable. The function will not be quoted.- Parameters:
sql
- the SQL builder where to add the spatial function name.function
- the function to append.
-
isSpatial
public final boolean isSpatial()Returnstrue
if this database is a spatial database. Tables such as "SPATIAL_REF_SYS" are used as sentinel values.- Returns:
- whether this database is a spatial database.
-
hasGeometry
public final boolean hasGeometry()Returnstrue
if this database contains at least one geometry column. This information can be used for metadata purpose.- Returns:
- whether at least one geometry column has been found.
-
hasRaster
public final boolean hasRaster()Returnstrue
if this database contains at least one raster column. This information can be used for metadata purpose.- Returns:
- whether at least one raster column has been found.
-
getMapping
Returns a function for getting values from a column having the given definition. The given definition should include data SQL type and type name. If no match is found, then this method returnsnull
.The default implementation handles types declared in the
Types
class and the geometry types defined in the spatial extensions defined by OGC standard. Subclasses should override if some types need to be handle in a non-standard way for a particular database product.- Parameters:
columnDefinition
- information about the column to extract values from and expose through Java API.- Returns:
- converter to the corresponding java type, or
null
if this class cannot find a mapping.
-
getArrayComponentType
Returns the type of components in SQL arrays stored in a column. This method is invoked when#type
=Types.ARRAY
. The default implementation returnsTypes.OTHER
because JDBC column metadata does not provide information about component types. Database-specific subclasses should override this method if they can provide that information from theColumn.typeName
value.- Parameters:
columnDefinition
- information about the column to extract array component type.- Returns:
- one of
Types
constants. - See Also:
-
getDefaultMapping
Returns a mapping forTypes.JAVA_OBJECT
or unrecognized types. Some JDBC drivers wrap objects in implementation-specific classes, for examplePGobject
. This method should be overwritten in database-specific subclasses for returning a value getter capable to unwrap the value.- Returns:
- the default mapping for unknown or unrecognized types.
-
getBinaryEncoding
Returns an identifier of the way binary data are encoded by the JDBC driver.- Parameters:
columnDefinition
- information about the column to extract binary values from.- Returns:
- how the binary data are returned by the JDBC driver.
-
getEstimatedExtent
protected org.opengis.geometry.Envelope getEstimatedExtent(TableReference table, Column[] columns, boolean recall) throws SQLException Computes an estimation of the envelope of all geometry columns in the given table. The returned envelope shall contain at least the two-dimensional spatial components. Whether other dimensions (vertical and temporal) and present or not depends on the implementation. This method is invoked only if thecolumns
array contains at least one geometry column.- Parameters:
table
- the table for which to compute an estimation of the envelope.columns
- all columns in the table. Implementation should ignore non-geometry columns. This is a reference to an internal array; do not modify.recall
- if it is at least the second time that this method is invoked for the specified table.- Returns:
- an estimation of the spatiotemporal resource extent, or
null
if none. - Throws:
SQLException
- if an error occurred while fetching the envelope.
-
forGeometry
Returns a function for getting values from a geometry or geography column. This is a helper method forgetMapping(Column)
implementations.- Parameters:
columnDefinition
- information about the column to extract values from and expose through Java API.- Returns:
- converter to the corresponding java type, or
null
if this class cannot find a mapping,
-
createInfoStatements
Prepares a cache of statements about spatial information using the given connection. Statements will be created only when first needed.- Parameters:
connection
- the connection to use for creating statements.- Returns:
- a cache of prepared statements about spatial information.
-
addIgnoredTables
Adds to the given map a list of tables to ignore when searching for feature tables. The given map already contains the"SPATIAL_REF_SYS"
and"GEOMETRY_COLUMNS"
entries when this method is invoked. The default implementation adds nothing.Values tells whether the table can be used as a sentinel value for determining that this database is a spatial database.
- Parameters:
ignoredTables
- where to add names of tables to ignore.
-
getFilterToSQL
Returns the converter from filters/expressions to theWHERE
part of SQL statement. Subclasses should override this method if their database supports an extended syntax for some filters or expressions.The returned instance is usually a singleton instance. The caller of this method may create a copy of the returned instance for removing some functions that are found to be unsupported by the database software. Consequently, implementation of this method can assume that the database supports all the spatial operations managed by the returned writer.
- Returns:
- the converter from filters/expressions to the
WHERE
part of SQL statement.
-
getFilterToSupportedSQL
Returns the converter from filters/expressions to theWHERE
part of SQL statement without the functions that are unsupported by the database software. -
log
Sets the logger, class and method names of the given record, then logs it. This method declaresSQLStore.components()
as the public source of the log.- Parameters:
record
- the record to configure and log.
-
appendTo
Creates a tree representation of this database for debugging purpose.- Parameters:
parent
- the parent node where to add the tree representation.
-
toString
Formats a graphical representation of this database for debugging purpose. This representation can be printed to the standard output stream (for example) if the output device uses a monospaced font and supports Unicode.
-