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;
}
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;
}
Aggregations