Class Database<G>

java.lang.Object
org.apache.sis.internal.metadata.sql.Syntax
org.apache.sis.internal.sql.feature.Database<G>
Type Parameters:
G - the type of geometry objects. Depends on the backing implementation (ESRI, JTS, Java2D…).
Direct Known Subclasses:
Postgres

public class Database<G> extends Syntax
Information about a connection to a spatial database and the structure of features in the database. This class provides functions for converting objects between the types used in the Java language and the types or SQL expressions expected by JDBC. Conversions may be straightforward (e.g. invoke 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:

Multi-threading

This class is safe for concurrent use by many threads. This class does not hold JDBC resources such as Connection. 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 new Database instance shall be created.
Since:
1.1
Version:
1.2
  • Field Details

    • WILDCARD

      public static final String WILDCARD
      The SQL wildcard for any characters. A string containing only this wildcard means "any value" and can sometimes be replaced by null.
      See Also:
    • source

      protected final DataSource source
      Provider of (pooled) connections to the database.
    • geomLibrary

      final Geometries<G> 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 isByteSigned
      Whether Types.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

      private final FeatureNaming<Table> tablesByNames
      All tables known to this Database. Populated in the constructor, and shall not be modified after construction for preserving thread-safety.
    • tables

      private Table[] tables
      All tables known to this Database in declaration order. This array contains only the tables specified at initialization time, not the dependencies. This field is initialized by
      invalid reference
      #analyze(SQLStore, Connection, ResourceDefinition...)
      and shall not be modified after that point.
    • isSpatial

      private boolean isSpatial
      Whether the database contains "GEOMETRY_COLUMNS" and/or "SPATIAL_REF_SYS" tables. May also be set to true if some database-specific tables are found such as "geography_columns" and "raster_columns" in PostGIS. This field is initialized by analyze(…) and shall not be modified after that point.
      See Also:
    • hasGeometry

      private boolean hasGeometry
      true if this database contains at least one geometry column. This field is initialized by analyze(…) and shall not be modified after that point.
      See Also:
    • hasRaster

      private boolean hasRaster
      true if this database contains at least one raster column. This field is initialized by analyze(…) and shall not be modified after that point.
      See Also:
    • catalogOfSpatialTables

      String catalogOfSpatialTables
      Catalog and schema of the "GEOMETRY_COLUMNS" and "SPATIAL_REF_SYS" tables, or null or empty string if none.
    • schemaOfSpatialTables

      String schemaOfSpatialTables
      Catalog and schema of the "GEOMETRY_COLUMNS" and "SPATIAL_REF_SYS" tables, or null or empty string if none.
    • supportsCatalogs

      final boolean supportsCatalogs
      Whether catalog or schema are supported.
    • supportsSchemas

      final boolean supportsSchemas
      Whether catalog or schema are supported.
    • filterToSQL

      private SelectionClauseWriter filterToSQL
      The converter from filters/expressions to the WHERE 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

      public final StoreListeners listeners
      Where to send warnings.
      See Also:
    • cacheOfCRS

      final Cache<Integer,org.opengis.referencing.crs.CoordinateReferenceSystem> 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

      final WeakHashMap<org.opengis.referencing.crs.CoordinateReferenceSystem,Integer> cacheOfSRID
      Cache of SRID for a given Coordinate Reference System. This is the converse of cacheOfCRS. 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, or null 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 after Database 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, or null 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

      private static String[] getTableTypes(DatabaseMetaData metadata) throws SQLException
      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 SQLException
      Returns true if the database contains at least one specified tables associated to Boolean.TRUE. This method updates schemaOfSpatialTables and catalogOfSpatialTables 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 of connection.getMetaData().
      tableTypes - value of getTableTypes(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

      public final List<FeatureSet> 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

      public final FeatureSet findTable(SQLStore store, String name) throws IllegalNameException
      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

      public final void appendFunctionCall(SQLBuilder sql, String function)
      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()
      Returns true 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()
      Returns true 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()
      Returns true 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

      protected ValueGetter<?> getMapping(Column columnDefinition)
      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 returns null.

      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

      protected int getArrayComponentType(Column columnDefinition)
      Returns the type of components in SQL arrays stored in a column. This method is invoked when
      invalid reference
      #type
      = Types.ARRAY. The default implementation returns Types.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 the Column.typeName value.
      Parameters:
      columnDefinition - information about the column to extract array component type.
      Returns:
      one of Types constants.
      See Also:
    • getDefaultMapping

      protected ValueGetter<Object> getDefaultMapping()
      Returns a mapping for Types.JAVA_OBJECT or unrecognized types. Some JDBC drivers wrap objects in implementation-specific classes, for example PGobject. 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

      protected BinaryEncoding getBinaryEncoding(Column columnDefinition)
      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 the columns 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

      protected final ValueGetter<?> forGeometry(Column columnDefinition)
      Returns a function for getting values from a geometry or geography column. This is a helper method for getMapping(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

      protected InfoStatements createInfoStatements(Connection connection)
      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

      protected void addIgnoredTables(Map<String,Boolean> ignoredTables)
      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

      protected SelectionClauseWriter getFilterToSQL()
      Returns the converter from filters/expressions to the WHERE 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

      final SelectionClauseWriter getFilterToSupportedSQL()
      Returns the converter from filters/expressions to the WHERE part of SQL statement without the functions that are unsupported by the database software.
    • log

      protected final void log(LogRecord record)
      Sets the logger, class and method names of the given record, then logs it. This method declares SQLStore.components() as the public source of the log.
      Parameters:
      record - the record to configure and log.
    • appendTo

      @Debug final void appendTo(TreeTable.Node parent)
      Creates a tree representation of this database for debugging purpose.
      Parameters:
      parent - the parent node where to add the tree representation.
    • toString

      public String 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.
      Overrides:
      toString in class Object
      Returns:
      string representation of this database.