/* * 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.mysql; 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.sql.Timestamp; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; 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.AttributeRole; 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.geotoolkit.db.JDBCFeatureStore; import org.apache.sis.storage.DataStoreException; import org.geotoolkit.util.NamesExt; 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.mysql.MySQLFeatureStoreFactory.*; import org.geotoolkit.storage.DataStores; import org.apache.sis.referencing.CommonCRS; import static org.junit.Assert.*; import org.junit.Ignore; import org.opengis.feature.AttributeType; import org.opengis.feature.Feature; import org.opengis.feature.FeatureType; import org.opengis.feature.PropertyType; import org.opengis.referencing.crs.CoordinateReferenceSystem; /** * * @author Johann Sorel (Geomatys) */ public class MySQLFeatureStoreTest extends org.geotoolkit.test.TestBase { private static final double DELTA = 0.00000001; /** 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; /** 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 = 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(); //////////////////////////////////////////////////////////////////////// final CoordinateReferenceSystem crs = CommonCRS.defaultGeographic(); ftb = new FeatureTypeBuilder(); ftb.setName("testTable"); ftb.addAttribute(Geometry.class).setName("geometry").setCRS(crs); ftb.addAttribute(Point.class).setName("point").setCRS(crs); ftb.addAttribute(MultiPoint.class).setName("multipoint").setCRS(crs); ftb.addAttribute(LineString.class).setName("linestring").setCRS(crs); ftb.addAttribute(MultiLineString.class).setName("multilinestring").setCRS(crs); ftb.addAttribute(Polygon.class).setName("polygon").setCRS(crs); ftb.addAttribute(MultiPolygon.class).setName("multipolygon").setCRS(crs); ftb.addAttribute(GeometryCollection.class).setName("geometrycollection").setCRS(crs); FTYPE_GEOMETRY = ftb.build(); //////////////////////////////////////////////////////////////////////// ftb = new FeatureTypeBuilder(); ftb.setName("Stop"); ftb.addAttribute(Point.class).setName("location").setCRS(crs); 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").addRole(AttributeRole.IDENTIFIER_COMPONENT); 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 = 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").addRole(AttributeRole.IDENTIFIER_COMPONENT); ftb.addAssociation(FTYPE_RECORD).setName("records").setMinimumOccurs(0).setMaximumOccurs(Integer.MAX_VALUE); FTYPE_COMPLEX2 = ftb.build(); //////////////////////////////////////////////////////////////////////// ftb = new FeatureTypeBuilder(); 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").addRole(AttributeRole.IDENTIFIER_COMPONENT); ftb.addAssociation(FTYPE_SDATA).setName("data1").setMinimumOccurs(0).setMaximumOccurs(1); ftb.addAssociation(FTYPE_SDATA).setName("data2").setMinimumOccurs(0).setMaximumOccurs(1); ftb.addAssociation(FTYPE_SDATA).setName("data3").setMinimumOccurs(0).setMaximumOccurs(1); FTYPE_COMPLEX3 = ftb.build(); } private MySQLFeatureStore store; public MySQLFeatureStoreTest(){ } private static ParameterValueGroup params; /** * <p>Find JDBC connection parameters in specified file at * "/home/.geotoolkit.org/test-msfeature.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-msfeature.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, MySQLFeatureStoreFactory.SIMPLETYPE.getName().getCode()).setValue(false); store = (MySQLFeatureStore) DataStores.open(params); for(GenericName n : store.getNames()){ 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, MySQLFeatureStoreFactory.SIMPLETYPE.getName().getCode()).setValue(simpleType); store = (MySQLFeatureStore) DataStores.open(params); assertTrue(store.getNames().isEmpty()); } @Ignore @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 List<PropertyType> descs = new ArrayList<PropertyType>(resType.getProperties(true)); int index=1; 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()); } @Ignore @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 List<? extends PropertyType> descs = new ArrayList<>(resType.getProperties(true)); int index=1; PropertyType desc; desc = descs.get(index++); assertEquals("geometry", desc.getName().tip().toString()); assertEquals(Geometry.class, ((AttributeType)desc).getValueClass()); assertTrue(AttributeConvention.isGeometryAttribute(desc)); assertEquals(CommonCRS.defaultGeographic(), 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.defaultGeographic(), 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.defaultGeographic(), 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.defaultGeographic(), 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.defaultGeographic(), 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.defaultGeographic(), 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.defaultGeographic(), 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.defaultGeographic(), FeatureExt.getCRS(desc)); } @Ignore @Test public void testFeatureTypeCreation() throws DataStoreException, VersioningException{ reload(false); final FeatureType refType = FTYPE_COMPLEX; store.createFeatureType(refType); assertEquals(1, store.getNames().size()); final GenericName name = store.getNames().iterator().next(); final FeatureType created = store.getFeatureType(name.toString()); lazyCompare(refType, created); } @Ignore @Test public void testFeatureType2Creation() throws DataStoreException, VersioningException{ reload(false); final FeatureType refType = FTYPE_COMPLEX2; store.createFeatureType(refType); assertEquals(1, store.getNames().size()); final GenericName name = store.getNames().iterator().next(); final FeatureType created = store.getFeatureType(name.toString()); lazyCompare(refType, created); } @Ignore @Test public void testFeatureType3Creation() throws DataStoreException, VersioningException{ reload(false); final FeatureType refType = FTYPE_COMPLEX3; store.createFeatureType(refType); assertEquals(1, store.getNames().size()); final GenericName name = store.getNames().iterator().next(); final FeatureType created = store.getFeatureType(name.toString()); lazyCompare(refType, created); } private void lazyCompare(final FeatureType refType, final FeatureType candidate){ final GenericName name = refType.getName(); assertEquals(refType.getName().tip().toString(), name.tip().toString()); final FeatureType ct = (FeatureType) refType; final FeatureType cct = (FeatureType) candidate; assertEquals(ct.getProperties(true).size()+1, cct.getProperties(true).size());// +1 for generated fid field for(PropertyType desc : ct.getProperties(true)){ final PropertyType cdesc = cct.getProperty(desc.getName().tip().toString()); assertEquals(desc, cdesc); } } @Ignore @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",45); feature.setPropertyValue("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"); store.addFeatures(resType.getName().toString(), Collections.singleton(feature)); 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(45, resFeature.getPropertyValue("byte")); assertEquals(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("boolean",true); feature.setPropertyValue("byte",45); feature.setPropertyValue("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"); store.addFeatures(resType.getName().toString(), Collections.singleton(feature)); 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(45, resFeature.getPropertyValue("byte")); assertEquals(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(); } } @Ignore @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("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); store.addFeatures(resType.getName().toString(), Collections.singleton(feature)); 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.getProperty("geometry").getValue(); assertEquals(point,geom); assertEquals(CommonCRS.defaultGeographic(), JTS.findCoordinateReferenceSystem(geom)); geom = (Geometry)resFeature.getProperty("point").getValue(); assertEquals(point,geom); assertEquals(CommonCRS.defaultGeographic(), JTS.findCoordinateReferenceSystem(geom)); geom = (Geometry)resFeature.getProperty("multipoint").getValue(); assertEquals(mp,geom); assertEquals(CommonCRS.defaultGeographic(), JTS.findCoordinateReferenceSystem(geom)); geom = (Geometry)resFeature.getProperty("linestring").getValue(); assertEquals(ls,geom); assertEquals(CommonCRS.defaultGeographic(), JTS.findCoordinateReferenceSystem(geom)); geom = (Geometry)resFeature.getProperty("multilinestring").getValue(); assertEquals(mls,geom); assertEquals(CommonCRS.defaultGeographic(), JTS.findCoordinateReferenceSystem(geom)); geom = (Geometry)resFeature.getProperty("polygon").getValue(); assertEquals(polygon,geom); assertEquals(CommonCRS.defaultGeographic(), JTS.findCoordinateReferenceSystem(geom)); geom = (Geometry)resFeature.getProperty("multipolygon").getValue(); assertEquals(mpolygon,geom); assertEquals(CommonCRS.defaultGeographic(), JTS.findCoordinateReferenceSystem(geom)); geom = (Geometry)resFeature.getProperty("geometrycollection").getValue(); assertEquals(gc,geom); assertEquals(CommonCRS.defaultGeographic(), JTS.findCoordinateReferenceSystem(geom)); }finally{ ite.close(); } } /** * 2 level depths feature test. */ @Ignore @Test public void testComplexInsert() throws DataStoreException, VersioningException{ reload(false); final GeometryFactory gf = new GeometryFactory(); store.createFeatureType(FTYPE_COMPLEX); final FeatureType resType = store.getFeatureType(store.getNames().iterator().next().toString()); final Feature voyage = resType.newInstance(); voyage.setPropertyValue("identifier",120); final Feature driver = FTYPE_DRIVER.newInstance(); driver.setPropertyValue("name","jean-michel"); driver.setPropertyValue("code","BHF:123456"); voyage.setPropertyValue("driver", driver); final Feature stop1 = FTYPE_STOP.newInstance(); stop1.setPropertyValue("location",gf.createPoint(new Coordinate(-10, 60))); stop1.setPropertyValue("time",new Date(5000000)); final Feature stop2 = FTYPE_STOP.newInstance(); stop2.setPropertyValue("location",gf.createPoint(new Coordinate(30, 15))); stop2.setPropertyValue("time",new Date(6000000)); final Feature stop3 = FTYPE_STOP.newInstance(); stop3.setPropertyValue("location",gf.createPoint(new Coordinate(40, -70))); stop3.setPropertyValue("time",new Date(7000000)); voyage.setPropertyValue("stops", Arrays.asList(stop1,stop2,stop3)); store.addFeatures(resType.getName().toString(), Collections.singleton(voyage)); final Session session = store.createSession(false); final FeatureCollection col = session.getFeatureCollection(QueryBuilder.all(resType.getName().toString())); assertEquals(1, col.size()); final FeatureIterator ite = col.iterator(); try{ final Feature resFeature = ite.next(); assertNotNull(resFeature); assertEquals(120l, resFeature.getProperty("identifier").getValue()); final Feature resDriver = (Feature) resFeature.getProperty("driver"); assertEquals("jean-michel", resDriver.getProperty("name").getValue()); assertEquals("BHF:123456", resDriver.getProperty("code").getValue()); final Collection<Feature> stops = (Collection<Feature>) resFeature.getPropertyValue("stops"); assertEquals(3, stops.size()); final boolean[] found = new boolean[3]; for(Feature stop : stops){ final Timestamp time = (Timestamp) stop.getProperty("time").getValue(); final Point location = (Point) stop.getProperty("location").getValue(); if(time.getTime() == 5000000){ assertEquals(stop1.getProperty("location").getValue(), location); found[0] = true; }else if(time.getTime() == 6000000){ assertEquals(stop2.getProperty("location").getValue(), location); found[1] = true; }else if(time.getTime() == 7000000){ assertEquals(stop3.getProperty("location").getValue(), location); found[2] = true; }else{ fail("Unexpected property \n"+stop); } } for(boolean b : found) assertTrue(b); }finally{ ite.close(); } } /** * 3 level depths feature test. */ @Ignore @Test public void testComplex2Insert() throws DataStoreException, VersioningException{ reload(false); store.createFeatureType(FTYPE_COMPLEX2); final FeatureType soundingType = store.getFeatureType(store.getNames().iterator().next().toString()); final Feature sounding = soundingType.newInstance(); sounding.setPropertyValue("identifier",120); final Feature record1 = FTYPE_RECORD.newInstance(); record1.setPropertyValue("time",new Date(5000000)); final Feature data11 = FTYPE_DATA.newInstance(); data11.setPropertyValue("values",new Float[]{1f,2f,3f}); final Feature data12 = FTYPE_DATA.newInstance(); data12.setPropertyValue("values",new Float[]{4f,5f,6f}); record1.setPropertyValue("datas", Arrays.asList(data11,data12)); final Feature record2 = FTYPE_RECORD.newInstance(); record2.setPropertyValue("time",new Date(6000000)); final Feature data21 = FTYPE_DATA.newInstance(); data21.setPropertyValue("values",new Float[]{7f,8f,9f}); record2.setPropertyValue("datas", Arrays.asList(data21)); sounding.setPropertyValue("records", Arrays.asList(record1,record2)); store.addFeatures(soundingType.getName().toString(), Collections.singleton(sounding)); final Session session = store.createSession(false); final FeatureCollection col = session.getFeatureCollection(QueryBuilder.all(soundingType.getName().toString())); assertEquals(1, col.size()); final FeatureIterator ite = store.getFeatureReader(QueryBuilder.all(soundingType.getName().toString())); try{ final Feature resFeature = ite.next(); assertNotNull(resFeature); assertEquals(120l, resFeature.getProperty("identifier").getValue()); final Collection<Feature> records = (Collection<Feature>) resFeature.getPropertyValue("records"); assertEquals(2, records.size()); final boolean[] found = new boolean[2]; for(Feature record : records){ final Timestamp time = (Timestamp) record.getProperty("time").getValue(); if(time.getTime() == 5000000){ found[0] = true; final Collection<Feature> datas = (Collection<Feature>) record.getPropertyValue("datas"); assertEquals(2, datas.size()); final boolean[] dfound = new boolean[2]; for(Feature data : datas){ final Float[] values = (Float[]) data.getProperty("values").getValue(); if(Arrays.equals(values, new Float[]{1f,2f,3f})){ dfound[0] = true; }else if(Arrays.equals(values, new Float[]{4f,5f,6f})){ dfound[1] = true; }else{ fail("Unexpected property \n"+data); } } for(boolean b : dfound) assertTrue(b); }else if(time.getTime() == 6000000){ found[1] = true; final Collection<Feature> datas = (Collection<Feature>) record.getPropertyValue("datas"); assertEquals(1, datas.size()); final boolean[] dfound = new boolean[1]; for(Feature data : datas){ final Float[] values = (Float[]) data.getProperty("values").getValue(); if(Arrays.equals(values, new Float[]{7f,8f,9f})){ dfound[0] = true; }else{ fail("Unexpected property \n"+data); } } for(boolean b : dfound) assertTrue(b); }else{ fail("Unexpected property \n"+record); } } for(boolean b : found) assertTrue(b); }finally{ ite.close(); } } /** * multiple complex properties of same type */ @Ignore @Test public void testComplex3Insert() throws DataStoreException, VersioningException{ reload(false); store.createFeatureType(FTYPE_COMPLEX3); final FeatureType recordType = store.getFeatureType(store.getNames().iterator().next().toString()); final Feature record = recordType.newInstance(); record.setPropertyValue("identifier",120); final Feature data1 = FTYPE_SDATA.newInstance(); data1.setPropertyValue("value",5f); final Feature data2 = FTYPE_SDATA.newInstance(); data2.setPropertyValue("value",10f); final Feature data3 = FTYPE_SDATA.newInstance(); data3.setPropertyValue("value",15f); record.setPropertyValue("datas", Arrays.asList(data1,data2,data3)); store.addFeatures(recordType.getName().toString(), Collections.singleton(record)); final Session session = store.createSession(false); final FeatureCollection col = session.getFeatureCollection(QueryBuilder.all(recordType.getName().toString())); assertEquals(1, col.size()); final FeatureIterator ite = store.getFeatureReader(QueryBuilder.all(recordType.getName().toString())); try{ final Feature resFeature = ite.next(); assertNotNull(resFeature); assertEquals(120l, resFeature.getProperty("identifier").getValue()); assertNotNull(resFeature.getProperty("data1")); assertNotNull(resFeature.getProperty("data2")); assertNotNull(resFeature.getProperty("data3")); assertEquals(5f, ((Feature)resFeature.getProperty("data1")).getProperty("value").getValue()); assertEquals(10f, ((Feature)resFeature.getProperty("data2")).getProperty("value").getValue()); assertEquals(15f, ((Feature)resFeature.getProperty("data3")).getProperty("value").getValue()); }finally{ ite.close(); } } /** * Test hand made query. * * @throws DataStoreException * @throws VersioningException */ @Ignore @Test public void testHandMadeSQLQuery() throws Exception{ reload(false); final GeometryFactory gf = new GeometryFactory(); store.createFeatureType(FTYPE_COMPLEX); final FeatureType resType = store.getFeatureType(store.getNames().iterator().next().toString()); final Feature voyage = resType.newInstance(); voyage.setPropertyValue("identifier",120); final Feature driver = FTYPE_DRIVER.newInstance(); driver.setPropertyValue("name","jean-michel"); driver.setPropertyValue("code","BHF:123456"); voyage.setPropertyValue("driver", driver); final Feature stop1 = FTYPE_STOP.newInstance(); stop1.setPropertyValue("location",gf.createPoint(new Coordinate(-10, 60))); stop1.setPropertyValue("time",new Date(5000000)); final Feature stop2 = FTYPE_STOP.newInstance(); stop2.setPropertyValue("location",gf.createPoint(new Coordinate(30, 15))); stop2.setPropertyValue("time",new Date(6000000)); final Feature stop3 = FTYPE_STOP.newInstance(); stop3.setPropertyValue("location",gf.createPoint(new Coordinate(40, -70))); stop3.setPropertyValue("time",new Date(7000000)); voyage.setPropertyValue("stops", Arrays.asList(stop1,stop2,stop3)); store.addFeatures(resType.getName().toString(), Collections.singleton(voyage)); final Query query = QueryBuilder.language(JDBCFeatureStore.CUSTOM_SQL, "SELECT * FROM \"Stop\"", "s1"); final FeatureReader ite = store.getFeatureReader(query); final boolean[] found = new boolean[3]; try{ while(ite.hasNext()){ final Feature feature = ite.next(); final Timestamp time = (Timestamp) feature.getProperty("time").getValue(); final Point location = (Point) feature.getProperty("location").getValue(); if(time.getTime() == 5000000){ assertEquals(stop1.getProperty("location").getValue(), location); found[0] = true; }else if(time.getTime() == 6000000){ assertEquals(stop2.getProperty("location").getValue(), location); found[1] = true; }else if(time.getTime() == 7000000){ assertEquals(stop3.getProperty("location").getValue(), location); found[2] = true; }else{ fail("Unexpected property \n"+feature); } assertNotNull(JTS.findCoordinateReferenceSystem((Geometry)FeatureExt.getDefaultGeometryAttributeValue(feature))); } }finally{ ite.close(); } for(boolean b : found) assertTrue(b); } }