Search in sources :

Example 1 with CRSAdaptorVisitor

use of org.geotoolkit.filter.visitor.CRSAdaptorVisitor in project geotoolkit by Geomatys.

the class DefaultJDBCFeatureStore method getQOMFeatureReader.

/**
 * Get reader with geotk query model.
 */
private FeatureReader getQOMFeatureReader(final org.geotoolkit.storage.feature.query.Query query, Connection cnx) throws DataStoreException {
    final String dbSchemaName = getDatabaseSchema();
    final FeatureType type = dbmodel.getFeatureType(query.getTypeName());
    final String tableName = type.getName().tip().toString();
    TableMetaModel tableMeta = null;
    if (dbSchemaName == null) {
        // Try to handle empty schema name given at configuration
        for (final SchemaMetaModel scheme : dbmodel.getSchemaMetaModels()) {
            final TableMetaModel tableMetaTemp = scheme.getTable(tableName);
            if (tableMetaTemp != null) {
                tableMeta = tableMetaTemp;
                break;
            }
        }
    } else {
        tableMeta = dbmodel.getSchemaMetaModel(getDatabaseSchema()).getTable(tableName);
    }
    if (tableMeta == null) {
        throw new DataStoreException("Unable to get table " + tableName + " in the database.");
    }
    final FeatureType tableType = tableMeta.getType(TableMetaModel.View.ALLCOMPLEX).build();
    final PrimaryKey pkey = dbmodel.getPrimaryKey(query.getTypeName());
    // replace any PropertyEqualsTo in true ID filters
    Filter baseFilter = query.getSelection();
    baseFilter = (Filter) FIDFixVisitor.INSTANCE.visit(baseFilter);
    // split the filter between what can be send and must be handle by code
    final Filter[] divided = getDialect().splitFilter(baseFilter, tableType);
    Filter preFilter = divided[0];
    Filter postFilter = divided[1];
    // ensure spatial filters are in featuretype geometry crs
    preFilter = (Filter) new CRSAdaptorVisitor(tableType).visit(preFilter);
    // rebuild a new query with the same params, but just the pre-filter
    final org.geotoolkit.storage.feature.query.Query builder = new org.geotoolkit.storage.feature.query.Query();
    builder.copy(query);
    builder.setSelection(preFilter);
    if (query.getResolution() != null) {
        // attach resampling in hints; used later by postgis dialect
        builder.getHints().add(new Hints(RESAMPLING, query.getResolution()));
    }
    final org.geotoolkit.storage.feature.query.Query preQuery = builder;
    final FeatureType baseType = getFeatureType(query.getTypeName());
    // Build the feature type returned by this query. Also build an eventual extra feature type
    // containing the attributes we might need in order to evaluate the post filter
    final FeatureType queryFeatureType;
    final FeatureType returnedFeatureType;
    if (query.retrieveAllProperties()) {
        returnedFeatureType = queryFeatureType = (FeatureType) baseType;
    } else {
        // TODO BUG here, query with filter on a not returned geometry field crash
        returnedFeatureType = (FeatureType) FeatureTypeExt.createSubType(tableType, query.getPropertyNames());
        final FilterAttributeExtractor extractor = new FilterAttributeExtractor(tableType);
        extractor.visit(postFilter, null);
        final GenericName[] extraAttributes = extractor.getAttributeNames();
        final List<GenericName> allAttributes = new ArrayList<>();
        for (String str : query.getPropertyNames()) {
            allAttributes.add(type.getProperty(str).getName());
        }
        for (GenericName extraAttribute : extraAttributes) {
            if (!allAttributes.contains(extraAttribute)) {
                allAttributes.add(extraAttribute);
            }
        }
        // ensure we have the primarykeys
        pkLoop: for (ColumnMetaModel pkc : pkey.getColumns()) {
            final String pkcName = pkc.getName();
            for (GenericName n : allAttributes) {
                if (n.tip().toString().equals(pkcName)) {
                    continue pkLoop;
                }
            }
            // add the pk attribut
            allAttributes.add(baseType.getProperty(pkcName).getName());
        }
        final GenericName[] allAttributeArray = allAttributes.toArray(new GenericName[allAttributes.size()]);
        queryFeatureType = (FeatureType) FeatureTypeExt.createSubType(tableType, allAttributeArray);
    }
    final String sql;
    // we gave him the connection, he must not release it
    final boolean release = (cnx == null);
    if (cnx == null) {
        try {
            cnx = getDataSource().getConnection();
        } catch (SQLException ex) {
            throw new DataStoreException(ex.getMessage(), ex);
        }
    }
    FeatureReader reader;
    // so for now if we got one, we let the filter be evaluated in java and not with a sql query
    if (containsOperation(preQuery, baseType)) {
        try {
            sql = getQueryBuilder().selectSQL(baseType, new org.geotoolkit.storage.feature.query.Query(baseType.getName()));
            reader = new JDBCFeatureReader(this, sql, baseType, cnx, release, null);
            FeatureStreams.subset(reader, query);
        } catch (SQLException ex) {
            throw new DataStoreException(ex.getMessage(), ex);
        }
    } else {
        try {
            sql = getQueryBuilder().selectSQL(queryFeatureType, preQuery);
            reader = new JDBCFeatureReader(this, sql, queryFeatureType, cnx, release, null);
        } catch (SQLException ex) {
            throw new DataStoreException(ex.getMessage(), ex);
        }
    }
    // if post filter, wrap it
    if (postFilter != null && postFilter != Filter.include()) {
        reader = FeatureStreams.filter(reader, postFilter);
    }
    // if we need to constraint type
    if (!returnedFeatureType.equals(queryFeatureType)) {
        reader = FeatureStreams.decorate(reader, new ViewMapper(type, query.getPropertyNames()), query.getHints());
    }
    return reader;
}
Also used : FeatureType(org.opengis.feature.FeatureType) Query(org.apache.sis.storage.Query) SQLQuery(org.geotoolkit.storage.feature.query.SQLQuery) Hints(org.geotoolkit.factory.Hints) SQLException(java.sql.SQLException) ArrayList(java.util.ArrayList) GenericName(org.opengis.util.GenericName) FeatureReader(org.geotoolkit.storage.feature.FeatureReader) DataStoreException(org.apache.sis.storage.DataStoreException) ViewMapper(org.geotoolkit.feature.ViewMapper) FilterAttributeExtractor(org.geotoolkit.filter.visitor.FilterAttributeExtractor) Filter(org.opengis.filter.Filter) CRSAdaptorVisitor(org.geotoolkit.filter.visitor.CRSAdaptorVisitor)

