This is an automated email from the ASF dual-hosted git repository. jsorel pushed a commit to branch geoapi-4.0 in repository https://gitbox.apache.org/repos/asf/sis.git
The following commit(s) were added to refs/heads/geoapi-4.0 by this push: new 4a69351845 Allow FeatureSQL to understand different standards about the table of CRS definitions. Supported standards are: 4a69351845 is described below commit 4a6935184574ebf6b296018737e94812ffe80c92 Author: Martin Desruisseaux <martin.desruisse...@geomatys.com> AuthorDate: Wed Aug 7 14:10:57 2024 +0200 Allow FeatureSQL to understand different standards about the table of CRS definitions. Supported standards are: - Geopackage - ISO-13249 SQL/MM - ISO 19125 / OGC Simple feature access part 2 They have basically the same content, but with different table and column names. --- .../apache/sis/storage/sql/feature/Analyzer.java | 2 +- .../apache/sis/storage/sql/feature/Database.java | 93 ++++++++------ .../sis/storage/sql/feature/FeatureIterator.java | 5 +- .../sis/storage/sql/feature/InfoStatements.java | 51 ++++---- .../sis/storage/sql/feature/SpatialSchema.java | 135 +++++++++++++++++++++ .../apache/sis/storage/sql/postgis/Postgres.java | 15 ++- 6 files changed, 235 insertions(+), 66 deletions(-) diff --git a/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/feature/Analyzer.java b/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/feature/Analyzer.java index 44a534e9b5..a6c61b1c59 100644 --- a/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/feature/Analyzer.java +++ b/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/feature/Analyzer.java @@ -134,7 +134,7 @@ final class Analyzer { this.metadata = metadata; this.escape = metadata.getSearchStringEscape(); this.nameFactory = DefaultNameFactory.provider(); - spatialInformation = database.isSpatial() ? database.createInfoStatements(connection) : null; + spatialInformation = database.getSpatialSchema().isPresent() ? database.createInfoStatements(connection) : null; } /** diff --git a/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/feature/Database.java b/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/feature/Database.java index be81eba736..71503d3fd3 100644 --- a/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/feature/Database.java +++ b/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/feature/Database.java @@ -25,6 +25,7 @@ import java.util.LinkedHashSet; import java.util.WeakHashMap; import java.util.ArrayList; import java.util.Locale; +import java.util.Optional; import java.util.AbstractMap.SimpleImmutableEntry; import java.util.logging.LogRecord; import java.sql.Array; @@ -79,9 +80,9 @@ import org.apache.sis.util.collection.Cache; * <h2>Specializations</h2> * Subclasses may be defined for some database engines. Methods that can be overridden are: * <ul> + * <li>{@link #getPossibleSpatialSchemas(Map)} for enumerating the spatial schema conventions that may be used.</li> * <li>{@link #getMapping(Column)} for adding column types to recognize.</li> * <li>{@link #createInfoStatements(Connection)} for more info about spatial information.</li> - * <li>{@link #addIgnoredTables(Map)} for specifying more tables to ignore.</li> * </ul> * * <h2>Multi-threading</h2> @@ -138,14 +139,17 @@ public class Database<G> extends Syntax { private Table[] tables; /** - * Whether the database contains "GEOMETRY_COLUMNS" and/or "SPATIAL_REF_SYS" tables. - * May also be set to {@code true} if some database-specific tables are found such as - * {@code "geography_columns"} and {@code "raster_columns"} in PostGIS. + * Information about table names and column names used for the spatial schema, or {@code null}. + * This is non-null if the database contains "GEOMETRY_COLUMNS" and/or "SPATIAL_REF_SYS" tables, + * possibly with different name depending on the conventions of the spatial schema. May also be + * non-null if some database-specific tables are found such as {@code "geography_columns"} and + * {@code "raster_columns"} in PostGIS. + * * This field is initialized by {@link #analyze analyze(…)} and shall not be modified after that point. * - * @see #isSpatial() + * @see #getSpatialSchema() */ - private boolean isSpatial; + private SpatialSchema spatialSchema; /** * {@code true} if this database contains at least one geometry column. @@ -164,8 +168,8 @@ public class Database<G> extends Syntax { private boolean hasRaster; /** - * Catalog and schema of the {@value InfoStatements#GEOMETRY_COLUMNS} and - * {@value InfoStatements#SPATIAL_REF_SYS} tables, or null or empty string if none. + * Catalog and schema of the {@code "GEOMETRY_COLUMNS"} and {@code "SPATIAL_REF_SYS"} tables, + * or null or empty string if none. The actual table names depend on {@link #spatialSchema}. */ String catalogOfSpatialTables, schemaOfSpatialTables; @@ -201,10 +205,10 @@ public class Database<G> extends Syntax { /** * Cache of Coordinate Reference Systems created for a given SRID. - * SRID are primary keys in the {@value InfoStatements#SPATIAL_REF_SYS} table. + * SRID are primary keys in the {@code "SPATIAL_REF_SYS"} (or equivalent) table. * They are not EPSG codes, even if the numerical values are often the same. * - * <p>This mapping depend on the content of {@value InfoStatements#SPATIAL_REF_SYS} table. + * <p>This mapping depends on the content of {@code "SPATIAL_REF_SYS"} (or equivalent) table. * For that reason, a distinct cache exists for each database.</p> */ final Cache<Integer, CoordinateReferenceSystem> cacheOfCRS; @@ -342,17 +346,26 @@ public class Database<G> extends Syntax { * the default case specified by the SQL standard. However, some databases use lower * cases instead. */ - String tableCRS = InfoStatements.SPATIAL_REF_SYS; - String tableGeom = InfoStatements.GEOMETRY_COLUMNS; - if (metadata.storesLowerCaseIdentifiers()) { - tableCRS = tableCRS .toLowerCase(Locale.US).intern(); - tableGeom = tableGeom.toLowerCase(Locale.US).intern(); + final var ignoredTables = new HashMap<String,Boolean>(8); + for (SpatialSchema schema : getPossibleSpatialSchemas(ignoredTables)) { + String tableCRS = schema.crsTable;; + String tableGeom = schema.geometryColumns; + if (metadata.storesLowerCaseIdentifiers()) { + tableCRS = tableCRS .toLowerCase(Locale.US).intern(); + tableGeom = tableGeom.toLowerCase(Locale.US).intern(); + } else if (metadata.storesUpperCaseIdentifiers()) { + tableCRS = tableCRS .toUpperCase(Locale.US).intern(); + tableGeom = tableGeom.toUpperCase(Locale.US).intern(); + } + ignoredTables.put(tableCRS, Boolean.TRUE); + ignoredTables.put(tableGeom, Boolean.TRUE); + if (hasTable(metadata, tableTypes, ignoredTables)) { + spatialSchema = schema; + break; + } + ignoredTables.remove(tableCRS); + ignoredTables.remove(tableGeom); } - final Map<String,Boolean> ignoredTables = new HashMap<>(8); - ignoredTables.put(tableCRS, Boolean.TRUE); - ignoredTables.put(tableGeom, Boolean.TRUE); - addIgnoredTables(ignoredTables); - isSpatial = hasTable(metadata, tableTypes, ignoredTables); /* * Collect the names of all tables specified by user, ignoring the tables * used for database internal working (for example by PostGIS). @@ -434,14 +447,14 @@ public class Database<G> extends Syntax { * * @param metadata value of {@code connection.getMetaData()}. * @param tableTypes value of {@link #getTableTypes(DatabaseMetaData)}. - * @param tables name of the table to search. + * @param tables name of the table to search. Will not be modified. * @return whether the given table has been found. */ private boolean hasTable(final DatabaseMetaData metadata, final String[] tableTypes, final Map<String,Boolean> tables) throws SQLException { // `SimpleImmutableEntry` used as a way to store a (catalog,schema) pair of strings. - final FrequencySortedSet<SimpleImmutableEntry<String,String>> schemas = new FrequencySortedSet<>(true); + final var schemas = new FrequencySortedSet<SimpleImmutableEntry<String,String>>(true); int count = 0; for (final Map.Entry<String,Boolean> entry : tables.entrySet()) { if (entry.getValue()) { @@ -527,13 +540,13 @@ public class Database<G> extends Syntax { } /** - * Returns {@code true} if this database is a spatial database. - * Tables such as "SPATIAL_REF_SYS" are used as sentinel values. + * Returns an identification of the table and column naming conventions. + * This is absent if the database is not spatial. * - * @return whether this database is a spatial database. + * @return an identification of the table and column naming conventions. */ - public final boolean isSpatial() { - return isSpatial; + public final Optional<SpatialSchema> getSpatialSchema() { + return Optional.ofNullable(spatialSchema); } /** @@ -706,16 +719,28 @@ public class Database<G> extends Syntax { } /** - * Adds to the given map a list of tables to ignore when searching for feature tables. - * The given map already contains the {@code "SPATIAL_REF_SYS"} and {@code "GEOMETRY_COLUMNS"} - * entries when this method is invoked. The default implementation adds nothing. + * Returns the spatial schema conventions that may possibly be supported by this database. + * The default implementation returns all {@link SpatialSchema} enumeration values. + * Subclasses may restrict to a smaller set of possibilities. + * + * <p>In addition, this method can declare in the supplied map which tables are used for describing + * the spatial schema. The default implementation does nothing because the entries to add depend on + * the {@link SpatialSchema}. For example, if Simple Features conventions are used, then the tables + * are {@code "SPATIAL_REF_SYS"} and {@code "GEOMETRY_COLUMNS"}. Subclasses can add other entries + * if they know in advance that they support only one convention, or that all the conventions that + * they support use the same table names. The table added to the map will be ignored when searching + * for feature tables.</p> + * + * <p>The values in the map tells whether the table can be used as a sentinel value for determining + * that the {@link SpatialSchema} enumeration value can be accepted.</p> * - * <p>Values tells whether the table can be used as a sentinel value for determining - * that this database {@linkplain #isSpatial is a spatial database}.</p> + * @param tables where to add names of tables that describe the spatial schema. + * @return the spatial schema conventions that may be supported by this database. * - * @param ignoredTables where to add names of tables to ignore. + * @see #getSpatialSchema() */ - protected void addIgnoredTables(final Map<String,Boolean> ignoredTables) { + protected SpatialSchema[] getPossibleSpatialSchemas(Map<String,Boolean> tables) { + return SpatialSchema.values(); } /** diff --git a/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/feature/FeatureIterator.java b/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/feature/FeatureIterator.java index eb60040003..01b605c8da 100644 --- a/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/feature/FeatureIterator.java +++ b/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/feature/FeatureIterator.java @@ -85,7 +85,7 @@ final class FeatureIterator implements Spliterator<Feature>, AutoCloseable { /** * A cache of statements for fetching spatial information such as geometry columns or SRID. - * This is non-null only if the {@linkplain Database#isSpatial() database is spatial}. + * This is non-null only if the {@linkplain Database#getSpatialSchema() database is spatial}. * The same instance is shared by all dependencies of this {@code FeatureIterator}. */ private final InfoStatements spatialInformation; @@ -118,7 +118,8 @@ final class FeatureIterator implements Spliterator<Feature>, AutoCloseable { throws SQLException, InternalDataStoreException { adapter = table.adapter(connection); - spatialInformation = table.database.isSpatial() ? table.database.createInfoStatements(connection) : null; + spatialInformation = table.database.getSpatialSchema().isPresent() + ? table.database.createInfoStatements(connection) : null; String sql = adapter.sql; if (distinct || filter != null || sort != null || offset > 0 || count > 0) { final SQLBuilder builder = new SQLBuilder(table.database).append(sql); diff --git a/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/feature/InfoStatements.java b/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/feature/InfoStatements.java index 0010191315..5337f93de9 100644 --- a/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/feature/InfoStatements.java +++ b/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/feature/InfoStatements.java @@ -74,19 +74,6 @@ import org.opengis.metadata.Identifier; * @see <a href="https://www.ogc.org/standards/sfs">OGC Simple feature access — Part 2: SQL option</a> */ public class InfoStatements implements Localized, AutoCloseable { - /** - * The table containing CRS definitions, as specified by ISO 19125 / OGC Simple feature access part 2. - * Note that the standard specifies table names in upper-case letters, which is also the default case - * specified by the SQL standard. However, some databases use lower cases instead. This table name can - * be used unquoted for letting the database engine converts the case. - */ - static final String SPATIAL_REF_SYS = "SPATIAL_REF_SYS"; - - /** - * The table containing the list of geometry columns, as specified by ISO 19125 / OGC Simple feature access part 2. - */ - static final String GEOMETRY_COLUMNS = "GEOMETRY_COLUMNS"; - /** * Specifies how the geometry type is encoded in the {@code "GEOMETRY_TYPE"} column. * The OGC standard defines numeric values, but PostGIS uses textual values. @@ -227,8 +214,10 @@ public class InfoStatements implements Localized, AutoCloseable { protected final PreparedStatement prepareIntrospectionStatement(final String table, final char prefix, final String column, final String otherColumn) throws SQLException { + final SpatialSchema schema = database.getSpatialSchema().orElseThrow(); final SQLBuilder sql = new SQLBuilder(database).append(SQLBuilder.SELECT) - .append(prefix).append('_').append(column).append(", SRID "); + .append(prefix).append('_').append(column).append(", ") + .append(schema.crsIdentifierColumn).append(' '); if (otherColumn != null) sql.append(", ").append(otherColumn); appendFrom(sql, table); if (database.supportsCatalogs) appendCondition(sql, prefix, "TABLE_CATALOG").append(" AND "); @@ -250,7 +239,8 @@ public class InfoStatements implements Localized, AutoCloseable { */ public void completeIntrospection(final TableReference source, final Map<String,Column> columns) throws Exception { if (geometryColumns == null) { - geometryColumns = prepareIntrospectionStatement(GEOMETRY_COLUMNS, 'F', "GEOMETRY_COLUMN", "GEOMETRY_TYPE"); + final SpatialSchema schema = database.getSpatialSchema().orElseThrow(); + geometryColumns = prepareIntrospectionStatement(schema.geometryColumns, 'F', "GEOMETRY_COLUMN", "GEOMETRY_TYPE"); } configureSpatialColumns(geometryColumns, source, columns, GeometryTypeEncoding.NUMERIC); } @@ -302,12 +292,13 @@ public class InfoStatements implements Localized, AutoCloseable { /** * Gets a Coordinate Reference System for to given SRID. * If the given SRID is zero or negative, then this method returns {@code null}. - * Otherwise the CRS is decoded from the database {@value #SPATIAL_REF_SYS} table. + * Otherwise the CRS is decoded from the database {@code "SPATIAL_REF_SYS"} table + * or equivalent (depending on the {@link SpatialSchema}). * * @param srid the Spatial Reference Identifier (SRID) to resolve as a CRS object. * @return the CRS associated to the given SRID, or {@code null} if the SRID is zero. * @throws DataStoreContentException if the CRS cannot be fetched. Possible reasons are: - * no entry found in the {@value #SPATIAL_REF_SYS} table, or more than one entry is found, + * no entry found in the {@code "SPATIAL_REF_SYS"} table, or more than one entry is found, * or a single entry exists but has no WKT definition and its authority code is unsupported by SIS. * @throws ParseException if the WKT cannot be parsed. * @throws SQLException if a SQL error occurred. @@ -323,7 +314,7 @@ public class InfoStatements implements Localized, AutoCloseable { /** * Invoked when the requested CRS is not in the cache. This method gets the entry from the - * {@value #SPATIAL_REF_SYS} table then gets the CRS from its authority code if possible, + * {@link SpatialSchema#refSysTable} then gets the CRS from its authority code if possible, * or fallback on the WKT otherwise. * * @param srid the Spatial Reference Identifier (SRID) of the CRS to create from the database content. @@ -332,10 +323,13 @@ public class InfoStatements implements Localized, AutoCloseable { */ private CoordinateReferenceSystem parseCRS(final int srid) throws Exception { if (wktFromSrid == null) { + final SpatialSchema schema = database.getSpatialSchema().orElseThrow(); final SQLBuilder sql = new SQLBuilder(database); - sql.append("SELECT auth_name, auth_srid, srtext"); - appendFrom(sql, SPATIAL_REF_SYS); - sql.append("srid=?"); + sql.append("SELECT").append(schema.crsAuthorityNameColumn) + .append(schema.crsAuthorityCodeColumn) + .append(schema.crsDefinitionColumn); + appendFrom(sql, schema.crsTable); + sql.append(schema.crsIdentifierColumn).append("=?"); wktFromSrid = connection.prepareStatement(sql.toString()); } wktFromSrid.setInt(1, srid); @@ -393,7 +387,8 @@ public class InfoStatements implements Localized, AutoCloseable { if (crs == null) { crs = v.recommendation; } else if (!crs.equals(v.recommendation)) { - throw invalidSRID(Resources.Keys.DuplicatedSRID_2, SPATIAL_REF_SYS, srid, authorityError); + final SpatialSchema schema = database.getSpatialSchema().orElseThrow(); + throw invalidSRID(Resources.Keys.DuplicatedSRID_2, schema.crsTable, srid, authorityError); } warning = v.warning(false); if (warning == null && fromWKT != null) { @@ -417,7 +412,8 @@ public class InfoStatements implements Localized, AutoCloseable { if (authorityError != null) { throw authorityError; } - throw invalidSRID(Resources.Keys.UnknownSRID_2, SPATIAL_REF_SYS, srid, null); + final SpatialSchema schema = database.getSpatialSchema().orElseThrow(); + throw invalidSRID(Resources.Keys.UnknownSRID_2, schema.crsTable, srid, null); } if (warning != null) { warning.setLoggerName(Modules.SQL); @@ -497,10 +493,13 @@ public class InfoStatements implements Localized, AutoCloseable { * Get the WKT and verifies if the CRS is approximately equal. */ if (sridFromCRS == null) { + final SpatialSchema schema = database.getSpatialSchema().orElseThrow(); final SQLBuilder sql = new SQLBuilder(database); - sql.append("SELECT srtext, srid"); - appendFrom(sql, SPATIAL_REF_SYS); - sql.append("auth_name=? AND auth_srid=?"); + sql.append("SELECT").append(schema.crsDefinitionColumn) + .append(schema.crsIdentifierColumn); + appendFrom(sql, schema.crsTable); + sql.append(schema.crsAuthorityNameColumn).append("=? AND ") + .append(schema.crsAuthorityCodeColumn).append("=?"); sridFromCRS = connection.prepareStatement(sql.toString()); } sridFromCRS.setString(1, authority); diff --git a/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/feature/SpatialSchema.java b/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/feature/SpatialSchema.java new file mode 100644 index 0000000000..5f0f915805 --- /dev/null +++ b/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/feature/SpatialSchema.java @@ -0,0 +1,135 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.sis.storage.sql.feature; + + +/** + * Information about table names and column names used for the spatial schema. + * There is many standards, with nearly identical content but different names. + * + * <ul> + * <li>Geopackage</li> + * <li>ISO-13249 SQL/MM</li> + * <li>ISO 19125 / OGC Simple feature access part 2</li> + * </ul> + * + * The presence of tables for each standard will be tested in enumeration order. + * + * @author Johann Sorel (Geomatys) + * @author Martin Desruisseaux (Geomatys) + */ +public enum SpatialSchema { + /** + * Table and column names as specified by Geopackage. This is the same thing as {@link #SQL_MM} + * except for table names and for the case (Geopackage uses lower case). + */ + GEOPACKAGE("gpkg_spatial_ref_sys", "srs_id", "organization", "organization_coordsys_id", "definition", + "gpkg_geometry_columns"), + + /** + * Table and column names as specified by ISO-13249 SQL/MM. This is the same thing as {@link #SIMPLE_FEATURE} + * with only different names. The table definition for CRS is: + * + * {@snippet lang="sql" : + * CREATE TABLE ST_SPATIAL_REFERENCE_SYSTEMS( + * SRS_NAME CHARACTER VARYING(ST_MaxSRSNameLength) NOT NULL, + * SRS_ID INTEGER NOT NULL, + * ORGANIZATION CHARACTER VARYING(ST_MaxOrganizationNameLength), + * ORGANIZATION_COORDSYS_ID INTEGER, + * DEFINITION CHARACTER VARYING(ST_MaxSRSDefinitionLength) NOT NULL, + * DESCRIPTION CHARACTER VARYING(ST_MaxDescriptionLength)) + * } + * + * In Geopackage, this table is named {@code "gpkg_spatial_ref_sys"} but otherwise has identical content + * except for the case (Geopackage uses lower case). + */ + SQL_MM("ST_SPATIAL_REFERENCE_SYSTEMS", "SRS_ID", "ORGANIZATION", "ORGANIZATION_COORDSYS_ID", "DEFINITION", + "ST_GEOMETRY_COLUMNS"), + + /** + * Table and column names as specified by ISO 19125 / OGC Simple feature access part 2. + * Note that the standard specifies table names in upper-case letters, which is also the default case + * specified by the SQL standard. However, some databases use lower cases instead. This table name can + * be used unquoted for letting the database engine converts the case. The table definition for CRS is: + * + * {@snippet lang="sql" : + * CREATE TABLE SPATIAL_REF_SYS ( + * SRID INTEGER NOT NULL PRIMARY KEY, + * AUTH_NAME CHARACTER VARYING, + * AUTH_SRID INTEGER, + * SRTEXT CHARACTER VARYING(2048)) + * } + */ + SIMPLE_FEATURE("SPATIAL_REF_SYS", "SRID", "AUTH_NAME", "AUTH_SRID", "SRTEXT", + "GEOMETRY_COLUMNS"); + + /** + * Name of the table for Spatial Reference System definitions. + * Example: {@code "SPATIAL_REF_SYS"}, {@code "ST_SPATIAL_REFERENCE_SYSTEMS"}. + */ + final String crsTable; + + /** + * Name of the column for CRS identifiers. + * Example: {@code "SRID"}, {@code "SRS_ID"}. + */ + final String crsIdentifierColumn; + + /** + * Name of the column for CRS authority names. + * Example: {@code "AUTH_NAME"}, {@code "ORGANIZATION"}. + */ + final String crsAuthorityNameColumn; + + /** + * Name of the column for CRS authority codes. + * Example: {@code "AUTH_SRID"}, {@code "ORGANIZATION_COORDSYS_ID"}. + */ + final String crsAuthorityCodeColumn; + + /** + * Name of the column for CRS definitions in Well-Known Text (<abbr>WKT</abbr>) format. + * Example: {@code "SRTEXT"}, {@code "DEFINITION"}. + */ + final String crsDefinitionColumn; + + /** + * Name of the table enumerating the geometry columns. + */ + final String geometryColumns; + + /** + * Creates a new enumeration value. + * + * @param crsTable name of the table for Spatial Reference System definitions. + * @param crsIdentifierColumn name of the column for CRS identifiers. + * @param crsAuthorityNameColumn name of the column for CRS authority names. + * @param crsAuthorityCodeColumn name of the column for CRS authority codes. + * @param crsDefinitionColumn name of the column for CRS definitions in <abbr>WKT</abbr> format. + * @param geometryColumns name of the table enumerating the geometry columns. + */ + private SpatialSchema(String crsTable, String crsIdentifierColumn, String crsAuthorityNameColumn, + String crsAuthorityCodeColumn, String crsDefinitionColumn, String geometryColumns) + { + this.crsTable = crsTable; + this.crsIdentifierColumn = crsIdentifierColumn; + this.crsAuthorityNameColumn = crsAuthorityNameColumn; + this.crsAuthorityCodeColumn = crsAuthorityCodeColumn; + this.crsDefinitionColumn = crsDefinitionColumn; + this.geometryColumns = geometryColumns; + } +} diff --git a/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/postgis/Postgres.java b/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/postgis/Postgres.java index 054f36b253..20a4a43d1a 100644 --- a/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/postgis/Postgres.java +++ b/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/postgis/Postgres.java @@ -37,6 +37,7 @@ import org.apache.sis.storage.sql.feature.Database; import org.apache.sis.storage.sql.feature.ValueGetter; import org.apache.sis.storage.sql.feature.Resources; import org.apache.sis.storage.sql.feature.SelectionClauseWriter; +import org.apache.sis.storage.sql.feature.SpatialSchema; import org.apache.sis.metadata.sql.privy.Dialect; import org.apache.sis.storage.event.StoreListeners; import org.apache.sis.util.Version; @@ -185,15 +186,23 @@ public final class Postgres<G> extends Database<G> { } /** - * Adds to the given set a list of tables to ignore when searching for feature tables. + * Returns the spatial schema conventions that may possibly be supported by this database. + * The only value expected by PostGIS databases is {@link SpatialSchema#SIMPLE_FEATURE}. + * This method also completes the given map with additional tables describing the schema. + * Those tables shall be ignored when searching for feature tables. * - * @param ignoredTables where to add names of tables to ignore. + * <p>The values in the map tells whether the table can be used as a sentinel value for + * determining that the {@link SpatialSchema} enumeration value can be accepted.</p> + * + * @param tables where to add names of tables that describe the spatial schema. + * @return the spatial schema convention supported by this database. */ @Override - protected void addIgnoredTables(final Map<String,Boolean> ignoredTables) { + protected SpatialSchema[] getPossibleSpatialSchemas(final Map<String,Boolean> ignoredTables) { ignoredTables.put("geography_columns", Boolean.TRUE); // Postgis 1+ ignoredTables.put("raster_columns", Boolean.TRUE); // Postgis 2 ignoredTables.put("raster_overviews", Boolean.FALSE); + return new SpatialSchema[] {SpatialSchema.SIMPLE_FEATURE}; } /**