DATACOUCH-165 - Add geospatial support
Add support for geo queries through the use of Spatial Views. This needs the query method to be annotated with @Dimensional (or a meta-annotation of it that is runtime retained). See SpatialViewQueryCreator javadoc for supported part types and corresponding expected arguments (to be documented). In a nutshell WITHIN Box (other shapes supported but approximated to bounding box), NEAR Point+Distance (approximated to bounding box), plus a few simple operators for dimensions beyond 2. When approximating, a DEBUG log is made along the logging of the query. Conversion methods from Shapes to bounding boxes are done in a GeoUtils class. Unit and Integration test of the feature. Added documentation for @Dimensional query derivation.
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.data.couchbase.repository;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.instanceOf;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.junit.Assert.*;
|
||||
@@ -26,6 +27,7 @@ import java.util.List;
|
||||
import com.couchbase.client.java.Bucket;
|
||||
import com.couchbase.client.java.view.Stale;
|
||||
import com.couchbase.client.java.view.ViewQuery;
|
||||
import com.couchbase.client.java.view.ViewResult;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
@@ -75,9 +77,13 @@ public class CouchbaseRepositoryViewTests {
|
||||
|
||||
@Test
|
||||
public void shouldCountWithCustomView() {
|
||||
client.query(ViewQuery.from("userCustom", "customCountView").stale(Stale.FALSE));
|
||||
ViewResult clientResult = client.query(ViewQuery.from("userCustom", "customCountView")
|
||||
.reduce().stale(Stale.FALSE));
|
||||
final Object clientRowValue = clientResult.allRows().get(0).value();
|
||||
final long value = repository.count();
|
||||
assertThat(value, is(100L));
|
||||
assertThat(clientRowValue, instanceOf(Number.class));
|
||||
assertThat(((Number) clientRowValue).longValue(), is(value));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
package org.springframework.data.couchbase.repository;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.List;
|
||||
|
||||
import com.couchbase.client.java.document.json.JsonArray;
|
||||
|
||||
import org.springframework.data.couchbase.core.view.Dimensional;
|
||||
import org.springframework.data.geo.Box;
|
||||
import org.springframework.data.geo.Circle;
|
||||
import org.springframework.data.geo.Distance;
|
||||
import org.springframework.data.geo.Point;
|
||||
import org.springframework.data.geo.Polygon;
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
|
||||
public interface DimensionalPartyRepository extends CrudRepository<Party, String> {
|
||||
|
||||
@Dimensional(designDocument = "partyGeo", spatialViewName = "byLocation")
|
||||
List<Party> findByLocationNear(Point p, Distance d);
|
||||
|
||||
@Dimensional(designDocument = "partyGeo", spatialViewName = "byLocation")
|
||||
List<Party> findByLocationWithin(Box boundingBox);
|
||||
|
||||
@Dimensional(designDocument = "partyGeo", spatialViewName = "byLocation")
|
||||
List<Party> findByLocationWithin(Polygon zone);
|
||||
|
||||
@Dimensional(designDocument = "partyGeo", spatialViewName = "byLocation")
|
||||
List<Party> findByLocationWithin(Point[] points);
|
||||
|
||||
@Dimensional(designDocument = "partyGeo", spatialViewName = "byLocation")
|
||||
List<Party> findByLocationWithin(Point point);
|
||||
|
||||
@Dimensional(designDocument = "partyGeo", spatialViewName = "byLocation")
|
||||
List<Party> findByLocationWithin(JsonArray range);
|
||||
|
||||
@Dimensional(designDocument = "partyGeo", spatialViewName = "byLocation")
|
||||
List<Party> findByLocationWithin(Point lowerLeft, Point upperRight);
|
||||
|
||||
@Dimensional(designDocument = "partyGeo", spatialViewName = "byLocationAndAttendees", dimensions = 3)
|
||||
List<Party> findByLocationWithin(Circle zone);
|
||||
|
||||
@Dimensional(designDocument = "partyGeo", spatialViewName = "byLocationAndAttendees", dimensions = 3)
|
||||
List<Party> findByLocationWithinAndAttendeesGreaterThan(Polygon zone, double minAttendees);
|
||||
|
||||
@Dimensional(designDocument = "partyGeo", spatialViewName = "byLocationAndAttendees", dimensions = 3)
|
||||
List<Party> findByLocationWithin(JsonArray startRange, JsonArray endRange);
|
||||
|
||||
//TODO more coverage of operators?
|
||||
|
||||
@IndexedByLocation
|
||||
List<Party> findByLocationIsWithin(Point a, Point b);
|
||||
|
||||
@Dimensional(designDocument = "partyGeo", spatialViewName = "byLocation", dimensions = 2)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@interface IndexedByLocation { }
|
||||
}
|
||||
@@ -0,0 +1,313 @@
|
||||
package org.springframework.data.couchbase.repository;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import com.couchbase.client.java.document.json.JsonArray;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.couchbase.IntegrationTestApplicationConfig;
|
||||
import org.springframework.data.couchbase.core.CouchbaseQueryExecutionException;
|
||||
import org.springframework.data.couchbase.core.CouchbaseTemplate;
|
||||
import org.springframework.data.couchbase.repository.support.CouchbaseRepositoryFactory;
|
||||
import org.springframework.data.geo.Box;
|
||||
import org.springframework.data.geo.Circle;
|
||||
import org.springframework.data.geo.Distance;
|
||||
import org.springframework.data.geo.Point;
|
||||
import org.springframework.data.geo.Polygon;
|
||||
import org.springframework.data.repository.core.support.RepositoryFactorySupport;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.TestExecutionListeners;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
* @author Simon Baslé
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(classes = IntegrationTestApplicationConfig.class)
|
||||
@TestExecutionListeners(PartyPopulatorListener.class)
|
||||
public class DimensionalQueryTests {
|
||||
|
||||
@Autowired
|
||||
private CouchbaseTemplate template;
|
||||
|
||||
private DimensionalPartyRepository repository;
|
||||
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
RepositoryFactorySupport factory = new CouchbaseRepositoryFactory(template);
|
||||
repository = factory.getRepository(DimensionalPartyRepository.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFindWithingPolygon() {
|
||||
Set<String> expectedKeys = new HashSet<String>();
|
||||
expectedKeys.add("testparty-2");
|
||||
expectedKeys.add("testparty-3");
|
||||
expectedKeys.add("testparty-4");
|
||||
expectedKeys.add("testparty-5");
|
||||
//a zone that engulfs parties 2, 3, 4 and 5, in the shape of a downward arrow pointing right
|
||||
Polygon zone = new Polygon(new Point(1, -2),
|
||||
new Point(3, -1.5),
|
||||
new Point(6, -4),
|
||||
new Point(5.5, -5.5),
|
||||
new Point(3, -5));
|
||||
|
||||
List<Party> parties = repository.findByLocationWithin(zone);
|
||||
|
||||
assertEquals(4, parties.size());
|
||||
for (Party party : parties) {
|
||||
assertTrue(expectedKeys.contains(party.getKey()));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testByLocationNear() {
|
||||
Set<String> expectedKeys = new HashSet<String>();
|
||||
expectedKeys.add("testparty-0");
|
||||
expectedKeys.add("testparty-1");
|
||||
|
||||
List<Party> parties = repository.findByLocationNear(new Point(0, 0), new Distance(1.5));
|
||||
assertEquals(2, parties.size());
|
||||
for (Party party : parties) {
|
||||
assertTrue(expectedKeys.contains(party.getKey()));
|
||||
}
|
||||
|
||||
parties = repository.findByLocationNear(new Point(0, 0), new Distance(2.5));
|
||||
expectedKeys.add("testparty-2");
|
||||
assertEquals(3, parties.size());
|
||||
for (Party party : parties) {
|
||||
assertTrue(expectedKeys.contains(party.getKey()));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testByLocationAndSparseAttendees() {
|
||||
Set<String> expectedKeys = new HashSet<String>();
|
||||
expectedKeys.add("testparty-4");
|
||||
expectedKeys.add("testparty-5");
|
||||
//a zone that engulfs parties 2, 3, 4 and 5 (with resp. 120, 130, 140 and 150 attendees)
|
||||
//in the shape of a downward arrow pointing right
|
||||
Polygon zone = new Polygon(new Point(1, -2),
|
||||
new Point(3, -1.5),
|
||||
new Point(6, -4),
|
||||
new Point(5.5, -5.5),
|
||||
new Point(3, -5));
|
||||
|
||||
//first check the zone contains 4 parties
|
||||
List<Party> allPartiesInZone = repository.findByLocationWithinAndAttendeesGreaterThan(zone, -1);
|
||||
List<Party> allPartiesInZoneWithoutAttendeeCriteria = repository.findByLocationWithin(zone);
|
||||
assertEquals(allPartiesInZone.toString(), 4, allPartiesInZone.size());
|
||||
assertEquals(allPartiesInZoneWithoutAttendeeCriteria, allPartiesInZone);
|
||||
|
||||
//check parties are limited by the attendees
|
||||
List<Party> parties = repository.findByLocationWithinAndAttendeesGreaterThan(zone, 140);
|
||||
for (Party party : parties) {
|
||||
System.out.println(party.getKey() + " : " + party.getLocation() + " " + party.getAttendees());
|
||||
}
|
||||
|
||||
assertEquals(parties.toString(), 2, parties.size());
|
||||
for (Party party : parties) {
|
||||
assertTrue(party.getAttendees() >= 140);
|
||||
assertTrue(expectedKeys.contains(party.getKey()));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testByLocationInCircle() {
|
||||
Circle zone1 = new Circle(new Point(-5,5), new Distance(5.5));
|
||||
Circle zone2 = new Circle(new Point(6, -6), new Distance(10));
|
||||
Circle zoneEmpty = new Circle(new Point(6,6), new Distance(3));
|
||||
|
||||
List<Party> parties = repository.findByLocationWithin(zone1);
|
||||
|
||||
assertEquals(1, parties.size());
|
||||
assertEquals("testparty-0", parties.get(0).getKey());
|
||||
|
||||
parties = repository.findByLocationWithin(zone2);
|
||||
|
||||
assertEquals(12, parties.size()); //all the parties except the special one at 100, 100
|
||||
|
||||
parties = repository.findByLocationWithin(zoneEmpty);
|
||||
assertEquals(0, parties.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testByLocationInBox() {
|
||||
Box zone1 = new Box(new Point(-10.5, -0.5), new Point(0.5, 10.5));
|
||||
Box zone2 = new Box(new Point(-4, -16), new Point(16, 4));
|
||||
Box zoneEmpty = new Box(new Point(3, 3), new Point(9, 9));
|
||||
|
||||
List<Party> parties = repository.findByLocationWithin(zone1);
|
||||
|
||||
assertEquals(1, parties.size());
|
||||
assertEquals("testparty-0", parties.get(0).getKey());
|
||||
|
||||
parties = repository.findByLocationWithin(zone2);
|
||||
|
||||
assertEquals(12, parties.size()); //all the parties except the special one at 100, 100
|
||||
|
||||
parties = repository.findByLocationWithin(zoneEmpty);
|
||||
assertEquals(0, parties.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testByLocationInPolygon() {
|
||||
//bounding box of (-10.5, -0.5),(0.5, 10.5)
|
||||
Polygon zone1 = new Polygon(
|
||||
new Point(-10.5, -0.5),
|
||||
new Point(-10.5, 10.5),
|
||||
new Point(0.5, 10.5),
|
||||
new Point(0.4, 1));
|
||||
//bounding box of (-4, -16),(16,4)
|
||||
Polygon zone2 = new Polygon(
|
||||
new Point(-4, -10),
|
||||
new Point(-3, 4),
|
||||
new Point(14, 2),
|
||||
new Point(16, -16));
|
||||
//bounding box of (3,3)(9,9)
|
||||
Polygon zoneEmpty = new Polygon(
|
||||
new Point(3, 3),
|
||||
new Point(3, 7),
|
||||
new Point(6, 7),
|
||||
new Point(6, 9),
|
||||
new Point(9, 9),
|
||||
new Point(9, 5),
|
||||
new Point(6, 5),
|
||||
new Point(6, 3));
|
||||
|
||||
List<Party> parties = repository.findByLocationWithin(zone1);
|
||||
|
||||
assertEquals(1, parties.size());
|
||||
assertEquals("testparty-0", parties.get(0).getKey());
|
||||
|
||||
parties = repository.findByLocationWithin(zone2);
|
||||
|
||||
assertEquals(12, parties.size()); //all the parties except the special one at 100, 100
|
||||
|
||||
parties = repository.findByLocationWithin(zoneEmpty);
|
||||
assertEquals(0, parties.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testByLocationWithinTwoPoints() {
|
||||
Point zone1LowerLeft = new Point(-10.5, -0.5);
|
||||
Point zone1UpperRight = new Point(0.5, 10.5);
|
||||
Point zone2LowerLeft = new Point(-4, -16);
|
||||
Point zone2UpperRight = new Point(16, 4);
|
||||
Point zoneEmptyLowerLeft = new Point(3, 3);
|
||||
Point zoneEmptyUpperRight = new Point(9, 9);
|
||||
|
||||
List<Party> parties = repository.findByLocationWithin(zone1LowerLeft, zone1UpperRight);
|
||||
|
||||
assertEquals(1, parties.size());
|
||||
assertEquals("testparty-0", parties.get(0).getKey());
|
||||
|
||||
parties = repository.findByLocationWithin(zone2LowerLeft, zone2UpperRight);
|
||||
|
||||
assertEquals(12, parties.size()); //all the parties except the special one at 100, 100
|
||||
|
||||
parties = repository.findByLocationWithin(zoneEmptyLowerLeft, zoneEmptyUpperRight);
|
||||
assertEquals(0, parties.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPolygonAndArrayOfPointsProduceSameResult() {
|
||||
Set<String> expectedKeys = new HashSet<String>();
|
||||
expectedKeys.add("testparty-2");
|
||||
expectedKeys.add("testparty-3");
|
||||
expectedKeys.add("testparty-4");
|
||||
expectedKeys.add("testparty-5");
|
||||
//a zone that engulfs parties 2, 3, 4 and 5, in the shape of a downward arrow pointing right
|
||||
Polygon zone = new Polygon(new Point(1, -2),
|
||||
new Point(3, -1.5),
|
||||
new Point(6, -4),
|
||||
new Point(5.5, -5.5),
|
||||
new Point(3, -5));
|
||||
Point[] points = zone.getPoints().toArray(new Point[5]);
|
||||
|
||||
List<Party> fromZone = repository.findByLocationWithin(zone);
|
||||
List<Party> fromPoints = repository.findByLocationWithin(points);
|
||||
|
||||
assertEquals(4, fromZone.size());
|
||||
assertEquals(fromZone, fromPoints);
|
||||
Set<String> keys = new HashSet<String>();
|
||||
for (Party party : fromZone) {
|
||||
keys.add(party.getKey());
|
||||
}
|
||||
assertEquals(expectedKeys, keys);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProvidingOnePointIsRejected() {
|
||||
try {
|
||||
repository.findByLocationWithin(new Point(0, 0));
|
||||
fail("Expected IllegalArgumentException");
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertEquals("Cannot compute a bounding box for within, 2 Point needed, missing parameter", e.getMessage());
|
||||
}
|
||||
|
||||
try {
|
||||
repository.findByLocationWithin(new Point(0, 0), null);
|
||||
fail("Expected IllegalArgumentException");
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertEquals("Cannot compute a bounding box for within, 2 Point needed, got null", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProvidingOneJsonArrayIsRejected() {
|
||||
try {
|
||||
List<Party> parties = repository.findByLocationWithin(JsonArray.from(0,0));
|
||||
fail();
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertEquals("2 JsonArray required for within: startRange and endRange, missing parameter", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = CouchbaseQueryExecutionException.class)
|
||||
public void testJsonArrayWithNonNumericalValueProducesServerSideError() {
|
||||
repository.findByLocationWithin(JsonArray.from("toto", -2), JsonArray.from(4, 1));
|
||||
fail();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithinJsonArrayRangesFiltersLocationAndAttendees() {
|
||||
List<Party> parties = repository.findByLocationWithin(JsonArray.from(0, -4, 115), JsonArray.from(4, 1, 132));
|
||||
assertEquals(2, parties.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDimensionalAnnotationCanBeUsedAsMeta() {
|
||||
try {
|
||||
//will trigger a specific message if parsed by SpatialViewQueryCreator
|
||||
repository.findByLocationIsWithin(new Point(0,0), null);
|
||||
fail("expected IllegalArgumentException from SpatialViewQueryCreator");
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertEquals("Cannot compute a bounding box for within, 2 Point needed, got null", e.getMessage());
|
||||
}
|
||||
|
||||
//when it is correctly formed, it actually returns data
|
||||
assertEquals(1, repository.findByLocationIsWithin(new Point(-10.5, -0.5), new Point(0.5, 10.5)).size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFindWithinBoxCornerOrderDoesMatter() {
|
||||
Point a = new Point(0, -4);
|
||||
Point b = new Point(6, -2);
|
||||
Box box1 = new Box(a, b);
|
||||
Box box2 = new Box(b, a);
|
||||
|
||||
final List<Party> parties1 = repository.findByLocationWithin(box1);
|
||||
final List<Party> parties2 = repository.findByLocationWithin(box2);
|
||||
|
||||
assertEquals(3, parties1.size());
|
||||
assertNotEquals(parties1, parties2);
|
||||
}
|
||||
}
|
||||
@@ -43,7 +43,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(classes = IntegrationTestApplicationConfig.class)
|
||||
@TestExecutionListeners(QueryDerivationConversionListener.class)
|
||||
@TestExecutionListeners(PartyPopulatorListener.class)
|
||||
public class N1qlCouchbaseRepositoryTests {
|
||||
|
||||
@Autowired
|
||||
|
||||
@@ -33,6 +33,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.couchbase.IntegrationTestApplicationConfig;
|
||||
import org.springframework.data.couchbase.repository.config.RepositoryOperationsMapping;
|
||||
import org.springframework.data.couchbase.repository.support.CouchbaseRepositoryFactory;
|
||||
import org.springframework.data.geo.Point;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
@@ -53,7 +54,7 @@ public class N1qlCrudRepositoryTests {
|
||||
private ItemRepository itemRepository;
|
||||
|
||||
private static final Item item = new Item("itemNotParty", "short description");
|
||||
private static final Party party = new Party("partyNotItem", "partyName", "short description", new Date(), 120);
|
||||
private static final Party party = new Party("partyNotItem", "partyName", "short description", new Date(), 120, new Point(500, 500));
|
||||
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
@@ -84,7 +85,7 @@ public class N1qlCrudRepositoryTests {
|
||||
|
||||
@Test
|
||||
public void shouldSaveObjectWithN1qlKeywordField() {
|
||||
Party party = new Party("partyHasKeyword", "party", "desc is a N1QL keyword", new Date(), 40);
|
||||
Party party = new Party("partyHasKeyword", "party", "desc is a N1QL keyword", new Date(), 40, new Point(500, 500));
|
||||
partyRepository.save(party);
|
||||
List<Object> parties = partyRepository.findAllByDescriptionNotNull();
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@ package org.springframework.data.couchbase.repository;
|
||||
import java.util.Date;
|
||||
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.geo.Point;
|
||||
|
||||
import com.couchbase.client.java.repository.annotation.Field;
|
||||
|
||||
/**
|
||||
@@ -24,12 +26,15 @@ public class Party {
|
||||
|
||||
private final long attendees;
|
||||
|
||||
public Party(String key, String name, String description, Date eventDate, long attendees) {
|
||||
private final Point location;
|
||||
|
||||
public Party(String key, String name, String description, Date eventDate, long attendees, Point location) {
|
||||
this.key = key;
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.eventDate = eventDate;
|
||||
this.attendees = attendees;
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
@@ -52,6 +57,10 @@ public class Party {
|
||||
return attendees;
|
||||
}
|
||||
|
||||
public Point getLocation() {
|
||||
return location;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.springframework.data.couchbase.repository;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@@ -10,16 +11,18 @@ import com.couchbase.client.java.ReplicateTo;
|
||||
import com.couchbase.client.java.cluster.ClusterInfo;
|
||||
import com.couchbase.client.java.view.DefaultView;
|
||||
import com.couchbase.client.java.view.DesignDocument;
|
||||
import com.couchbase.client.java.view.SpatialView;
|
||||
import com.couchbase.client.java.view.View;
|
||||
|
||||
import org.springframework.data.couchbase.core.CouchbaseTemplate;
|
||||
import org.springframework.data.geo.Point;
|
||||
import org.springframework.test.context.TestContext;
|
||||
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
|
||||
|
||||
/**
|
||||
* @author Simon Baslé
|
||||
*/
|
||||
public class QueryDerivationConversionListener extends DependencyInjectionTestExecutionListener {
|
||||
public class PartyPopulatorListener extends DependencyInjectionTestExecutionListener {
|
||||
|
||||
@Override
|
||||
public void beforeTestClass(final TestContext testContext) throws Exception {
|
||||
@@ -40,7 +43,8 @@ public class QueryDerivationConversionListener extends DependencyInjectionTestEx
|
||||
for (int i = 0; i < 12; i++) {
|
||||
Party p = new Party("testparty-" + i, "party like it's 199" + i,
|
||||
"An awesome party, 90's themed, every 10 of the month",
|
||||
cal.getTime(), 100 + i * 10);
|
||||
cal.getTime(), 100 + i * 10,
|
||||
new Point(i, -i));
|
||||
template.save(p, PersistTo.MASTER, ReplicateTo.NONE);
|
||||
cal.roll(Calendar.MONTH, true);
|
||||
}
|
||||
@@ -49,14 +53,32 @@ public class QueryDerivationConversionListener extends DependencyInjectionTestEx
|
||||
cal.set(Calendar.YEAR, 1990);
|
||||
cal.set(Calendar.MONTH, Calendar.JANUARY);
|
||||
cal.set(Calendar.DAY_OF_MONTH, 01);
|
||||
template.save(new Party("aTestParty", "New Year's Eve 90", "Happy New Year", cal.getTime(), 1230000));
|
||||
template.save(new Party("aTestParty", "New Year's Eve 90", "Happy New Year", cal.getTime(), 1230000, new Point(100, 100)));
|
||||
}
|
||||
|
||||
private void createAndWaitForDesignDocs(Bucket client) {
|
||||
String mapFunction = "function (doc, meta) { if(doc._class == \"" + Party.class.getName() + "\") { emit(doc.eventDate, null); } }";
|
||||
View view = DefaultView.create("byDate", mapFunction, "_count");
|
||||
List<View> views = Collections.singletonList(view);
|
||||
//standard views
|
||||
List<View> views = new ArrayList<View>();
|
||||
String mapFunction = "function (doc, meta) { if(doc._class == \"" + Party.class.getName() + "\") " +
|
||||
"{ emit(doc.eventDate, null); } }";
|
||||
views.add(DefaultView.create("byDate", mapFunction, "_count"));
|
||||
|
||||
//create the view design document
|
||||
DesignDocument designDoc = DesignDocument.create("party", views);
|
||||
client.bucketManager().upsertDesignDocument(designDoc);
|
||||
|
||||
//geo views
|
||||
List<View> geoViews = new ArrayList<View>();
|
||||
mapFunction = "function (doc, meta) { if(doc._class == \"" + Party.class.getName() + "\") " +
|
||||
"{ emit([doc.location.x, doc.location.y], null); } }";
|
||||
geoViews.add(SpatialView.create("byLocation", mapFunction));
|
||||
|
||||
mapFunction = "function (doc, meta) { if(doc._class == \"" + Party.class.getName() + "\") " +
|
||||
"{ emit([doc.location.x, doc.location.y, doc.attendees], null); } }";
|
||||
geoViews.add(SpatialView.create("byLocationAndAttendees", mapFunction));
|
||||
|
||||
//create the geo views design document
|
||||
DesignDocument geoDesignDoc = DesignDocument.create("partyGeo", geoViews);
|
||||
client.bucketManager().upsertDesignDocument(geoDesignDoc);
|
||||
}
|
||||
}
|
||||
@@ -27,7 +27,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(classes = IntegrationTestApplicationConfig.class)
|
||||
@TestExecutionListeners(QueryDerivationConversionListener.class)
|
||||
@TestExecutionListeners(PartyPopulatorListener.class)
|
||||
public class QueryDerivationConversionTests {
|
||||
|
||||
@Autowired
|
||||
|
||||
Reference in New Issue
Block a user