Example 2 with CRSAdaptorVisitor

use of org.geotoolkit.filter.visitor.CRSAdaptorVisitor in project geotoolkit by Geomatys.

the class DefaultJDBCFeatureStore method getFeatureWriterInternal.

private FeatureWriter getFeatureWriterInternal(final String typeName, Filter baseFilter, final EditMode mode, Connection cnx, final Hints hints) throws DataStoreException, IOException {
    if (!isWritable(typeName)) {
        throw new DataStoreException("Type " + typeName + " is not writeable.");
    }
    final FeatureType baseType = getFeatureType(typeName);
    final PrimaryKey pkey = dbmodel.getPrimaryKey(typeName);
    // replace any PropertyEqualsTo in true ID filters
    baseFilter = (Filter) FIDFixVisitor.INSTANCE.visit(baseFilter);
    // split the filter between what can be send and must be handle by code
    final Filter[] divided = getDialect().splitFilter(baseFilter, baseType);
    Filter preFilter = divided[0];
    Filter postFilter = divided[1];
    // ensure spatial filters are in featuretype geometry crs
    preFilter = (Filter) new CRSAdaptorVisitor(baseType).visit(preFilter);
    // we gave him the connection, he must not release it
    final boolean release = (cnx == null);
    if (cnx == null) {
        try {
            cnx = getDataSource().getConnection();
        } catch (SQLException ex) {
            throw new DataStoreException(ex.getMessage(), ex);
        }
    }
    FeatureWriter writer;
    try {
        // check for insert only
        if (EditMode.INSERT == mode) {
            // build up a statement for the content, inserting only so we dont want
            // the query to return any data ==> Filter.exclude()
            final org.geotoolkit.storage.feature.query.Query queryNone = org.geotoolkit.storage.feature.query.Query.filtered(typeName, Filter.exclude());
            final String sql = getQueryBuilder().selectSQL(baseType, queryNone);
            getLogger().fine(sql);
            return new JDBCFeatureWriterInsert(this, sql, baseType, cnx, release, hints);
        }
        // build up a statement for the content
        final org.geotoolkit.storage.feature.query.Query preQuery = org.geotoolkit.storage.feature.query.Query.filtered(typeName, preFilter);
        final String sql = getQueryBuilder().selectSQL(baseType, preQuery);
        getLogger().fine(sql);
        if (EditMode.UPDATE == mode) {
            writer = new JDBCFeatureWriterUpdate(this, sql, baseType, cnx, release, hints);
        } else {
            // update insert case
            writer = new JDBCFeatureWriterUpdateInsert(this, sql, baseType, cnx, release, hints);
        }
    } catch (SQLException e) {
        // close the connection
        JDBCFeatureStoreUtilities.closeSafe(getLogger(), (release) ? cnx : null);
        // now we can safely rethrow the exception
        throw new DataStoreException(e);
    }
    // check for post filter and wrap accordingly
    if (postFilter != null && postFilter != Filter.include()) {
        writer = FeatureStreams.filter(writer, postFilter);
    }
    return writer;
}
Also used : FeatureType(org.opengis.feature.FeatureType) FeatureWriter(org.geotoolkit.storage.feature.FeatureWriter) DataStoreException(org.apache.sis.storage.DataStoreException) SQLException(java.sql.SQLException) Filter(org.opengis.filter.Filter) CRSAdaptorVisitor(org.geotoolkit.filter.visitor.CRSAdaptorVisitor)

Aggregations

SQLException (java.sql.SQLException)2 DataStoreException (org.apache.sis.storage.DataStoreException)2 CRSAdaptorVisitor (org.geotoolkit.filter.visitor.CRSAdaptorVisitor)2 FeatureType (org.opengis.feature.FeatureType)2 Filter (org.opengis.filter.Filter)2 ArrayList (java.util.ArrayList)1 Query (org.apache.sis.storage.Query)1 Hints (org.geotoolkit.factory.Hints)1 ViewMapper (org.geotoolkit.feature.ViewMapper)1 FilterAttributeExtractor (org.geotoolkit.filter.visitor.FilterAttributeExtractor)1 FeatureReader (org.geotoolkit.storage.feature.FeatureReader)1 FeatureWriter (org.geotoolkit.storage.feature.FeatureWriter)1 SQLQuery (org.geotoolkit.storage.feature.query.SQLQuery)1 GenericName (org.opengis.util.GenericName)1