/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2002-2011, Open Source Geospatial Foundation (OSGeo) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ package org.geotools.jdbc; import java.util.Arrays; import java.util.HashSet; import java.util.Set; import org.geotools.data.Join; import org.geotools.data.Query; import org.geotools.data.Join.Type; import org.geotools.data.simple.SimpleFeatureCollection; import org.geotools.data.simple.SimpleFeatureIterator; import org.opengis.feature.simple.SimpleFeature; import org.opengis.filter.Filter; import org.opengis.filter.FilterFactory; import org.opengis.filter.FilterFactory2; import org.opengis.filter.sort.SortBy; import org.opengis.filter.sort.SortOrder; public abstract class JDBCJoinTest extends JDBCTestSupport { @Override protected abstract JDBCJoinTestSetup createTestSetup(); public void testSimpleJoin() throws Exception { doTestSimpleJoin(false); doTestSimpleJoin(true); } void doTestSimpleJoin(boolean exposePrimaryKeys) throws Exception { dataStore.setExposePrimaryKeyColumns(exposePrimaryKeys); SimpleFeatureIterator ita = dataStore.getFeatureSource(tname("ft1")).getFeatures().features(); SimpleFeatureIterator itb = dataStore.getFeatureSource(tname("ftjoin")).getFeatures().features(); FilterFactory ff = dataStore.getFilterFactory(); Query q = new Query(tname("ft1")); q.getJoins().add(new Join(tname("ftjoin"), ff.equal(ff.property(aname("stringProperty")), ff.property(aname("name")), true))); SimpleFeatureCollection features = dataStore.getFeatureSource(tname("ft1")).getFeatures(q); assertEquals(dataStore.getFeatureSource(tname("ft1")).getFeatures(q).size(), features.size()); SimpleFeatureIterator it = features.features(); try { assertTrue(it.hasNext() && ita.hasNext() && itb.hasNext()); while(it.hasNext()) { SimpleFeature f = it.next(); assertEquals(5, f.getAttributeCount()); SimpleFeature g = (SimpleFeature) f.getAttribute(tname("ftjoin")); SimpleFeature a = ita.next(); SimpleFeature b = itb.next(); for (int i = 0; i < a.getAttributeCount(); i++) { assertAttributeValuesEqual(a.getAttribute(i), f.getAttribute(i)); } for (int i = 0; i < b.getAttributeCount(); i++) { assertAttributeValuesEqual(b.getAttribute(i), g.getAttribute(i)); } } } finally { it.close(); ita.close(); itb.close(); } } public void testSimpleJoinWithFilter() throws Exception { doTestSimpleJoinWithFilter(false); doTestSimpleJoinWithFilter(true); } void doTestSimpleJoinWithFilter(boolean exposePrimaryKeys) throws Exception { dataStore.setExposePrimaryKeyColumns(exposePrimaryKeys); FilterFactory ff = dataStore.getFilterFactory(); Query q = new Query(tname("ft1")); q.getJoins().add(new Join(tname("ftjoin"), ff.equal(ff.property(aname("stringProperty")), ff.property(aname("name")), true))); q.setFilter(ff.equal(ff.property(aname("stringProperty")), ff.literal("two"), true)); SimpleFeatureCollection features = dataStore.getFeatureSource(tname("ft1")).getFeatures(q); assertEquals(1, features.size()); SimpleFeatureIterator it = features.features(); try { SimpleFeature f = it.next(); assertEquals(5, f.getAttributeCount()); assertEquals(2, ((Number)f.getAttribute(aname("intProperty"))).intValue()); assertEquals("two", f.getAttribute(aname("stringProperty"))); SimpleFeature g = (SimpleFeature) f.getAttribute(aname("ftjoin")); assertEquals(3, g.getAttributeCount()); assertEquals(2, ((Number)g.getAttribute(aname("id"))).intValue()); assertEquals("two", g.getAttribute(aname("name"))); } finally { it.close(); } } public void testSimpleJoinWithFilterNoProperties() throws Exception { doTestSimpleJoinWithFilterNoProperties(false); doTestSimpleJoinWithFilterNoProperties(true); } void doTestSimpleJoinWithFilterNoProperties(boolean exposePrimaryKeys) throws Exception { dataStore.setExposePrimaryKeyColumns(exposePrimaryKeys); FilterFactory ff = dataStore.getFilterFactory(); Query q = new Query(tname("ft1")); Join j = new Join(tname("ftjoin"), ff.equal(ff.property(aname("stringProperty")), ff.property(aname("name")), true)); j.setProperties(Query.NO_PROPERTIES); q.getJoins().add(j); q.setFilter(ff.equal(ff.property(aname("stringProperty")), ff.literal("two"), true)); SimpleFeatureCollection features = dataStore.getFeatureSource(tname("ft1")).getFeatures(q); assertEquals(1, features.size()); SimpleFeatureIterator it = features.features(); try { SimpleFeature f = it.next(); assertEquals(5, f.getAttributeCount()); assertEquals(2, ((Number)f.getAttribute(aname("intProperty"))).intValue()); assertEquals("two", f.getAttribute(aname("stringProperty"))); SimpleFeature g = (SimpleFeature) f.getAttribute(aname("ftjoin")); assertEquals(0, g.getAttributeCount()); } finally { it.close(); } } public void testSimpleJoinWithFilterCount() throws Exception { doTestSimpleJoinWithFilterCount(false); doTestSimpleJoinWithFilterCount(true); } void doTestSimpleJoinWithFilterCount(boolean exposePrimaryKeys) throws Exception { dataStore.setExposePrimaryKeyColumns(exposePrimaryKeys); FilterFactory ff = dataStore.getFilterFactory(); Query q = new Query(tname("ft1")); Join j = new Join(tname("ftjoin"), ff.equal(ff.property(aname("stringProperty")), ff.property(aname("name")), true)); j.filter(ff.greater(ff.property(aname("id")), ff.literal(1))); q.getJoins().add(j); q.setFilter(ff.less(ff.property(aname("intProperty")), ff.literal(3))); assertEquals(1, dataStore.getFeatureSource(tname("ft1")).getCount(q)); } public void testSimpleJoinWithPostFilter() throws Exception { doTestSimpleJoinWithPostFilter(false); doTestSimpleJoinWithPostFilter(true); } void doTestSimpleJoinWithPostFilter(boolean exposePrimaryKeys) throws Exception { dataStore.setExposePrimaryKeyColumns(exposePrimaryKeys); FilterFactory ff = dataStore.getFilterFactory(); Filter j = ff.equal(ff.property(aname("stringProperty")), ff.property(aname("name")), true); Query q = new Query(tname("ft1")); q.getJoins().add(new Join(tname("ftjoin"), j)); q.setFilter(ff.equal( ff.function("__equals", ff.property(aname("stringProperty")), ff.literal("one")), ff.literal(true), true)); SimpleFeatureCollection features = dataStore.getFeatureSource(tname("ft1")).getFeatures(q); assertEquals(1, features.size()); //test with post filter on table being joined q = new Query(tname("ft1")); Join join = new Join(tname("ftjoin"), j); join.filter(ff.equal( ff.function("__equals", ff.property(aname("name")), ff.literal("one")), ff.literal(true), true)); q.getJoins().add(join); features = dataStore.getFeatureSource(tname("ft1")).getFeatures(q); assertEquals(1, features.size()); } public void testSimpleJoinWithPostFilterNoProperties() throws Exception { doTestSimpleJoinWithPostFilterNoProperties(false); doTestSimpleJoinWithPostFilterNoProperties(true); } void doTestSimpleJoinWithPostFilterNoProperties(boolean exposePrimaryKeys) throws Exception { dataStore.setExposePrimaryKeyColumns(exposePrimaryKeys); FilterFactory ff = dataStore.getFilterFactory(); Filter j = ff.equal(ff.property(aname("stringProperty")), ff.property(aname("name")), true); Query q = new Query(tname("ft1")); Join join = new Join(tname("ftjoin"), j); join.setProperties(Query.NO_PROPERTIES); q.getJoins().add(join); q.setFilter(ff.equal( ff.function("__equals", ff.property(aname("stringProperty")), ff.literal("one")), ff.literal(true), true)); SimpleFeatureCollection features = dataStore.getFeatureSource(tname("ft1")).getFeatures(q); assertEquals(1, features.size()); //test with post filter on table being joined q = new Query(tname("ft1")); join = new Join(tname("ftjoin"), j); join.setProperties(Query.NO_PROPERTIES); join.filter(ff.equal( ff.function("__equals", ff.property(aname("name")), ff.literal("one")), ff.literal(true), true)); q.getJoins().add(join); features = dataStore.getFeatureSource(tname("ft1")).getFeatures(q); assertEquals(1, features.size()); } public void testSimpleJoinWithSort() throws Exception { doTestSimpleJoinWithSort(false); doTestSimpleJoinWithSort(true); } void doTestSimpleJoinWithSort(boolean exposePrimaryKeys) throws Exception { dataStore.setExposePrimaryKeyColumns(exposePrimaryKeys); FilterFactory ff = dataStore.getFilterFactory(); Filter j = ff.equal(ff.property(aname("stringProperty")), ff.property(aname("name")), true); Query q = new Query(tname("ft1")); q.getJoins().add(new Join(tname("ftjoin"), j)); q.setSortBy(new SortBy[]{ff.sort(aname("intProperty"), SortOrder.DESCENDING)}); SimpleFeatureCollection features = dataStore.getFeatureSource(tname("ft1")).getFeatures(q); SimpleFeatureIterator it = features.features(); try { assertTrue(it.hasNext()); assertEquals("two", it.next().getAttribute(aname("stringProperty"))); assertTrue(it.hasNext()); assertEquals("one", it.next().getAttribute(aname("stringProperty"))); assertTrue(it.hasNext()); assertEquals("zero", it.next().getAttribute(aname("stringProperty"))); } finally { it.close(); } } public void testSimpleJoinWithLimitOffset() throws Exception { doTestSimpleJoinWithLimitOffset(false); doTestSimpleJoinWithLimitOffset(true); } void doTestSimpleJoinWithLimitOffset(boolean exposePrimaryKeys) throws Exception { dataStore.setExposePrimaryKeyColumns(exposePrimaryKeys); FilterFactory ff = dataStore.getFilterFactory(); Filter j = ff.equal(ff.property(aname("stringProperty")), ff.property(aname("name")), true); Query q = new Query(tname("ft1")); q.getJoins().add(new Join(tname("ftjoin"), j)); q.setFilter(ff.greater(ff.property(aname("intProperty")), ff.literal(0))); q.setStartIndex(1); q.setSortBy(new SortBy[]{ff.sort(aname("intProperty"), SortOrder.ASCENDING)}); SimpleFeatureCollection features = dataStore.getFeatureSource(tname("ft1")).getFeatures(q); assertEquals(1, features.size()); SimpleFeatureIterator it = features.features(); try { assertTrue(it.hasNext()); SimpleFeature f = it.next(); assertEquals("two", f.getAttribute(aname("stringProperty"))); SimpleFeature g = (SimpleFeature) f.getAttribute(aname("ftjoin")); assertEquals("two", g.getAttribute(aname("name"))); } finally { it.close(); } } public void testSelfJoin() throws Exception { doTestSelfJoin(false); doTestSelfJoin(true); } public void doTestSelfJoin(boolean exposePrimaryKeys) throws Exception { dataStore.setExposePrimaryKeyColumns(exposePrimaryKeys); FilterFactory ff = dataStore.getFilterFactory(); Query q = new Query(tname("ft1")); q.getJoins().add(new Join(tname("ft1"), ff.equal(ff.property(aname("intProperty")), ff.property(aname("foo.intProperty")), true)).alias(aname("foo"))); q.setFilter(ff.equal(ff.property(aname("stringProperty")), ff.literal("two"), true)); SimpleFeatureCollection features = dataStore.getFeatureSource(tname("ft1")).getFeatures(q); assertEquals(1, features.size()); SimpleFeatureIterator it = features.features(); try { assertTrue(it.hasNext()); SimpleFeature f = it.next(); assertEquals(5, f.getAttributeCount()); assertEquals(2, ((Number)f.getAttribute(aname("intProperty"))).intValue()); assertEquals("two", f.getAttribute(aname("stringProperty"))); SimpleFeature g = (SimpleFeature) f.getAttribute(aname("foo")); assertEquals(4, g.getAttributeCount()); assertEquals(2, ((Number)g.getAttribute(aname("intProperty"))).intValue()); assertEquals("two", g.getAttribute(aname("stringProperty"))); } finally { it.close(); } } public void testSpatialJoin() throws Exception { doTestSpatialJoin(false); doTestSpatialJoin(true); } void doTestSpatialJoin(boolean exposePrimaryKeys) throws Exception { dataStore.setExposePrimaryKeyColumns(exposePrimaryKeys); FilterFactory2 ff = (FilterFactory2) dataStore.getFilterFactory(); Query q = new Query(tname("ft1")); q.setPropertyNames(Arrays.asList(aname("geometry"), aname("intProperty"))); q.setSortBy(new SortBy[]{ff.sort(aname("intProperty"), SortOrder.ASCENDING)}); q.getJoins().add(new Join(tname("ftjoin"), ff.contains(ff.property(aname("geom")), ff.property(aname("geometry"))))); SimpleFeatureCollection features = dataStore.getFeatureSource(tname("ft1")).getFeatures(q); assertEquals(6, features.size()); SimpleFeatureIterator it = features.features(); SimpleFeature f; try { Set<String> s = new HashSet<String>(Arrays.asList("zero", "one", "two")); assertTrue(it.hasNext()); f = it.next(); assertEquals(0, ((Number)f.getAttribute(aname("intProperty"))).intValue()); s.remove(((SimpleFeature)f.getAttribute(tname("ftjoin"))).getAttribute(aname("name"))); assertTrue(it.hasNext()); f = it.next(); assertEquals(0, ((Number)f.getAttribute(aname("intProperty"))).intValue()); s.remove(((SimpleFeature)f.getAttribute(tname("ftjoin"))).getAttribute(aname("name"))); assertTrue(it.hasNext()); f = it.next(); assertEquals(0, ((Number)f.getAttribute(aname("intProperty"))).intValue()); s.remove(((SimpleFeature)f.getAttribute(tname("ftjoin"))).getAttribute(aname("name"))); assertEquals(0, s.size()); s = new HashSet<String>(Arrays.asList("one", "two")); assertTrue(it.hasNext()); f = it.next(); assertEquals(1, ((Number)f.getAttribute(aname("intProperty"))).intValue()); s.remove(((SimpleFeature)f.getAttribute(tname("ftjoin"))).getAttribute(aname("name"))); assertTrue(it.hasNext()); f = it.next(); assertEquals(1, ((Number)f.getAttribute(aname("intProperty"))).intValue()); s.remove(((SimpleFeature)f.getAttribute(tname("ftjoin"))).getAttribute(aname("name"))); assertEquals(0, s.size()); assertTrue(it.hasNext()); f = it.next(); assertEquals(2, ((Number)f.getAttribute(aname("intProperty"))).intValue()); assertEquals("two", ((SimpleFeature)f.getAttribute(tname("ftjoin"))).getAttribute(aname("name"))); assertFalse(it.hasNext()); } finally { it.close(); } } public void testOuterJoin() throws Exception { doTestOuterJoin(false); doTestOuterJoin(true); } void doTestOuterJoin(boolean exposePrimaryKeys) throws Exception { dataStore.setExposePrimaryKeyColumns(exposePrimaryKeys); FilterFactory ff = dataStore.getFilterFactory(); Query q = new Query(tname("ftjoin")); q.getJoins().add(new Join(tname("ft1"), ff.equal(ff.property(aname("name")), ff.property(aname("stringProperty")), true)).type(Type.OUTER)); SimpleFeatureCollection features = dataStore.getFeatureSource(tname("ftjoin")).getFeatures(q); assertEquals(dataStore.getFeatureSource(tname("ftjoin")).getFeatures(q).size(), features.size()); SimpleFeatureIterator it = features.features(); try { while(it.hasNext()) { SimpleFeature f = it.next(); assertEquals(4, f.getAttributeCount()); SimpleFeature g = (SimpleFeature) f.getAttribute(tname("ft1")); if ("three".equals(f.getAttribute(aname("name")))) { assertNull(g); } else { assertNotNull(g); } } } finally { it.close(); } } }