Class Relation

java.lang.Object
org.apache.sis.internal.sql.feature.TableReference
org.apache.sis.internal.sql.feature.Relation

final class Relation extends TableReference
Description of a relation between two tables, as defined by foreigner keys. Each Table may contain an arbitrary number of relations. Relations are defined in two directions:
  • Relation.Direction.IMPORT: primary keys of other tables are referenced by the foreigner keys of the table containing this Relation.
  • Relation.Direction.EXPORT: foreigner keys of other tables are referencing the primary keys of the table containing this Relation.
Instances of this class are created from the results of getImportedKeys​ or getExportedKeys​ with (catalog, schema, table) parameters.
Since:
1.0
Version:
1.2
  • Field Details

    • EMPTY

      static final Relation[] EMPTY
      An empty array used when there are no relations.
    • columns

      private final Map<String,String> columns
      The columns of the other table that constitute a primary or foreigner key. Keys are the columns of the other table and values are columns of the table containing this Relation.
    • searchTable

      private Table searchTable
      The other table identified by TableReference.catalog, TableReference.schema and TableReference.table names. This is set during Table construction and should not be modified after that point.
      See Also:
    • propertyName

      String propertyName
      The name of the feature property where the association to searchTable table will be stored. If the foreigner key uses exactly one column, then this is the name of that column.
    • useFullKey

      private boolean useFullKey
      Whether the columns map include all primary key columns. This field is set to false if the foreigner key uses only a subset of the primary key columns, in which case the referenced rows may not be unique.
      See Also:
    • excluded

      boolean excluded
      Whether this relation should be omitted from the list of feature type properties. This is a temporary information used only at FeatureType construction time. A relation is excluded if table A is a dependency of table B (defined by foreigner keys) and the relation is pointing back to A.
      Since:
      1.2
  • Constructor Details

    • Relation

      Relation(Analyzer analyzer, Relation.Direction dir, ResultSet reflect) throws SQLException, DataStoreContentException
      Creates a new relation for an imported key. The given ResultSet must be positioned on the first row of DatabaseMetaData.getImportedKeys​(catalog, schema, table) result, and the result must be sorted in the order of the given keys:
      1. Relation.Direction.catalog
      2. Relation.Direction.schema
      3. Relation.Direction.table
      Note that JDBC specification ensures this order if Relation.Direction.IMPORT is used with the result of getImportedKeys​ and Relation.Direction.EXPORT is used with the result of getExportedKeys​.

      After construction, the ResultSet will be positioned on the first row of the next relation, or be closed if the last row has been reached. This constructor always moves the given result set by at least one row, unless an exception occurs.

      Parameters:
      analyzer - the object which is analyzing the database schema for inferring feature types.
      dir - whether another table is using or is used by the table containing this relation.
      reflect - metadata about foreigner keys, with cursor already on the first row.
      Throws:
      SQLException
      DataStoreContentException
  • Method Details

    • setPropertyName

      final void setPropertyName(String column, int count)
      Invoked after construction for setting the name of the feature property of the enclosing table where to store association to the feature instances read from the search table. If the foreigner key use exactly one column, we can use the name of that column. Otherwise we don't know which column has the most appropriate name (often there is none), so we fallback on the foreigner key name.
      Parameters:
      column - a foreigner key column.
      count - number of names previously created from that column.
    • getPropertyName

      final String getPropertyName()
      Returns the name of the feature property where the association to the search table will be stored. If the foreigner key uses exactly one column, then this is the name of that column.
    • setSearchTable

      final void setSearchTable(Analyzer analyzer, Table search, PrimaryKey primaryKey, Relation.Direction direction) throws DataStoreException
      Invoked after construction for setting the table identified by TableReference.catalog, TableReference.schema and TableReference.table names. Shall be invoked exactly once.
      Parameters:
      analyzer - the object which is analyzing the database schema for inferring feature types.
      search - the other table containing the primary key (Relation.Direction.IMPORT) or the foreigner key (Relation.Direction.EXPORT) of this relation.
      primaryKey - the primary key columns of the relation. May be the primary key columns of this table or the primary key columns of the other table, depending on Relation.Direction.
      direction - this.direction (see comment in field declarations).
      Throws:
      DataStoreException
    • getSearchTable

      final Table getSearchTable() throws InternalDataStoreException
      Returns the other table identified by TableReference.catalog, TableReference.schema and TableReference.table names. This is the table where the search operations will be performed. In other words, this is part of the following pseudo-query:
      SELECT * FROM <search table> WHERE <search columns> = ...
      Throws:
      InternalDataStoreException
    • isSearchTableDeferred

      final boolean isSearchTableDeferred()
      Returns whether setSearchTable(…) needs to be invoked.
    • getSearchColumns

      final Collection<String> getSearchColumns()
      Returns the columns of the search table which will need to appear in the WHERE clause. For Relation.Direction.IMPORT, they are primary key columns. For Relation.Direction.EXPORT, they are foreigner key columns.
    • getOwnerColumns

      final Collection<String> getOwnerColumns()
      Returns the foreigner key columns of the table that contains this relation. For Relation.Direction.IMPORT, this is the foreigner keys in the enclosing table. For Relation.Direction.EXPORT, this is the primary keys in the dependency table. This method returns only the columns known to this relation; this is not necessarily all the enclosing table foreigner keys. Some columns may be used in more than one relation.
    • useFullKey

      final boolean useFullKey()
      Returns true if this relation includes all required primary key columns. Returns false if the foreigner key uses only a subset of the primary key columns, in which case the referenced rows may not be unique.
    • isInverseOf

      final boolean isInverseOf(Relation other)
      Returns true if this relation is the inverse of the given relation. If two relations are inverse, then following those relations recursively would result in an infinite loop.

      This method tests only the column names; the table names shall be verified by the caller. Table names can be verified as below (see comment in field declarations for meaning of "owner"):

      • this.equals(other.owner.name): the target of this relation is the source of other relation.
      • this.owner.name.equals(other): the source of this relation is the target of other relation.
      Parameters:
      other - the other relation to check for inverse relationship.
    • startFollowing

      final void startFollowing(List<Relation> following) throws InternalDataStoreException
      Adds this relation to the given list, making sure that the relation has not already been added. The check for previous existence of this relation is for preventing infinite recursivity.
      Throws:
      InternalDataStoreException
    • endFollowing

      final void endFollowing(List<Relation> following) throws InternalDataStoreException
      Removes this relation from the given list, making sure that this relation was at the tail.
      Throws:
      InternalDataStoreException
    • appendTo

      @Debug void appendTo(TreeTable.Node parent, String arrow)
      Creates a tree representation of this relation for debugging purpose.
      Parameters:
      parent - the parent node where to add the tree representation.
      arrow - the symbol to use for relating the columns of two tables in a foreigner key.
    • toString

      public String toString()
      Formats a graphical representation of this relation 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 TableReference
      Returns:
      a string representation of this table reference.