/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2002-2008, 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.data.postgis; import junit.framework.TestCase; import org.easymock.classextension.EasyMock; import org.geotools.data.jdbc.JDBCDataStoreConfig; import org.geotools.data.jdbc.fidmapper.FIDMapper; import org.geotools.data.postgis.fidmapper.OIDFidMapper; import org.geotools.factory.CommonFactoryFinder; import org.geotools.feature.NameImpl; import org.geotools.feature.type.AttributeDescriptorImpl; import org.geotools.feature.type.AttributeTypeImpl; import org.geotools.filter.Filter; import org.geotools.filter.SQLEncoder; import org.geotools.filter.SQLEncoderException; import org.opengis.feature.type.AttributeDescriptor; import org.opengis.feature.type.AttributeType; import org.opengis.filter.FilterFactory; import org.opengis.filter.sort.SortBy; import org.opengis.filter.sort.SortOrder; /** * @author Gabriel Roldan (TOPP) * @version $Id$ * @since 2.5.x * * * @source $URL$ */ public class PostgisSQLBuilderTest extends TestCase { PostgisSQLBuilder builder; private JDBCDataStoreConfig config; /** * @see junit.framework.TestCase#setUp() */ protected void setUp() throws Exception { config = EasyMock.createMock(JDBCDataStoreConfig.class); builder = new PostgisSQLBuilder(4326, config); super.setUp(); } /** * @see junit.framework.TestCase#tearDown() */ protected void tearDown() throws Exception { super.tearDown(); } /** * Test method for {@link PostgisSQLBuilder#sqlFrom(java.lang.StringBuffer, java.lang.String)}. */ public void testSqlFromSchemaDisabled() { builder.setSchemaEnabled(false); StringBuffer sql = new StringBuffer(); builder.sqlFrom(sql, "typeName"); assertEquals(" FROM \"typeName\"", sql.toString()); } /** * Test method for {@link PostgisSQLBuilder#sqlFrom(java.lang.StringBuffer, java.lang.String)}. */ public void testSqlFromSchemaEnabled() { builder.setSchemaEnabled(true); EasyMock.expect(config.getDatabaseSchemaName()).andReturn("schema"); EasyMock.replay(config); StringBuffer sql = new StringBuffer(); builder.sqlFrom(sql, "typeName"); assertEquals(" FROM \"schema\".\"typeName\"", sql.toString()); EasyMock.verify(config); } /** * Test method for * {@link PostgisSQLBuilder#sqlWhere(java.lang.StringBuffer, org.geotools.filter.Filter)}. * * @throws SQLEncoderException */ public void testSqlWhere() throws SQLEncoderException { StringBuffer sql = new StringBuffer(); Filter preFilter = null; builder.sqlWhere(sql, preFilter); assertEquals("", sql.toString()); FilterFactory filterFactory = CommonFactoryFinder.getFilterFactory(null); preFilter = (Filter) filterFactory.bbox("the_geom", 0, 0, 1, 1, null); SQLEncoder encoder = EasyMock.createMock(SQLEncoder.class); encoder.setFeatureType(null); EasyMock.expect(encoder.encode(EasyMock.same(preFilter))).andReturn("encoded"); EasyMock.replay(encoder); builder = new PostgisSQLBuilder(encoder, config); builder.sqlWhere(sql, preFilter); assertEquals(" encoded", sql.toString()); EasyMock.verify(encoder); } /** * Test method for * {@link PostgisSQLBuilder#buildSQLQuery(java.lang.String, org.geotools.data.jdbc.fidmapper.FIDMapper, org.opengis.feature.type.AttributeDescriptor[], org.opengis.filter.Filter, org.opengis.filter.sort.SortBy[], java.lang.Integer, java.lang.Integer)}. * * @throws SQLEncoderException */ public void testBuildSQLQueryNoOffsetNoLimit() throws SQLEncoderException { FIDMapper mapper = new OIDFidMapper(); SortBy[] sortBy = null; Integer offset = null; Integer limit = null; String sql = buildSQLQuery(mapper, sortBy, offset, limit); final String baseSelect = "SELECT \"oid\", \"attribute\" FROM \"typeName\""; assertEquals(baseSelect, sql); } /** * Test method for * {@link PostgisSQLBuilder#buildSQLQuery(java.lang.String, org.geotools.data.jdbc.fidmapper.FIDMapper, org.opengis.feature.type.AttributeDescriptor[], org.opengis.filter.Filter, org.opengis.filter.sort.SortBy[], java.lang.Integer, java.lang.Integer)}. * * @throws SQLEncoderException */ public void testBuildSQLQueryOrderBy() throws SQLEncoderException { FIDMapper mapper = new OIDFidMapper(); SortBy[] sortBy = { CommonFactoryFinder.getFilterFactory(null).sort("attribute", SortOrder.DESCENDING) }; Integer offset = null; Integer limit = null; String sql = buildSQLQuery(mapper, sortBy, offset, limit); final String baseSelect = "SELECT \"oid\", \"attribute\" FROM \"typeName\""; assertEquals(baseSelect + " ORDER BY \"attribute\" DESC", sql); sortBy = new SortBy[] { SortBy.NATURAL_ORDER }; sql = buildSQLQuery(mapper, sortBy, offset, limit); assertEquals(baseSelect + " ORDER BY oid ASC", sql); sortBy = new SortBy[] { SortBy.REVERSE_ORDER }; sql = buildSQLQuery(mapper, sortBy, offset, limit); assertEquals(baseSelect + " ORDER BY oid DESC", sql); } /** * Test method for * {@link PostgisSQLBuilder#buildSQLQuery(java.lang.String, org.geotools.data.jdbc.fidmapper.FIDMapper, org.opengis.feature.type.AttributeDescriptor[], org.opengis.filter.Filter, org.opengis.filter.sort.SortBy[], java.lang.Integer, java.lang.Integer)}. * If offset is used and no sortby is provided, the primary key is used as sort order * * @throws SQLEncoderException */ public void testBuildSQLQueryOffset() throws SQLEncoderException { FIDMapper mapper = new OIDFidMapper(); SortBy[] sortBy = null; Integer offset = new Integer(15); Integer limit = null; String sql = buildSQLQuery(mapper, sortBy, offset, limit); final String baseSelect = "SELECT \"oid\", \"attribute\" FROM \"typeName\""; assertEquals(baseSelect + " ORDER BY oid ASC OFFSET 15", sql); } /** * Test method for * {@link PostgisSQLBuilder#buildSQLQuery(java.lang.String, org.geotools.data.jdbc.fidmapper.FIDMapper, org.opengis.feature.type.AttributeDescriptor[], org.opengis.filter.Filter, org.opengis.filter.sort.SortBy[], java.lang.Integer, java.lang.Integer)}. * An explicit SortBy[] not including the primary key produces an ORDER BY clause including the * primary key at the end to ensure consistent order event if the requested attribute list to * sort by does not produces a consistently ordered result * * @throws SQLEncoderException */ public void testBuildSQLQueryOffsetOrderBy() throws SQLEncoderException { FIDMapper mapper = new OIDFidMapper(); SortBy[] sortBy = { CommonFactoryFinder.getFilterFactory(null).sort("attribute", SortOrder.DESCENDING) }; Integer offset = new Integer(15); Integer limit = null; String sql = buildSQLQuery(mapper, sortBy, offset, limit); final String baseSelect = "SELECT \"oid\", \"attribute\" FROM \"typeName\""; assertEquals(baseSelect + " ORDER BY \"attribute\" DESC, oid ASC OFFSET 15", sql); } /** * Test method for * {@link PostgisSQLBuilder#buildSQLQuery(java.lang.String, org.geotools.data.jdbc.fidmapper.FIDMapper, org.opengis.feature.type.AttributeDescriptor[], org.opengis.filter.Filter, org.opengis.filter.sort.SortBy[], java.lang.Integer, java.lang.Integer)}. * If maxFeatures was provided then encode it as LIMIT <maxFeatures> * * @throws SQLEncoderException */ public void testBuildSQLQueryMaxFeatures() throws SQLEncoderException { FIDMapper mapper = new OIDFidMapper(); SortBy[] sortBy = null; Integer offset = null; Integer limit = new Integer(50); String sql = buildSQLQuery(mapper, sortBy, offset, limit); final String baseSelect = "SELECT \"oid\", \"attribute\" FROM \"typeName\""; assertEquals(baseSelect + " LIMIT 50", sql); } /** * Test method for * {@link PostgisSQLBuilder#buildSQLQuery(java.lang.String, org.geotools.data.jdbc.fidmapper.FIDMapper, org.opengis.feature.type.AttributeDescriptor[], org.opengis.filter.Filter, org.opengis.filter.sort.SortBy[], java.lang.Integer, java.lang.Integer)}. * If both startIndex and maxFeatures are provided but no sortBy, encode OFFSET and LIMIT as * well as PK based ORDER BY * * @throws SQLEncoderException */ public void testBuildSQLQueryOffsetMaxFeatures() throws SQLEncoderException { FIDMapper mapper = new OIDFidMapper(); SortBy[] sortBy = null; Integer offset = new Integer(15); Integer limit = new Integer(30); String sql = buildSQLQuery(mapper, sortBy, offset, limit); final String baseSelect = "SELECT \"oid\", \"attribute\" FROM \"typeName\""; assertEquals(baseSelect + " ORDER BY oid ASC OFFSET 15 LIMIT 30", sql); } /** * Test method for * {@link PostgisSQLBuilder#buildSQLQuery(java.lang.String, org.geotools.data.jdbc.fidmapper.FIDMapper, org.opengis.feature.type.AttributeDescriptor[], org.opengis.filter.Filter, org.opengis.filter.sort.SortBy[], java.lang.Integer, java.lang.Integer)}. * If startIndex,maxFeatures and sortBy are provided, encode OFFSET and LIMIT and ORDER BY the * required attributes, as well as trailing PK based ORDER BY * * @throws SQLEncoderException */ public void testBuildSQLQueryOffsetMaxFeaturesOrderBy() throws SQLEncoderException { FIDMapper mapper = new OIDFidMapper(); SortBy[] sortBy = { CommonFactoryFinder.getFilterFactory(null).sort("attribute", SortOrder.DESCENDING) }; Integer offset = new Integer(15); Integer limit = new Integer(30); String sql = buildSQLQuery(mapper, sortBy, offset, limit); final String baseSelect = "SELECT \"oid\", \"attribute\" FROM \"typeName\""; assertEquals(baseSelect + " ORDER BY \"attribute\" DESC, oid ASC OFFSET 15 LIMIT 30", sql); } private String buildSQLQuery(FIDMapper mapper, SortBy[] sortBy, Integer offset, Integer limit) throws SQLEncoderException { // the attribute to include in the query AttributeType type = new AttributeTypeImpl(new NameImpl("attType"), String.class, false, false, null, null, null); AttributeDescriptor attribute = new AttributeDescriptorImpl(type, new NameImpl("attribute"), 0, 1, true, null); AttributeDescriptor[] attrTypes = { attribute }; String typeName = "typeName"; org.opengis.filter.Filter filter = null; builder.setSchemaEnabled(false); String sql = builder.buildSQLQuery(typeName, mapper, attrTypes, filter, sortBy, offset, limit); return sql; } }