allow adhoc unmarshalling for individual n1ql results

This commit is contained in:
Simon Baslé
2015-06-29 19:54:08 +02:00
parent f1c0157fee
commit 81d13ff6f7
5 changed files with 110 additions and 17 deletions

View File

@@ -17,12 +17,15 @@
package org.springframework.data.couchbase.core;
import static com.couchbase.client.java.query.Select.select;
import static com.couchbase.client.java.query.dsl.Expression.i;
import static com.couchbase.client.java.query.dsl.Expression.s;
import static com.couchbase.client.java.query.dsl.Expression.x;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.IsEqual.equalTo;
import static org.junit.Assert.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
@@ -41,7 +44,6 @@ import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Test;
import org.junit.runner.RunWith;
import sun.reflect.generics.reflectiveObjects.NotImplementedException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.OptimisticLockingFailureException;
@@ -219,7 +221,7 @@ public class CouchbaseTemplateTests {
@Test
public void shouldQueryRaw() {
Query query = Query.simple(select("name").from(Expression.i(client.name()))
Query query = Query.simple(select("name").from(i(client.name()))
.where(x("name").isNotMissing()));
QueryResult queryResult = template.queryN1QL(query);
@@ -228,15 +230,22 @@ public class CouchbaseTemplateTests {
assertFalse(queryResult.allRows().isEmpty());
}
@Test(expected = NotImplementedException.class) //TODO remove when implemented
@Test
public void shouldQueryWithMapping() {
Query query = Query.simple(select("name").from(Expression.i(client.name()))
.where(x("name").isNotMissing()));
FullFragment ff1 = new FullFragment("fullFragment1", 1, "fullFragment", "test1");
FullFragment ff2 = new FullFragment("fullFragment2", 2, "fullFragment", "test2");
template.save(Arrays.asList(ff1, ff2));
List<BeerFragment> fragments = template.findByN1QL(query, BeerFragment.class);
Query query = Query.simple(select(i("value")) //"value" is a n1ql keyword apparently
.from(i(client.name()))
.where(x("type").eq(s("fullFragment"))
.and(x("criteria").gt(1))));
List<Fragment> fragments = template.findByN1QL(query, Fragment.class);
assertNotNull(fragments);
assertFalse(fragments.isEmpty());
//TODO assert the content of the fragments, etc...
assertEquals(1, fragments.size());
assertEquals("test2", fragments.get(0).value);
}
@Test
@@ -580,15 +589,55 @@ public class CouchbaseTemplateTests {
}
}
static class BeerFragment {
private String name;
@Document
static class FullFragment {
public String getName() {
return name;
@Id
private String id;
private long criteria;
private String type;
private String value;
public FullFragment(String id, long criteria, String type, String value) {
this.id = id;
this.criteria = criteria;
this.type = type;
this.value = value;
}
public void setName(String name) {
this.name = name;
public String getId() {
return id;
}
public long getCriteria() {
return criteria;
}
public String getType() {
return type;
}
public String getValue() {
return value;
}
public void setCriteria(long criteria) {
this.criteria = criteria;
}
public void setType(String type) {
this.type = type;
}
public void setValue(String value) {
this.value = value;
}
}
static class Fragment {
public String value;
}
}

View File

@@ -34,12 +34,12 @@ import com.couchbase.client.java.document.RawJsonDocument;
import com.couchbase.client.java.error.CASMismatchException;
import com.couchbase.client.java.query.Query;
import com.couchbase.client.java.query.QueryResult;
import com.couchbase.client.java.query.QueryRow;
import com.couchbase.client.java.view.ViewQuery;
import com.couchbase.client.java.view.ViewResult;
import com.couchbase.client.java.view.ViewRow;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sun.reflect.generics.reflectiveObjects.NotImplementedException;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
@@ -286,9 +286,17 @@ public class CouchbaseTemplate implements CouchbaseOperations, ApplicationEventP
@Override
public <T> List<T> findByN1QL(Query n1ql, Class<T> entityClass) {
//TODO find a way of mapping content to T
QueryResult queryResult = queryN1QL(n1ql);
List<QueryRow> allRows = queryResult.allRows();
List<T> result = new ArrayList<T>(allRows.size());
for (QueryRow row : allRows) {
String json = row.value().toString();
T decoded = translationService.decodeFragment(json, entityClass);
result.add(decoded);
}
//TODO error handling
throw new NotImplementedException();
return result;
}
@Override

View File

@@ -236,7 +236,17 @@ public class JacksonTranslationService implements TranslationService, Initializi
case VALUE_NULL:
return null;
default:
throw new MappingException("Could not decode primitve value " + token);
throw new MappingException("Could not decode primitive value " + token);
}
}
@Override
public <T> T decodeFragment(String source, Class<T> target) {
try {
return objectMapper.readValue(source, target);
}
catch (IOException e) {
throw new RuntimeException("Cannot decode ad-hoc JSON", e);
}
}

View File

@@ -16,6 +16,8 @@
package org.springframework.data.couchbase.core.convert.translation;
import com.couchbase.client.java.query.QueryRow;
import org.springframework.data.couchbase.core.mapping.CouchbaseDocument;
import org.springframework.data.couchbase.core.mapping.CouchbaseStorable;
@@ -42,4 +44,14 @@ public interface TranslationService {
* @return a properly populated document to work with.
*/
CouchbaseStorable decode(String source, CouchbaseStorable target);
/**
* Decodes an ad-hoc JSON object into a corresponding "case" class.
*
* @param source the JSON for the ad-hoc JSON object (from a N1QL {@link QueryRow} for instance).
* @param target the target class information.
* @param <T> the target class.
* @return an ad-hoc instance of the decoded JSON into the corresponding "case" class.
*/
<T> T decodeFragment(String source, Class<T> target);
}

View File

@@ -17,6 +17,7 @@
package org.springframework.data.couchbase.core.convert.translation;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import org.junit.Before;
import org.junit.Test;
@@ -35,6 +36,7 @@ public class JacksonTranslationServiceTests {
@Before
public void setup() {
service = new JacksonTranslationService();
((JacksonTranslationService) service).afterPropertiesSet();
}
@Test
@@ -52,4 +54,16 @@ public class JacksonTranslationServiceTests {
service.decode(source, target);
assertEquals("русский", target.get("language"));
}
@Test
public void shouldDecodeAdHocFragment() {
String source = "{\"language\":\"french\"}";
LanguageFragment f = service.decodeFragment(source, LanguageFragment.class);
assertNotNull(f);
assertEquals("french", f.language);
}
private static class LanguageFragment {
public String language;
}
}