package org.geotools.jdbc;
import org.geotools.data.FeatureStore;
import org.geotools.data.Transaction;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.factory.CommonFactoryFinder;
import org.geotools.feature.AttributeTypeBuilder;
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.feature.type.AttributeDescriptor;
import org.opengis.filter.FilterFactory;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import com.vividsolutions.jts.geom.Polygon;
public abstract class JDBCViewTest extends JDBCTestSupport {
protected static final String LAKESVIEW = "lakesview";
protected static final String LAKESVIEWPK = "lakesviewpk";
protected static final String FID = "fid";
protected static final String ID = "id";
protected static final String NAME = "name";
protected static final String GEOM = "geom";
protected FilterFactory ff = CommonFactoryFinder.getFilterFactory(null);
protected SimpleFeatureType lakeViewSchema;
protected SimpleFeatureType lakeViewPkSchema;
@Override
protected abstract JDBCViewTestSetup createTestSetup();
@Override
protected void connect() throws Exception {
super.connect();
// we need to use the type builder because the pk has min occurs = 1 on Oracle
AttributeTypeBuilder atb = new AttributeTypeBuilder();
atb.setMinOccurs(isPkNillable() ? 0 : 1);
atb.setMaxOccurs(1);
atb.setNillable(isPkNillable());
atb.setName(FID);
atb.setBinding(Integer.class);
AttributeDescriptor fidDescriptor = atb.buildDescriptor(FID);
SimpleFeatureTypeBuilder tb = new SimpleFeatureTypeBuilder();
tb.setNamespaceURI(dataStore.getNamespaceURI());
tb.setName(LAKESVIEW);
tb.add(fidDescriptor);
tb.add(ID, Integer.class);
tb.add(GEOM, Polygon.class, (CoordinateReferenceSystem) null);
tb.add(NAME, String.class);
lakeViewSchema = tb.buildFeatureType();
lakeViewPkSchema = tb.retype(lakeViewSchema, new String[] {ID, GEOM, NAME});
}
/**
* Whether the pk field in a view is nillable or not (it is for most databases, but not
* for Oracle for example).
* @return
*/
protected boolean isPkNillable() {
return true;
}
/**
* Whether the database supports primary keys defined on views (Oracle does)
* @return
*/
protected boolean supportsPkOnViews() {
return false;
}
public void testSchema() throws Exception {
SimpleFeatureType ft = dataStore.getSchema(tname(LAKESVIEW));
assertFeatureTypesEqual(lakeViewSchema, ft);
}
public void testSchemaPk() throws Exception {
if(!supportsPkOnViews())
return;
SimpleFeatureType ft = dataStore.getSchema(tname(LAKESVIEWPK));
assertFeatureTypesEqual(lakeViewPkSchema, ft);
}
public void testReadFeatures() throws Exception {
SimpleFeatureCollection fc = dataStore.getFeatureSource(tname(LAKESVIEW)).getFeatures();
assertEquals(1, fc.size());
SimpleFeatureIterator fr = fc.features();
assertTrue(fr.hasNext());
SimpleFeature f = fr.next();
assertFalse(fr.hasNext());
fr.close();
}
public void testGetBounds() throws Exception {
// GEOT-2067 Make sure it's possible to compute bounds out of a view
ReferencedEnvelope reference = dataStore.getFeatureSource(tname(LAKESVIEW)).getBounds();
assertEquals(12.0, reference.getMinX());
assertEquals(16.0, reference.getMaxX());
assertEquals(4.0, reference.getMinY());
assertEquals(8.0, reference.getMaxY());
}
/**
* Subclasses may want to override this in case the database has a native way, other
* than the pk, to identify a row
* @throws Exception
*/
public void testReadOnly() throws Exception {
try {
dataStore.getFeatureWriter(tname(LAKESVIEW), Transaction.AUTO_COMMIT);
fail("Should not be able to pick a writer without a pk");
} catch(Exception e) {
// ok, fine
}
assertFalse(dataStore.getFeatureSource(tname(LAKESVIEW)) instanceof FeatureStore);
}
}