001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2002-2006, GeoTools Project Managment Committee (PMC)
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation;
009: * version 2.1 of the License.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: */
016: package org.geotools.data.mysql;
017:
018: import java.io.BufferedReader;
019: import java.io.IOException;
020: import java.io.InputStreamReader;
021: import java.sql.Connection;
022: import java.sql.PreparedStatement;
023: import java.sql.SQLException;
024: import java.sql.Statement;
025: import java.util.NoSuchElementException;
026: import java.util.PropertyResourceBundle;
027: import java.util.logging.Level;
028: import java.util.logging.Logger;
029:
030: import junit.framework.Test;
031: import junit.framework.TestCase;
032: import junit.framework.TestSuite;
033:
034: import org.geotools.data.DefaultQuery;
035: import org.geotools.data.DefaultTransaction;
036: import org.geotools.data.FeatureReader;
037: import org.geotools.data.FeatureSource;
038: import org.geotools.data.FeatureWriter;
039: import org.geotools.data.Query;
040: import org.geotools.data.SchemaNotFoundException;
041: import org.geotools.data.Transaction;
042: import org.geotools.data.jdbc.ConnectionPoolManager;
043: import org.geotools.data.jdbc.JDBCTransactionState;
044: import org.geotools.data.jdbc.datasource.ManageableDataSource;
045: import org.geotools.data.jdbc.fidmapper.BasicFIDMapper;
046: import org.geotools.data.jdbc.fidmapper.TypedFIDMapper;
047: import org.geotools.feature.Feature;
048: import org.geotools.feature.FeatureCollection;
049: import org.geotools.feature.FeatureCollections;
050: import org.geotools.feature.FeatureType;
051: import org.geotools.feature.IllegalAttributeException;
052: import org.geotools.feature.SimpleFeature;
053: import org.geotools.filter.AbstractFilter;
054: import org.geotools.filter.CompareFilter;
055: import org.geotools.filter.Expression;
056: import org.geotools.filter.Filter;
057: import org.geotools.filter.FilterFactory;
058: import org.geotools.filter.FilterFactoryFinder;
059: import org.geotools.filter.IllegalFilterException;
060: import org.geotools.filter.LiteralExpression;
061:
062: import com.vividsolutions.jts.geom.Coordinate;
063: import com.vividsolutions.jts.geom.Envelope;
064: import com.vividsolutions.jts.geom.GeometryFactory;
065: import com.vividsolutions.jts.geom.LineString;
066: import com.vividsolutions.jts.geom.LinearRing;
067: import com.vividsolutions.jts.geom.MultiPolygon;
068: import com.vividsolutions.jts.geom.Polygon;
069: import com.vividsolutions.jts.geom.PrecisionModel;
070:
071: /**
072: * Test for mysql. Must use a locally available instance of mysql.
073: *
074: * @author Chris Holmes, TOPP
075: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/unsupported/mysql/src/test/java/org/geotools/data/mysql/MySQLDataStoreTest.java $
076: */
077: public class MySQLDataStoreTest extends TestCase {
078: /** The logger for the filter module. */
079: private static final Logger LOGGER = org.geotools.util.logging.Logging
080: .getLogger("org.geotools.postgis");
081: private static String FEATURE_TABLE = "testset";
082: private static String TEST_NS = "http://www.geotools.org/data/postgis";
083: private static GeometryFactory geomFac = new GeometryFactory();
084: private FilterFactory filterFac = FilterFactoryFinder
085: .createFilterFactory();
086: private FeatureCollection collection = FeatureCollections
087: .newCollection();
088: private FeatureType schema;
089: private int srid = -1;
090: private MySQLDataStore dstore;
091: private ManageableDataSource connPool;
092: private CompareFilter tFilter;
093: private int addId = 32;
094: private org.geotools.filter.GeometryFilter geomFilter;
095:
096: public MySQLDataStoreTest(String testName) {
097: super (testName);
098: }
099:
100: public static void main(String[] args) {
101: junit.textui.TestRunner.run(suite());
102: }
103:
104: public static Test suite() {
105: LOGGER.info("starting suite...");
106:
107: TestSuite suite = new TestSuite(MySQLDataStoreTest.class);
108: LOGGER.info("made suite...");
109:
110: return suite;
111: }
112:
113: protected void setUp() throws Exception {
114: super .setUp();
115:
116: PropertyResourceBundle resource;
117: resource = new PropertyResourceBundle(this .getClass()
118: .getResourceAsStream("fixture.properties"));
119:
120: String namespace = resource.getString("namespace");
121: String host = resource.getString("host");
122: int port = Integer.parseInt(resource.getString("port"));
123: String database = resource.getString("database");
124:
125: String user = resource.getString("user");
126: String password = resource.getString("passwd");
127:
128: if (namespace.equals("http://www.geotools.org/data/postgis")) {
129: throw new IllegalStateException(
130: "The fixture.properties file needs to be configured for your own database");
131: }
132:
133: connPool = MySQLDataStoreFactory.getDefaultDataSource(host,
134: user, password, port, database, 10, 2, false);
135: setupTestTable(connPool.getConnection());
136:
137: dstore = new MySQLDataStore(connPool, namespace);
138: dstore.setFIDMapper("testset", new TypedFIDMapper(
139: new BasicFIDMapper("gid", 255, true), "testset"));
140: dstore.setWKBEnabled(true);
141: schema = dstore.getSchema(FEATURE_TABLE);
142: }
143:
144: /**
145: * @param connection
146: */
147: private void setupTestTable(Connection conn) throws IOException,
148: SQLException {
149: // gid;int4;4;0;;YES;;
150: // area;float8;8;0;;YES;;
151: // perimeter;float8;8;0;;YES;;
152: // testb_;int4;4;0;;YES;;
153: // testb_id;int4;4;0;;YES;;
154: // name;varchar;0;0;;YES;;
155: // pcedflag;int4;4;0;;YES;;
156: // dbdflag;int4;4;0;;YES;;
157: // the_geom;geometry;-1;0;;YES;;
158:
159: Statement st = conn.createStatement();
160: try {
161: st.execute("DROP TABLE testset");
162: } catch (Exception e) {
163: }
164: st
165: .execute("CREATE TABLE testset ( gid integer, area double, perimeter double, testb_ integer, "
166: + " testb_id integer, name varchar(255), pcedflag integer, dbdflag integer, the_geom multipolygon)");
167: st.close();
168: PreparedStatement ps = conn
169: .prepareStatement("INSERT into testset values(?, ?, ?, ?, ?, ?, ?, ?, GeomFromText(?))");
170: BufferedReader reader = new BufferedReader(
171: new InputStreamReader(this .getClass()
172: .getResourceAsStream("testdata.txt")));
173:
174: try {
175:
176: String line = null;
177: while ((line = reader.readLine()) != null) {
178: String[] values = line.split(";");
179: ps.setInt(1, Integer.parseInt(values[0]));
180: ps.setDouble(2, Double.parseDouble(values[1]));
181: ps.setDouble(3, Double.parseDouble(values[2]));
182: ps.setInt(4, Integer.parseInt(values[3]));
183: ps.setInt(5, Integer.parseInt(values[4]));
184: ps.setString(6, values[5]);
185: ps.setInt(7, Integer.parseInt(values[6]));
186: ps.setInt(8, Integer.parseInt(values[7]));
187: ps.setString(9, values[8]);
188: ps.execute();
189: }
190: } finally {
191: reader.close();
192: ps.close();
193: }
194: }
195:
196: protected void tearDown() {
197: try {
198: dropTestTable(connPool.getConnection());
199: dstore.dispose();
200: } catch (SQLException e) {
201: } finally {
202: ConnectionPoolManager.getInstance().closeAll();
203: }
204: }
205:
206: public void dropTestTable(Connection conn) throws SQLException {
207: Statement st = conn.createStatement();
208: st.execute("DROP TABLE testset");
209: }
210:
211: //todo assert on schema.
212: public void testFeatureTypes() throws Exception {
213: String[] types = dstore.getTypeNames();
214: FeatureType schema1 = dstore.getSchema(types[0]);
215:
216: //FeatureType schema2 = dstore.getSchema(types[1]);
217: //need to figure out spatial_ref_system and geometry_columns
218: LOGGER.fine("first schemas are: \n" + schema1); // + "\n" + schema2);
219:
220: try {
221: String badSchema = "bad-schema23";
222: dstore.getSchema(badSchema);
223: fail("should not have schema " + badSchema);
224: } catch (SchemaNotFoundException e) {
225: LOGGER.fine("succesfully caught exception: " + e);
226:
227: //catch the proper exception
228: }
229: }
230:
231: //tests todo: bad retyping. post filters.
232: public void testGetReader() throws Exception {
233: String testTable = FEATURE_TABLE;
234: LOGGER.fine("testTable " + testTable + " has schema "
235: + dstore.getSchema(testTable));
236:
237: FeatureReader reader = dstore.getFeatureReader(schema,
238: Filter.INCLUDE, Transaction.AUTO_COMMIT);
239: int numFeatures = count(reader);
240: assertEquals("Number of features off:", 6, numFeatures);
241: }
242:
243: public void testFilter() throws Exception {
244: CompareFilter test1 = null;
245:
246: try {
247: test1 = filterFac
248: .createCompareFilter(AbstractFilter.COMPARE_EQUALS);
249:
250: Integer testInt = new Integer(0);
251: Expression testLiteral = filterFac
252: .createLiteralExpression(testInt);
253: test1.addLeftValue(testLiteral);
254: test1.addRightValue(filterFac.createAttributeExpression(
255: schema, "pcedflag"));
256: } catch (IllegalFilterException e) {
257: fail("Illegal Filter Exception " + e);
258: }
259:
260: Query query = new DefaultQuery(FEATURE_TABLE, test1);
261: FeatureReader reader = dstore.getFeatureReader(schema, test1,
262: Transaction.AUTO_COMMIT);
263: assertEquals("Number of filtered features off:", 2,
264: count(reader));
265: }
266:
267: public void testGeomFilter() throws Exception {
268: org.geotools.filter.GeometryFilter gf = filterFac
269: .createGeometryFilter(AbstractFilter.GEOMETRY_BBOX);
270: Envelope env = new Envelope(428500, 430000, 428500, 440000);
271: LiteralExpression right = filterFac.createBBoxExpression(env);
272: gf.addRightGeometry(right);
273: gf.addLeftGeometry(filterFac.createAttributeExpression(schema,
274: "the_geom"));
275:
276: FeatureReader reader = dstore.getFeatureReader(schema, gf,
277: Transaction.AUTO_COMMIT);
278: assertEquals("Number of geom filtered features off:", 2,
279: count(reader));
280: }
281:
282: int count(FeatureReader reader) throws NoSuchElementException,
283: IOException, IllegalAttributeException {
284: int count = 0;
285:
286: try {
287: while (reader.hasNext()) {
288: reader.next();
289: count++;
290: }
291: } finally {
292: reader.close();
293: }
294:
295: return count;
296: }
297:
298: int count(FeatureWriter writer) throws NoSuchElementException,
299: IOException, IllegalAttributeException {
300: int count = 0;
301:
302: try {
303: while (writer.hasNext()) {
304: writer.next();
305: count++;
306: }
307: } finally {
308: writer.close();
309: }
310:
311: return count;
312: }
313:
314: public void testGetFeatureWriter() throws Exception {
315: Transaction trans = new DefaultTransaction();
316: JDBCTransactionState state = new JDBCTransactionState(connPool);
317: trans.putState(connPool, state);
318:
319: FeatureWriter writer = dstore.getFeatureWriter("testset",
320: Filter.INCLUDE, trans);
321:
322: //count(writer);
323: assertEquals(6, count(writer));
324:
325: try {
326: assertFalse(writer.hasNext());
327: } catch (IOException expected) {
328: }
329:
330: //TODO: test that writer.next is an empty feature.
331: //try {
332: // writer.next();
333: // fail("Should not be able to use a closed writer");
334: //} catch (IOException expected) {
335: //}
336: }
337:
338: public void testBadTypeName() throws Exception {
339: try {
340: String badType = "badType43";
341: FeatureWriter writer = dstore.getFeatureWriter(badType,
342: Filter.INCLUDE, Transaction.AUTO_COMMIT);
343: fail("should not have type " + badType);
344: } catch (SchemaNotFoundException e) {
345: LOGGER.fine("succesfully caught exception: " + e);
346:
347: //catch the proper exception
348: }
349: }
350:
351: public void testOptimizedBounds() throws Exception {
352: FeatureSource source = dstore.getFeatureSource(FEATURE_TABLE);
353: CompareFilter test1 = null;
354:
355: try {
356: test1 = filterFac
357: .createCompareFilter(AbstractFilter.COMPARE_EQUALS);
358:
359: Integer testInt = new Integer(0);
360: Expression testLiteral = filterFac
361: .createLiteralExpression(testInt);
362: test1.addLeftValue(testLiteral);
363: test1.addRightValue(filterFac.createAttributeExpression(
364: schema, "pcedflag"));
365: } catch (IllegalFilterException e) {
366: fail("Illegal Filter Exception " + e);
367: }
368:
369: Query query = new DefaultQuery(FEATURE_TABLE, test1);
370: Envelope bounds = source.getBounds(query);
371: LOGGER.info("bounds on query " + query + " is " + bounds);
372:
373: Envelope fBounds = source.getBounds();
374: LOGGER.info("Bounds of source is " + fBounds);
375:
376: FeatureCollection results = source.getFeatures(query);
377: LOGGER.info("bounds from feature results is "
378: + results.getBounds());
379: }
380:
381: public void testGetFeaturesWriterModify() throws IOException,
382: IllegalAttributeException {
383: Transaction trans = new DefaultTransaction();
384: JDBCTransactionState state = new JDBCTransactionState(connPool);
385: trans.putState(connPool, state);
386:
387: FeatureWriter writer = dstore.getFeatureWriter(FEATURE_TABLE,
388: Filter.INCLUDE, trans);
389: int attKeyPos = 0;
390: Integer attKey = new Integer(10);
391: String attName = "name";
392: String newAttVal = "LS 503";
393: Feature feature;
394:
395: while (writer.hasNext()) {
396: feature = writer.next();
397:
398: if (feature.getAttribute(attKeyPos).equals(attKey)) {
399: LOGGER.info("changing name of feature " + feature);
400: ;
401: feature.setAttribute(attName, newAttVal);
402: writer.write();
403: }
404: }
405:
406: //writer.close();
407: FeatureReader reader = dstore.getFeatureReader(schema,
408: Filter.INCLUDE, trans);
409:
410: while (reader.hasNext()) {
411: feature = reader.next();
412:
413: if (feature.getAttribute(attKeyPos).equals(attKey)) {
414: LOGGER.fine("checking feature " + feature);
415: ;
416:
417: Object modAtt = feature.getAttribute(attName);
418:
419: //LOGGER.fine("modified attribute is " + modAtt);
420: assertEquals("attribute was not changed", newAttVal,
421: (String) modAtt);
422: }
423: }
424:
425: //feature = (Feature) data.features( "road" ).get( "road.rd1" );
426: //assertEquals( "changed", feature.getAttribute("name") );
427: state.rollback();
428: }
429:
430: public void testGetFeaturesWriterModifyGeometry()
431: throws IOException, IllegalAttributeException {
432: FeatureWriter writer = dstore.getFeatureWriter("road",
433: Filter.INCLUDE, Transaction.AUTO_COMMIT);
434: Feature feature;
435: Coordinate[] points = { new Coordinate(59, 59),
436: new Coordinate(17, 17), new Coordinate(49, 39),
437: new Coordinate(57, 67), new Coordinate(79, 79) };
438: LineString geom = geomFac.createLineString(points);
439:
440: while (writer.hasNext()) {
441: feature = writer.next();
442: LOGGER.info("looking at feature " + feature);
443:
444: if (feature.getAttribute(0).equals("asphalt")) {
445: LOGGER.info("changing name and geom");
446: feature.setAttribute("the_geom", geom);
447: writer.write();
448: }
449: }
450:
451: //feature = (Feature) data.features( "road" ).get( "road.rd1" );
452: //assertEquals( "changed", feature.getAttribute("name") );
453: writer.close();
454: }
455:
456: public void testGetFeaturesWriterModifyMultipleAtts()
457: throws IOException, IllegalAttributeException {
458: FeatureWriter writer = dstore.getFeatureWriter("road",
459: Filter.INCLUDE, Transaction.AUTO_COMMIT);
460: Feature feature;
461: Coordinate[] points = { new Coordinate(32, 44),
462: new Coordinate(62, 51), new Coordinate(45, 35),
463: new Coordinate(55, 65), new Coordinate(73, 75) };
464: LineString geom = geomFac.createLineString(points);
465:
466: while (writer.hasNext()) {
467: feature = writer.next();
468: LOGGER.info("looking at feature " + feature);
469:
470: if (feature.getAttribute(0).equals("asphalt")) {
471: LOGGER.info("changing name and geom");
472: feature.setAttribute("the_geom", geom);
473: feature.setAttribute("name", "trick");
474: writer.write();
475: }
476: }
477:
478: //feature = (Feature) data.features( "road" ).get( "road.rd1" );
479: //assertEquals( "changed", feature.getAttribute("name") );
480: writer.close();
481: }
482:
483: public void testGetFeaturesWriterAdd() throws IOException,
484: IllegalAttributeException {
485: Transaction trans = new DefaultTransaction();
486: JDBCTransactionState state = new JDBCTransactionState(connPool);
487: trans.putState(connPool, state);
488:
489: FeatureWriter writer = dstore.getFeatureWriter(FEATURE_TABLE,
490: Filter.INCLUDE, trans);
491: int count = 0;
492:
493: while (writer.hasNext()) {
494: Feature feature = writer.next();
495: count++;
496: }
497:
498: assertEquals("Checking num features before add", 6, count);
499: assertFalse(writer.hasNext());
500:
501: SimpleFeature feature = (SimpleFeature) writer.next();
502: Object[] atts = getTestAtts("testAdd");
503: feature.setAttributes(atts);
504: writer.write();
505: assertFalse(writer.hasNext());
506:
507: //assertEquals( fixture.roadFeatures.length+1, data.features( "road" ).size() );
508: writer.close();
509:
510: FeatureReader reader = dstore.getFeatureReader(schema,
511: Filter.INCLUDE, trans);
512: int numFeatures = count(reader);
513: assertEquals("Wrong number of features after add", 7,
514: numFeatures);
515: state.rollback();
516: }
517:
518: private Object[] getTestAtts(String name) {
519: Coordinate[] points = { new Coordinate(45, 45),
520: new Coordinate(45, 55), new Coordinate(55, 55),
521: new Coordinate(55, 45), new Coordinate(45, 45) };
522: PrecisionModel precModel = new PrecisionModel();
523: LinearRing shell = new LinearRing(points, precModel, srid);
524: Polygon[] testPolys = { new Polygon(shell, precModel, srid) };
525: MultiPolygon the_geom = new MultiPolygon(testPolys, precModel,
526: srid);
527: Integer gID = new Integer(addId);
528: Double area = new Double(100.0);
529: Double perimeter = new Double(40.0);
530: Integer testb_ = new Integer(22);
531: Integer testb_id = new Integer(4833);
532: Integer code = new Integer(0);
533:
534: Object[] attributes = { gID, area, perimeter, testb_, testb_id,
535: name, code, code, the_geom };
536:
537: return attributes;
538: }
539:
540: public void testGetFeatureWriterRemove() throws IOException,
541: IllegalAttributeException {
542: Transaction trans = new DefaultTransaction();
543: JDBCTransactionState state = new JDBCTransactionState(connPool);
544: trans.putState(connPool, state);
545:
546: FeatureWriter writer = dstore.getFeatureWriter(FEATURE_TABLE,
547: Filter.INCLUDE, trans);
548:
549: FeatureReader reader = dstore.getFeatureReader(schema,
550: Filter.INCLUDE, trans);
551: int numFeatures = count(reader);
552:
553: //assertEquals("Wrong number of features before delete", 6, numFeatures);
554: Feature feature;
555:
556: while (writer.hasNext()) {
557: feature = writer.next();
558:
559: if (feature.getAttribute(0).equals(new Integer(4))) {
560: LOGGER.info("deleting feature " + feature);
561: writer.remove();
562: }
563: }
564:
565: writer.close();
566: reader = dstore.getFeatureReader(schema, Filter.INCLUDE, trans);
567: numFeatures = count(reader);
568: assertEquals("Wrong number of features after add", 5,
569: numFeatures);
570: state.rollback();
571: }
572:
573: //assertEquals( fixture.roadFeatures.length-1, data.features( "road" ).size() );
574: }
|