/* * Geotoolkit - An Open Source Java GIS Toolkit * http://www.geotoolkit.org * * (C) 2013, Geomatys * * 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.geotoolkit.db.postgres; import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.GeometryCollection; import com.vividsolutions.jts.geom.GeometryFactory; import com.vividsolutions.jts.geom.LineString; import com.vividsolutions.jts.geom.LinearRing; import com.vividsolutions.jts.geom.MultiLineString; import com.vividsolutions.jts.geom.MultiPoint; import com.vividsolutions.jts.geom.MultiPolygon; import com.vividsolutions.jts.geom.Point; import com.vividsolutions.jts.geom.Polygon; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.List; import java.util.Map; import java.util.Properties; import org.apache.sis.feature.FeatureExt; import org.apache.sis.feature.builder.FeatureTypeBuilder; import org.apache.sis.internal.feature.AttributeConvention; import org.geotoolkit.data.FeatureCollection; import org.geotoolkit.data.FeatureIterator; import org.geotoolkit.data.FeatureReader; import org.geotoolkit.data.query.Query; import org.geotoolkit.data.query.QueryBuilder; import org.geotoolkit.data.session.Session; import org.apache.sis.storage.DataStoreException; import org.geotoolkit.geometry.jts.JTS; import org.geotoolkit.utility.parameter.ParametersExt; import org.geotoolkit.version.VersionControl; import org.geotoolkit.version.VersioningException; import org.junit.Assume; import org.junit.BeforeClass; import org.junit.Test; import org.opengis.util.GenericName; import org.opengis.parameter.ParameterValueGroup; import org.opengis.referencing.NoSuchAuthorityCodeException; import org.opengis.util.FactoryException; import static org.geotoolkit.db.postgres.PostgresFeatureStoreFactory.*; import org.geotoolkit.filter.identity.DefaultFeatureId; import static org.junit.Assert.*; import org.geotoolkit.storage.DataStores; import org.junit.After; import org.opengis.filter.identity.FeatureId; import org.apache.sis.referencing.CommonCRS; import org.opengis.feature.AttributeType; import org.opengis.feature.Feature; import org.opengis.feature.FeatureType; import org.opengis.feature.PropertyType; /** * * @author Johann Sorel (Geomatys) */ public class PostgresSimpleTypeTest extends org.geotoolkit.test.TestBase { /** driver types */ private static final FeatureType FTYPE_DRIVER; /** stop types */ private static final FeatureType FTYPE_STOP; /** data types */ private static final FeatureType FTYPE_DATA; /** record types */ private static final FeatureType FTYPE_RECORD; /** sdata types */ private static final FeatureType FTYPE_SDATA; /** basic field types */ private static final FeatureType FTYPE_SIMPLE; /** 1 dimension arrays */ private static final FeatureType FTYPE_ARRAY; /** 2 dimensions arrays */ private static final FeatureType FTYPE_ARRAY2; /** geometric fields */ private static final FeatureType FTYPE_GEOMETRY; /** 1 depth feature type */ private static final FeatureType FTYPE_COMPLEX; /** 2 depth feature type */ private static final FeatureType FTYPE_COMPLEX2; /** multiple properties of same complex type */ private static final FeatureType FTYPE_COMPLEX3; static{ //////////////////////////////////////////////////////////////////////// FeatureTypeBuilder ftb = new FeatureTypeBuilder(); ftb.setName("testTable"); ftb.addAttribute(Boolean.class).setName("boolean"); ftb.addAttribute(Byte.class).setName("byte"); ftb.addAttribute(Short.class).setName("short"); ftb.addAttribute(Integer.class).setName("integer"); ftb.addAttribute(Long.class).setName("long"); ftb.addAttribute(Float.class).setName("float"); ftb.addAttribute(Double.class).setName("double"); ftb.addAttribute(String.class).setName("string"); FTYPE_SIMPLE = ftb.build(); //////////////////////////////////////////////////////////////////////// ftb = new FeatureTypeBuilder(); ftb.setName("testTable"); ftb.addAttribute(Boolean[].class).setName("boolean"); ftb.addAttribute(Byte[].class).setName("byte"); ftb.addAttribute(Short[].class).setName("short"); ftb.addAttribute(Integer[].class).setName("integer"); ftb.addAttribute(Long[].class).setName("long"); ftb.addAttribute(Float[].class).setName("float"); ftb.addAttribute(Double[].class).setName("double"); ftb.addAttribute(String[].class).setName("string"); FTYPE_ARRAY = ftb.build(); //////////////////////////////////////////////////////////////////////// ftb = new FeatureTypeBuilder(); ftb.setName("testTable"); ftb.addAttribute(Boolean[][].class).setName("boolean"); ftb.addAttribute(Byte[][].class).setName("byte"); ftb.addAttribute(Short[][].class).setName("short"); ftb.addAttribute(Integer[][].class).setName("integer"); ftb.addAttribute(Long[][].class).setName("long"); ftb.addAttribute(Float[][].class).setName("float"); ftb.addAttribute(Double[][].class).setName("double"); ftb.addAttribute(String[][].class).setName("string"); FTYPE_ARRAY2 = ftb.build(); //////////////////////////////////////////////////////////////////////// ftb = new FeatureTypeBuilder(); ftb.setName("testTable"); ftb.addAttribute(Geometry.class).setName("geometry").setCRS(CommonCRS.WGS84.normalizedGeographic()); ftb.addAttribute(Point.class).setName("point").setCRS(CommonCRS.WGS84.normalizedGeographic()); ftb.addAttribute(MultiPoint.class).setName("multipoint").setCRS(CommonCRS.WGS84.normalizedGeographic()); ftb.addAttribute(LineString.class).setName("linestring").setCRS(CommonCRS.WGS84.normalizedGeographic()); ftb.addAttribute(MultiLineString.class).setName("multilinestring").setCRS(CommonCRS.WGS84.normalizedGeographic()); ftb.addAttribute(Polygon.class).setName("polygon").setCRS(CommonCRS.WGS84.normalizedGeographic()); ftb.addAttribute(MultiPolygon.class).setName("multipolygon").setCRS(CommonCRS.WGS84.normalizedGeographic()); ftb.addAttribute(GeometryCollection.class).setName("geometrycollection").setCRS(CommonCRS.WGS84.normalizedGeographic()); FTYPE_GEOMETRY = ftb.build(); //////////////////////////////////////////////////////////////////////// ftb = new FeatureTypeBuilder(); ftb.setName("Stop"); ftb.addAttribute(Point.class).setName("location").setCRS(CommonCRS.defaultGeographic()); ftb.addAttribute(Date.class).setName("time"); FTYPE_STOP = ftb.build(); ftb = new FeatureTypeBuilder(); ftb.setName("Driver"); ftb.addAttribute(String.class).setName("name"); ftb.addAttribute(String.class).setName("code"); FTYPE_DRIVER = ftb.build(); ftb = new FeatureTypeBuilder(); ftb.setName("Voyage"); ftb.addAttribute(Long.class).setName("identifier"); ftb.addAssociation(FTYPE_DRIVER).setName("driver"); ftb.addAssociation(FTYPE_STOP).setName("stops").setMinimumOccurs(0).setMaximumOccurs(Integer.MAX_VALUE); FTYPE_COMPLEX = ftb.build(); //////////////////////////////////////////////////////////////////////// ftb = new FeatureTypeBuilder(); ftb.setName("Data"); ftb.addAttribute(Float[].class).setName("values"); FTYPE_DATA = ftb.build(); ftb = new FeatureTypeBuilder(); ftb.setName("Record"); ftb.addAttribute(Date.class).setName("time"); ftb.addAssociation(FTYPE_DATA).setName("datas").setMinimumOccurs(0).setMaximumOccurs(Integer.MAX_VALUE); FTYPE_RECORD = ftb.build(); ftb = new FeatureTypeBuilder(); ftb.setName("Sounding"); ftb.addAttribute(Long.class).setName("identifier"); ftb.addAssociation(FTYPE_RECORD).setName("records").setMinimumOccurs(0).setMaximumOccurs(Integer.MAX_VALUE); FTYPE_COMPLEX2 = ftb.build(); //////////////////////////////////////////////////////////////////////// ftb = new FeatureTypeBuilder(); ftb.setName("Data"); ftb.addAttribute(Float.class).setName("value"); FTYPE_SDATA = ftb.build(); ftb = new FeatureTypeBuilder(); ftb.setName("Record"); ftb.addAttribute(Long.class).setName("identifier"); ftb.addAssociation(FTYPE_SDATA).setName("data1"); ftb.addAssociation(FTYPE_SDATA).setName("data2"); ftb.addAssociation(FTYPE_SDATA).setName("data3"); FTYPE_COMPLEX3 = ftb.build(); } private PostgresFeatureStore store; public PostgresSimpleTypeTest(){ } private static ParameterValueGroup params; /** * <p>Find JDBC connection parameters in specified file at * "/home/.geotoolkit.org/test-pgfeature.properties".<br/> * If properties file doesn't find all tests are skipped.</p> * * <p>To lunch tests user should create file with this architecture<br/> * for example : <br/> * database = junit (table name)<br/> * port = 5432 (port number)<br/> * schema = public (schema name)<br/> * user = postgres (user login)<br/> * password = postgres (user password)<br/> * simpletype = false <br/> * namespace = no namespace</p> * @throws IOException */ @BeforeClass public static void beforeClass() throws IOException { String path = System.getProperty("user.home"); path += "/.geotoolkit.org/test-pgfeature.properties"; final File f = new File(path); Assume.assumeTrue(f.exists()); final Properties properties = new Properties(); properties.load(new FileInputStream(f)); params = FeatureExt.toParameter((Map)properties, PARAMETERS_DESCRIPTOR, false); } private void reload(boolean simpleType) throws DataStoreException, VersioningException { if(store != null){ store.close(); } //open in complex type to delete all types ParametersExt.getOrCreateValue(params, PostgresFeatureStoreFactory.SIMPLETYPE.getName().getCode()).setValue(false); store = (PostgresFeatureStore) DataStores.open(params); while(!store.getNames().isEmpty()){ // we get the list each type because relations may delete multiple types each time final GenericName n = store.getNames().iterator().next(); final VersionControl vc = store.getVersioning(n.toString()); vc.dropVersioning(); store.deleteFeatureType(n.toString()); } assertTrue(store.getNames().isEmpty()); store.close(); //reopen the way it was asked ParametersExt.getOrCreateValue(params, PostgresFeatureStoreFactory.SIMPLETYPE.getName().getCode()).setValue(simpleType); store = (PostgresFeatureStore) DataStores.open(params); assertTrue(store.getNames().isEmpty()); } @After public void disposeStore() { if (store != null) { store.close(); } } @Test public void testSimpleTypeCreation() throws DataStoreException, VersioningException { reload(true); final FeatureType refType = FTYPE_SIMPLE; store.createFeatureType(refType); assertEquals(1, store.getNames().size()); final FeatureType resType = store.getFeatureType(store.getNames().iterator().next().toString()); assertEquals(resType.getName().tip().toString(), refType.getName().tip().toString()); //we expect one more field for id final ArrayList<? extends PropertyType> descs = new ArrayList<>(resType.getProperties(true)); int index=2; PropertyType desc; desc = descs.get(index++); assertEquals("boolean", desc.getName().tip().toString()); assertEquals(Boolean.class, ((AttributeType)desc).getValueClass()); desc = descs.get(index++); assertEquals("byte", desc.getName().tip().toString()); assertEquals(Short.class, ((AttributeType)desc).getValueClass()); desc = descs.get(index++); assertEquals("short", desc.getName().tip().toString()); assertEquals(Short.class, ((AttributeType)desc).getValueClass()); desc = descs.get(index++); assertEquals("integer", desc.getName().tip().toString()); assertEquals(Integer.class, ((AttributeType)desc).getValueClass()); desc = descs.get(index++); assertEquals("long", desc.getName().tip().toString()); assertEquals(Long.class, ((AttributeType)desc).getValueClass()); desc = descs.get(index++); assertEquals("float", desc.getName().tip().toString()); assertEquals(Float.class, ((AttributeType)desc).getValueClass()); desc = descs.get(index++); assertEquals("double", desc.getName().tip().toString()); assertEquals(Double.class, ((AttributeType)desc).getValueClass()); desc = descs.get(index++); assertEquals("string", desc.getName().tip().toString()); assertEquals(String.class, ((AttributeType)desc).getValueClass()); } @Test public void testArrayTypeCreation() throws DataStoreException, VersioningException { reload(true); final FeatureType refType = FTYPE_ARRAY; store.createFeatureType(refType); assertEquals(1, store.getNames().size()); final FeatureType resType = store.getFeatureType(store.getNames().iterator().next().toString()); assertEquals(resType.getName().tip().toString(), refType.getName().tip().toString()); //we expect one more field for id final ArrayList<? extends PropertyType> descs = new ArrayList<>(resType.getProperties(true)); //Postgis allow NULL in arrays, so returned array are not primitive types int index=2; PropertyType desc; desc = descs.get(index++); assertEquals("boolean", desc.getName().tip().toString()); assertEquals(Boolean[].class, ((AttributeType)desc).getValueClass()); desc = descs.get(index++); assertEquals("byte", desc.getName().tip().toString()); assertEquals(Short[].class, ((AttributeType)desc).getValueClass()); desc = descs.get(index++); assertEquals("short", desc.getName().tip().toString()); assertEquals(Short[].class, ((AttributeType)desc).getValueClass()); desc = descs.get(index++); assertEquals("integer", desc.getName().tip().toString()); assertEquals(Integer[].class, ((AttributeType)desc).getValueClass()); desc = descs.get(index++); assertEquals("long", desc.getName().tip().toString()); assertEquals(Long[].class, ((AttributeType)desc).getValueClass()); desc = descs.get(index++); assertEquals("float", desc.getName().tip().toString()); assertEquals(Float[].class, ((AttributeType)desc).getValueClass()); desc = descs.get(index++); assertEquals("double", desc.getName().tip().toString()); assertEquals(Double[].class, ((AttributeType)desc).getValueClass()); desc = descs.get(index++); assertEquals("string", desc.getName().tip().toString()); assertEquals(String[].class, ((AttributeType)desc).getValueClass()); } @Test public void testArray2TypeCreation() throws DataStoreException, VersioningException { reload(true); final FeatureType refType = FTYPE_ARRAY2; store.createFeatureType(refType); assertEquals(1, store.getNames().size()); final FeatureType resType = store.getFeatureType(store.getNames().iterator().next().toString()); assertEquals(resType.getName().tip().toString(), refType.getName().tip().toString()); //we expect one more field for id final List<PropertyType> descs = new ArrayList<PropertyType>(resType.getProperties(true)); //Postgis allow NULL in arrays, so returned array are not primitive types int index=2; PropertyType desc; desc = descs.get(index++); assertEquals("boolean", desc.getName().tip().toString()); assertEquals(Boolean[][].class, ((AttributeType)desc).getValueClass()); desc = descs.get(index++); assertEquals("byte", desc.getName().tip().toString()); assertEquals(Short[][].class, ((AttributeType)desc).getValueClass()); desc = descs.get(index++); assertEquals("short", desc.getName().tip().toString()); assertEquals(Short[][].class, ((AttributeType)desc).getValueClass()); desc = descs.get(index++); assertEquals("integer", desc.getName().tip().toString()); assertEquals(Integer[][].class, ((AttributeType)desc).getValueClass()); desc = descs.get(index++); assertEquals("long", desc.getName().tip().toString()); assertEquals(Long[][].class, ((AttributeType)desc).getValueClass()); desc = descs.get(index++); assertEquals("float", desc.getName().tip().toString()); assertEquals(Float[][].class, ((AttributeType)desc).getValueClass()); desc = descs.get(index++); assertEquals("double", desc.getName().tip().toString()); assertEquals(Double[][].class, ((AttributeType)desc).getValueClass()); desc = descs.get(index++); assertEquals("string", desc.getName().tip().toString()); assertEquals(String[][].class, ((AttributeType)desc).getValueClass()); } @Test public void testGeometryTypeCreation() throws DataStoreException, NoSuchAuthorityCodeException, FactoryException, VersioningException { reload(true); final FeatureType refType = FTYPE_GEOMETRY; store.createFeatureType(refType); assertEquals(1, store.getNames().size()); final FeatureType resType = store.getFeatureType(store.getNames().iterator().next().toString()); assertEquals(resType.getName().tip().toString(), refType.getName().tip().toString()); //we expect one more field for id final ArrayList<? extends PropertyType> descs = new ArrayList<>(resType.getProperties(true)); int index=2; PropertyType desc; desc = descs.get(index++); assertEquals("geometry", desc.getName().tip().toString()); assertEquals(Geometry.class, ((AttributeType)desc).getValueClass()); assertTrue(AttributeConvention.isGeometryAttribute(desc)); assertEquals(CommonCRS.WGS84.normalizedGeographic(), FeatureExt.getCRS(desc)); desc = descs.get(index++); assertEquals("point", desc.getName().tip().toString()); assertEquals(Point.class, ((AttributeType)desc).getValueClass()); assertTrue(AttributeConvention.isGeometryAttribute(desc)); assertEquals(CommonCRS.WGS84.normalizedGeographic(), FeatureExt.getCRS(desc)); desc = descs.get(index++); assertEquals("multipoint", desc.getName().tip().toString()); assertEquals(MultiPoint.class, ((AttributeType)desc).getValueClass()); assertTrue(AttributeConvention.isGeometryAttribute(desc)); assertEquals(CommonCRS.WGS84.normalizedGeographic(), FeatureExt.getCRS(desc)); desc = descs.get(index++); assertEquals("linestring", desc.getName().tip().toString()); assertEquals(LineString.class, ((AttributeType)desc).getValueClass()); assertTrue(AttributeConvention.isGeometryAttribute(desc)); assertEquals(CommonCRS.WGS84.normalizedGeographic(), FeatureExt.getCRS(desc)); desc = descs.get(index++); assertEquals("multilinestring", desc.getName().tip().toString()); assertEquals(MultiLineString.class, ((AttributeType)desc).getValueClass()); assertTrue(AttributeConvention.isGeometryAttribute(desc)); assertEquals(CommonCRS.WGS84.normalizedGeographic(), FeatureExt.getCRS(desc)); desc = descs.get(index++); assertEquals("polygon", desc.getName().tip().toString()); assertEquals(Polygon.class, ((AttributeType)desc).getValueClass()); assertTrue(AttributeConvention.isGeometryAttribute(desc)); assertEquals(CommonCRS.WGS84.normalizedGeographic(), FeatureExt.getCRS(desc)); desc = descs.get(index++); assertEquals("multipolygon", desc.getName().tip().toString()); assertEquals(MultiPolygon.class, ((AttributeType)desc).getValueClass()); assertTrue(AttributeConvention.isGeometryAttribute(desc)); assertEquals(CommonCRS.WGS84.normalizedGeographic(), FeatureExt.getCRS(desc)); desc = descs.get(index++); assertEquals("geometrycollection", desc.getName().tip().toString()); assertEquals(GeometryCollection.class, ((AttributeType)desc).getValueClass()); assertTrue(AttributeConvention.isGeometryAttribute(desc)); assertEquals(CommonCRS.WGS84.normalizedGeographic(), FeatureExt.getCRS(desc)); } @Test public void testSimpleInsert() throws DataStoreException, VersioningException{ reload(true); store.createFeatureType(FTYPE_SIMPLE); FeatureType resType = store.getFeatureType(store.getNames().iterator().next().toString()); Feature feature = resType.newInstance(); feature.setPropertyValue("boolean",true); feature.setPropertyValue("byte",(short)45); //byte type do not exist, it's converted to smallint/int2 feature.setPropertyValue("short",(short)963); feature.setPropertyValue("integer",123456); feature.setPropertyValue("long",456789l); feature.setPropertyValue("float",7.3f); feature.setPropertyValue("double",14.5); feature.setPropertyValue("string","a string"); List<FeatureId> addedIds = store.addFeatures(resType.getName().toString(), Collections.singleton(feature)); assertEquals(1, addedIds.size()); assertEquals(new DefaultFeatureId("1"), addedIds.get(0)); Session session = store.createSession(false); FeatureCollection col = session.getFeatureCollection(QueryBuilder.all(resType.getName().toString())); assertEquals(1, col.size()); FeatureIterator ite = col.iterator(); try{ final Feature resFeature = ite.next(); assertNotNull(resFeature); assertEquals(true, resFeature.getPropertyValue("boolean")); assertEquals((short)45, resFeature.getPropertyValue("byte")); assertEquals((short)963, resFeature.getPropertyValue("short")); assertEquals(123456, resFeature.getPropertyValue("integer")); assertEquals(456789l, resFeature.getPropertyValue("long")); assertEquals(7.3f, resFeature.getPropertyValue("float")); assertEquals(14.5d, resFeature.getPropertyValue("double")); assertEquals("a string", resFeature.getPropertyValue("string")); }finally{ ite.close(); } // SECOND TEST for NAN values ------------------------------------------ reload(true); store.createFeatureType(FTYPE_SIMPLE); resType = store.getFeatureType(store.getNames().iterator().next().toString()); feature = resType.newInstance(); feature.setPropertyValue("fid",0); feature.setPropertyValue("boolean",true); feature.setPropertyValue("byte",(short)45); feature.setPropertyValue("short",(short)963); feature.setPropertyValue("integer",123456); feature.setPropertyValue("long",456789l); feature.setPropertyValue("float",Float.NaN); feature.setPropertyValue("double",Double.NaN); feature.setPropertyValue("string","a string"); addedIds = store.addFeatures(resType.getName().toString(), Collections.singleton(feature)); assertEquals(1, addedIds.size()); assertEquals(new DefaultFeatureId("1"), addedIds.get(0)); session = store.createSession(false); col = session.getFeatureCollection(QueryBuilder.all(resType.getName().toString())); assertEquals(1, col.size()); ite = col.iterator(); try{ final Feature resFeature = ite.next(); assertNotNull(resFeature); assertEquals(true, resFeature.getPropertyValue("boolean")); assertEquals((short)45, resFeature.getPropertyValue("byte")); assertEquals((short)963, resFeature.getPropertyValue("short")); assertEquals(123456, resFeature.getPropertyValue("integer")); assertEquals(456789l, resFeature.getPropertyValue("long")); assertEquals(Float.NaN, resFeature.getPropertyValue("float")); assertEquals(Double.NaN, resFeature.getPropertyValue("double")); assertEquals("a string", resFeature.getPropertyValue("string")); }finally{ ite.close(); } } @Test public void testArrayInsert() throws DataStoreException, VersioningException{ reload(true); store.createFeatureType(FTYPE_ARRAY); final FeatureType resType = store.getFeatureType(store.getNames().iterator().next().toString()); final Feature feature = resType.newInstance(); feature.setPropertyValue("fid",0); feature.setPropertyValue("boolean",new Boolean[]{true,false,true}); feature.setPropertyValue("byte",new Short[]{3,6,9}); feature.setPropertyValue("short",new Short[]{-5,12,-50}); feature.setPropertyValue("integer",new Integer[]{123,456,789}); feature.setPropertyValue("long",new Long[]{111l,222l,333l}); feature.setPropertyValue("float",new Float[]{1.2f,-5.9f,8.1f}); feature.setPropertyValue("double",new Double[]{78.3d,41.23d,-99.66d}); feature.setPropertyValue("string",new String[]{"marc","hubert","samy"}); List<FeatureId> addedIds = store.addFeatures(resType.getName().toString(), Collections.singleton(feature)); assertEquals(1, addedIds.size()); assertEquals(new DefaultFeatureId("1"), addedIds.get(0)); final Session session = store.createSession(false); final FeatureCollection col = session.getFeatureCollection(QueryBuilder.all(resType.getName().toString())); assertEquals(1, col.size()); //Postgis allow NULL in arrays, so returned array are not primitive types final FeatureIterator ite = col.iterator(); try{ final Feature resFeature = ite.next(); assertNotNull(resFeature); assertArrayEquals(new Boolean[]{true,false,true}, (Boolean[])resFeature.getPropertyValue("boolean")); assertArrayEquals(new Short[]{3,6,9}, (Short[])resFeature.getPropertyValue("byte")); assertArrayEquals(new Short[]{-5,12,-50}, (Short[])resFeature.getPropertyValue("short")); assertArrayEquals(new Integer[]{123,456,789}, (Integer[])resFeature.getPropertyValue("integer")); assertArrayEquals(new Long[]{111l,222l,333l}, (Long[])resFeature.getPropertyValue("long")); assertArrayEquals(new Float[]{1.2f,-5.9f,8.1f}, (Float[])resFeature.getPropertyValue("float")); assertArrayEquals(new Double[]{78.3d,41.23d,-99.66d}, (Double[])resFeature.getPropertyValue("double")); assertArrayEquals(new String[]{"marc","hubert","samy"}, (String[])resFeature.getPropertyValue("string")); }finally{ ite.close(); } } @Test public void testArray2Insert() throws DataStoreException, VersioningException{ reload(true); store.createFeatureType(FTYPE_ARRAY2); final FeatureType resType = store.getFeatureType(store.getNames().iterator().next().toString()); final Feature feature = resType.newInstance(); feature.setPropertyValue("fid", 0); feature.setPropertyValue("boolean",new Boolean[][]{{true,false,true},{false,true,false},{false,false,false}}); feature.setPropertyValue("byte",new Short[][]{{1,2,3},{4,5,6},{7,8,9}}); feature.setPropertyValue("short",new Short[][]{{1,2,3},{4,5,6},{7,8,9}}); feature.setPropertyValue("integer",new Integer[][]{{1,2,3},{4,5,6},{7,8,9}}); feature.setPropertyValue("long",new Long[][]{{1l,2l,3l},{4l,5l,6l},{7l,8l,9l}}); feature.setPropertyValue("float",new Float[][]{{1f,2f,3f},{4f,5f,6f},{7f,8f,9f}}); feature.setPropertyValue("double",new Double[][]{{1d,2d,3d},{4d,5d,6d},{7d,8d,9d}}); feature.setPropertyValue("string",new String[][]{{"1","2","3"},{"4","5","6"},{"7","8","9"}}); List<FeatureId> addedIds = store.addFeatures(resType.getName().toString(), Collections.singleton(feature)); assertEquals(1, addedIds.size()); assertEquals(new DefaultFeatureId("1"), addedIds.get(0)); final Session session = store.createSession(false); final FeatureCollection col = session.getFeatureCollection(QueryBuilder.all(resType.getName().toString())); assertEquals(1, col.size()); //Postgis allow NULL in arrays, so returned array are not primitive types final FeatureIterator ite = col.iterator(); try{ final Feature resFeature = ite.next(); assertNotNull(resFeature); assertArrayEquals((Boolean[][])feature.getPropertyValue("boolean"), (Boolean[][])resFeature.getPropertyValue("boolean")); assertArrayEquals((Short[][])feature.getPropertyValue("byte"), (Short[][])resFeature.getPropertyValue("byte")); assertArrayEquals((Short[][])feature.getPropertyValue("short"), (Short[][])resFeature.getPropertyValue("short")); assertArrayEquals((Integer[][])feature.getPropertyValue("integer"), (Integer[][])resFeature.getPropertyValue("integer")); assertArrayEquals((Long[][])feature.getPropertyValue("long"), (Long[][])resFeature.getPropertyValue("long")); assertArrayEquals((Float[][])feature.getPropertyValue("float"), (Float[][])resFeature.getPropertyValue("float")); assertArrayEquals((Double[][])feature.getPropertyValue("double"), (Double[][])resFeature.getPropertyValue("double")); assertArrayEquals((String[][])feature.getPropertyValue("string"), (String[][])resFeature.getPropertyValue("string")); }finally{ ite.close(); } } @Test public void testGeometryInsert() throws DataStoreException, NoSuchAuthorityCodeException, FactoryException, VersioningException{ reload(true); //////////////////////////////////////////////////////////////////////// final GeometryFactory gf = new GeometryFactory(); //creating a point ----------------------------------------------- final Point point = gf.createPoint(new Coordinate(56, 45)); //creating a multipoint ------------------------------------------ final MultiPoint mp = gf.createMultiPoint(new Coordinate[]{ new Coordinate(23, 78), new Coordinate(-10, 43), new Coordinate(12, 94)}); //creating a linestring ------------------------------------------ final LineString ls = gf.createLineString(new Coordinate[]{ new Coordinate(23, 78), new Coordinate(-10, 43), new Coordinate(12, 94)}); //creating a multilinestring ------------------------------------- final LineString ls1 = gf.createLineString(new Coordinate[]{ new Coordinate(30, 45),new Coordinate(56, 29)}); final LineString ls2 = gf.createLineString(new Coordinate[]{ new Coordinate(98,12),new Coordinate(19, 87)}); final MultiLineString mls = gf.createMultiLineString(new LineString[]{ ls1,ls2}); //creating a polygon --------------------------------------------- final LinearRing ring = gf.createLinearRing(new Coordinate[]{ new Coordinate(23, 78), new Coordinate(-10, 43), new Coordinate(12, 94), new Coordinate(23, 78)}); final Polygon polygon = gf.createPolygon(ring, new LinearRing[0]); //creating a multipolygon ---------------------------------------- final MultiPolygon mpolygon = gf.createMultiPolygon(new Polygon[]{polygon}); //creating a geometry collection ---------------------------------------- final GeometryCollection gc = gf.createGeometryCollection(new Geometry[]{point,ls,polygon}); //////////////////////////////////////////////////////////////////////// store.createFeatureType(FTYPE_GEOMETRY); final FeatureType resType = store.getFeatureType(store.getNames().iterator().next().toString()); final Feature feature = resType.newInstance(); feature.setPropertyValue("fid", 0); feature.setPropertyValue("geometry",point); feature.setPropertyValue("point",point); feature.setPropertyValue("multipoint",mp); feature.setPropertyValue("linestring",ls); feature.setPropertyValue("multilinestring",mls); feature.setPropertyValue("polygon",polygon); feature.setPropertyValue("multipolygon",mpolygon); feature.setPropertyValue("geometrycollection",gc); List<FeatureId> addedIds = store.addFeatures(resType.getName().toString(), Collections.singleton(feature)); assertEquals(1, addedIds.size()); assertEquals(new DefaultFeatureId("1"), addedIds.get(0)); final Session session = store.createSession(false); final FeatureCollection col = session.getFeatureCollection(QueryBuilder.all(resType.getName().toString())); assertEquals(1, col.size()); //Postgis allow NULL in arrays, so returned array are not primitive types final FeatureIterator ite = col.iterator(); try{ final Feature resFeature = ite.next(); assertNotNull(resFeature); Geometry geom; geom = (Geometry)resFeature.getPropertyValue("geometry"); assertEquals(point,geom); assertEquals(CommonCRS.WGS84.normalizedGeographic(), JTS.findCoordinateReferenceSystem(geom)); geom = (Geometry)resFeature.getPropertyValue("point"); assertEquals(point,geom); assertEquals(CommonCRS.WGS84.normalizedGeographic(), JTS.findCoordinateReferenceSystem(geom)); geom = (Geometry)resFeature.getPropertyValue("multipoint"); assertEquals(mp,geom); assertEquals(CommonCRS.WGS84.normalizedGeographic(), JTS.findCoordinateReferenceSystem(geom)); geom = (Geometry)resFeature.getPropertyValue("linestring"); assertEquals(ls,geom); assertEquals(CommonCRS.WGS84.normalizedGeographic(), JTS.findCoordinateReferenceSystem(geom)); geom = (Geometry)resFeature.getPropertyValue("multilinestring"); assertEquals(mls,geom); assertEquals(CommonCRS.WGS84.normalizedGeographic(), JTS.findCoordinateReferenceSystem(geom)); geom = (Geometry)resFeature.getPropertyValue("polygon"); assertEquals(polygon,geom); assertEquals(CommonCRS.WGS84.normalizedGeographic(), JTS.findCoordinateReferenceSystem(geom)); geom = (Geometry)resFeature.getPropertyValue("multipolygon"); assertEquals(mpolygon,geom); assertEquals(CommonCRS.WGS84.normalizedGeographic(), JTS.findCoordinateReferenceSystem(geom)); geom = (Geometry)resFeature.getPropertyValue("geometrycollection"); assertEquals(gc,geom); assertEquals(CommonCRS.WGS84.normalizedGeographic(), JTS.findCoordinateReferenceSystem(geom)); }finally{ ite.close(); } } /** * Test ugly named table * * @throws DataStoreException * @throws VersioningException */ @Test public void testUglyTableName() throws Exception{ reload(true); final FeatureTypeBuilder ftb = new FeatureTypeBuilder(); ftb.setName("test'te#st$'test\"'test"); ftb.addAttribute(String.class).setName("text"); final FeatureType ft = ftb.build(); store.createFeatureType(ft); final FeatureType resType = store.getFeatureType(store.getNames().iterator().next().toString()); final Feature record = resType.newInstance(); record.setPropertyValue("text","un'deux'trois'quatre"); List<FeatureId> addedIds = store.addFeatures(resType.getName().toString(), Collections.singleton(record)); assertEquals(1, addedIds.size()); assertEquals(new DefaultFeatureId("1"), addedIds.get(0)); final Query query = QueryBuilder.all(resType.getName().toString()); final FeatureReader ite = store.getFeatureReader(query); boolean found = false; try{ while(ite.hasNext()){ final Feature feature = ite.next(); Object val = feature.getPropertyValue("text"); assertEquals("un'deux'trois'quatre", val); found = true; } }finally{ ite.close(); } assertTrue(found); } }