DATACASS-297 - Polish.

Original pull request: #65.
This commit is contained in:
John Blum
2016-06-14 15:52:43 -07:00
parent 1b4eec9dd4
commit 97be7d6fc3
6 changed files with 126 additions and 99 deletions

View File

@@ -99,6 +99,7 @@ import com.datastax.driver.core.querybuilder.Update;
public class CqlTemplate extends CassandraAccessor implements CqlOperations {
protected static final Executor RUN_RUNNABLE_EXECUTOR = new Executor() {
@Override
@SuppressWarnings("all")
public void execute(Runnable command) {
@@ -856,48 +857,50 @@ public class CqlTemplate extends CassandraAccessor implements CqlOperations {
/**
* Attempts to translate the {@link Exception} into a Spring Data {@link Exception}.
* @param ex the Exception
* @return the translated {@link RuntimeException}
*
* @param e the {@link Exception} to translate.
* @return the translated {@link RuntimeException}.
* @see <a href="http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#dao-exceptions">Consistent exception hierarchy</a>
*/
@SuppressWarnings("all")
protected RuntimeException translateExceptionIfPossible(Exception ex) {
return translateExceptionIfPossible(ex, getExceptionTranslator());
protected RuntimeException translateExceptionIfPossible(Exception e) {
return translateExceptionIfPossible(e, getExceptionTranslator());
}
/**
* Tries to convert the given {@link RuntimeException} into a {@link DataAccessException} but returns the original
* exception if the conversation failed. Thus allows safe re-throwing of the return value.
*
* @param ex the exception to translate
* @param e the exception to translate
* @param exceptionTranslator the {@link PersistenceExceptionTranslator} to be used for translation
* @return
*/
@SuppressWarnings("all")
protected static RuntimeException translateExceptionIfPossible(Exception ex, PersistenceExceptionTranslator exceptionTranslator) {
Assert.notNull(ex, "Exception must not be null");
Assert.notNull(exceptionTranslator, "PersistenceExceptionTranslator must not be null");
if (ex instanceof RuntimeException) {
return potentiallyConvertRuntimeException((RuntimeException) ex, exceptionTranslator);
}
return new CassandraUncategorizedDataAccessException("Caught Uncategorized Exception", ex);
}
/**
* Tries to convert the given {@link RuntimeException} into a {@link DataAccessException} but returns the original
* exception if the conversation failed. Thus allows safe re-throwing of the return value.
*
* @param ex the exception to translate
* @param exceptionTranslator the {@link PersistenceExceptionTranslator} to be used for translation
* @return
*/
private static RuntimeException potentiallyConvertRuntimeException(RuntimeException ex,
protected static RuntimeException translateExceptionIfPossible(Exception e,
PersistenceExceptionTranslator exceptionTranslator) {
RuntimeException resolved = exceptionTranslator.translateExceptionIfPossible(ex);
return resolved == null ? ex : resolved;
Assert.notNull(e, "Exception must not be null");
Assert.notNull(exceptionTranslator, "PersistenceExceptionTranslator must not be null");
return (e instanceof RuntimeException) ? potentiallyConvertRuntimeException((RuntimeException) e, exceptionTranslator)
: new CassandraUncategorizedDataAccessException("Caught Uncategorized Exception", e);
}
/**
* Tries to convert the given {@link RuntimeException} into a {@link DataAccessException} but returns the original
* exception if the conversation failed. Thus allows safe re-throwing of the return value.
*
* @param e the exception to translate
* @param exceptionTranslator the {@link PersistenceExceptionTranslator} to be used for translation
* @return
*/
@SuppressWarnings("all")
private static RuntimeException potentiallyConvertRuntimeException(RuntimeException e,
PersistenceExceptionTranslator exceptionTranslator) {
RuntimeException resolved = exceptionTranslator.translateExceptionIfPossible(e);
return (resolved != null ? resolved : e);
}
@Override

View File

@@ -56,12 +56,12 @@ public interface CassandraOperations extends CqlOperations {
* Executes the given select {@code query} on the entity table of the specified {@code type} backed by a Cassandra
* {@link com.datastax.driver.core.ResultSet}.
* <p>
* Returns a {@link java.util.Iterator} that wraps the a Cassandra {@link com.datastax.driver.core.ResultSet}.
*
* @param <T> element return type
* @param query must not be empty and not {@literal null}.
* @param type must not be {@literal null}.
* @return
* Returns a {@link java.util.Iterator} that wraps the Cassandra {@link com.datastax.driver.core.ResultSet}.
*
* @param <T> element return type.
* @param query query to execute. Must not be empty or {@literal null}.
* @param type Class type of the elements in the {@link Iterator} stream. Must not be {@literal null}.
* @return an {@link Iterator} (stream) over the elements in the query result set.
* @since 1.5
*/
<T> Iterator<T> stream(String query, Class<T> type);

View File

@@ -602,15 +602,22 @@ public class CassandraTemplate extends CqlTemplate implements CassandraOperation
@Override
public ResultSet doInSession(Session s) throws DataAccessException {
return s.execute(query);
return s.execute(logCql(query));
}
});
if (resultSet == null) {
return Collections.<T>emptyList().iterator();
}
return (resultSet != null ? toIterator(resultSet, type) : Collections.<T>emptyIterator());
}
return new ResultSetIteratorAdapter(resultSet.iterator(), getExceptionTranslator(), new CassandraConverterRowCallback<T>(cassandraConverter, type));
/*
* (non-Javadoc)
* @see org.springframework.data.cassandra.core.CassandraTemplate.ResultSetIteratorAdapter
*/
@SuppressWarnings("unchecked")
private <T> Iterator<T> toIterator(ResultSet resultSet, Class<T> type) {
return new ResultSetIteratorAdapter(resultSet.iterator(), getExceptionTranslator(),
new CassandraConverterRowCallback<T>(cassandraConverter, type));
}
protected <T> List<T> select(final Select query, CassandraConverterRowCallback<T> readRowCallback) {
@@ -1109,7 +1116,7 @@ public class CassandraTemplate extends CqlTemplate implements CassandraOperation
throw new IllegalArgumentException(
String.format("Expected type String or Select; got type [%s] with value [%s]", query.getClass(), query));
}
private static class ResultSetIteratorAdapter<T> implements Iterator<T>{
private final Iterator<Row> iterator;
@@ -1117,7 +1124,7 @@ public class CassandraTemplate extends CqlTemplate implements CassandraOperation
private final CassandraConverterRowCallback<T> rowCallback;
public ResultSetIteratorAdapter(Iterator<Row> iterator, PersistenceExceptionTranslator exceptionTranslator, CassandraConverterRowCallback<T> rowCallback) {
this.iterator = iterator;
this.exceptionTranslator = exceptionTranslator;
this.rowCallback = rowCallback;
@@ -1125,7 +1132,7 @@ public class CassandraTemplate extends CqlTemplate implements CassandraOperation
@Override
public boolean hasNext() {
try {
return iterator.hasNext();
} catch (Exception e) {
@@ -1135,7 +1142,7 @@ public class CassandraTemplate extends CqlTemplate implements CassandraOperation
@Override
public T next() {
try {
return rowCallback.doWith(iterator.next());
} catch (Exception e) {

View File

@@ -104,14 +104,15 @@ public abstract class AbstractCassandraQuery implements RepositoryQuery {
return new ResultProcessingExecution(getExecutionToWrap(accessor, resultProcessing), resultProcessing);
}
private CassandraQueryExecution getExecutionToWrap(CassandraParameterAccessor accessor, Converter<Object, Object> resultProcessing) {
private CassandraQueryExecution getExecutionToWrap(CassandraParameterAccessor accessor,
Converter<Object, Object> resultProcessing) {
if (method.isResultSetQuery()) {
if (method.isCollectionQuery()) {
return new CollectionExecution(template);
} else if (method.isResultSetQuery()) {
return new ResultSetQuery(template);
} else if (method.isStreamQuery()) {
return new StreamExecution(template, resultProcessing);
} else if (method.isCollectionQuery()) {
return new CollectionExecution(template);
} else {
return new SingleEntityExecution(template);
}

View File

@@ -24,7 +24,6 @@ import java.util.Iterator;
import java.util.List;
import java.util.UUID;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -184,14 +183,16 @@ public class CassandraOperationsIntegrationTests extends AbstractSpringDataEmbed
@Test
public void insertEmptyList() {
List<Book> list = template.insert(new ArrayList<Book>());
assertNotNull(list);
assertEquals(0, list.size());
assertThat(list, is(notNullValue(List.class)));
assertThat(list.isEmpty(), is(true));
}
@Test
public void insertNullList() {
List<Book> list = template.insert((List<Book>) null);
assertNull(list);
assertThat(list, is(nullValue(List.class)));
}
@Test
@@ -253,21 +254,21 @@ public class CassandraOperationsIntegrationTests extends AbstractSpringDataEmbed
/**
* @return
*/
private List<Book> getBookList(int numBooks) {
private List<Book> getBookList(long numBooks) {
List<Book> books = new ArrayList<Book>();
Book book;
Book b = null;
for (int i = 0; i < numBooks; i++) {
b = new Book();
b.setIsbn(UUID.randomUUID().toString());
b.setTitle("Spring Data Cassandra Guide");
b.setAuthor("Cassandra Guru");
b.setPages(i * 10 + 5);
b.setInStock(true);
b.setSaleDate(new Date());
b.setCondition(BookCondition.NEW);
books.add(b);
for (int index = 0; index < numBooks; index++) {
book = new Book();
book.setIsbn(UUID.randomUUID().toString());
book.setTitle("Spring Data Cassandra Guide");
book.setAuthor("Cassandra Guru");
book.setPages(index * 10 + 5);
book.setInStock(true);
book.setSaleDate(new Date());
book.setCondition(BookCondition.NEW);
books.add(book);
}
return books;
@@ -648,13 +649,13 @@ public class CassandraOperationsIntegrationTests extends AbstractSpringDataEmbed
Select select = QueryBuilder.select().all().from("book");
select.where(QueryBuilder.eq("isbn", "123456-1"));
Book b = template.selectOne(select, Book.class);
Book book = template.selectOne(select, Book.class);
log.debug("SingleSelect Book Title -> " + b.getTitle());
log.debug("SingleSelect Book Author -> " + b.getAuthor());
log.debug("SingleSelect Book Title -> " + book.getTitle());
log.debug("SingleSelect Book Author -> " + book.getAuthor());
assertEquals(b.getTitle(), "Spring Data Cassandra Guide");
assertEquals(b.getAuthor(), "Cassandra Guru");
assertThat(book.getTitle(), is(equalTo("Spring Data Cassandra Guide")));
assertThat(book.getAuthor(), is(equalTo("Cassandra Guru")));
}
@@ -667,39 +668,39 @@ public class CassandraOperationsIntegrationTests extends AbstractSpringDataEmbed
Select select = QueryBuilder.select().all().from("book");
List<Book> bookz = template.select(select, Book.class);
List<Book> selectedBooks = template.select(select, Book.class);
log.debug("Book Count -> " + bookz.size());
log.debug("Book Count -> " + selectedBooks.size());
assertEquals(bookz.size(), 20);
assertThat(selectedBooks.size(), is(equalTo(20)));
for (Book b : bookz) {
Assert.assertTrue(b.isInStock());
assertEquals(BookCondition.NEW, b.getCondition());
for (Book book : selectedBooks) {
assertThat(book.isInStock(), is(true));
assertThat(book.getCondition(), is(equalTo(BookCondition.NEW)));
}
}
@Test
public void selectCountTest() {
int count = 20;
long count = 20;
List<Book> books = getBookList(count);
template.insert(books);
assertEquals(count, template.count(Book.class));
assertThat(template.count(Book.class), is(equalTo(count)));
}
@Test
public void insertAndSelect() {
int count = 20;
long count = 20;
List<Book> books = getBookList(count);
template.insert(books);
assertEquals(count, template.count(Book.class));
assertThat(template.count(Book.class), is(equalTo(count)));
}
/**
@@ -708,16 +709,27 @@ public class CassandraOperationsIntegrationTests extends AbstractSpringDataEmbed
@Test
public void stream() {
List<Book> books = getBookList(20);
template.insert(books);
template.insert(getBookList(20));
Iterator<Book> iterator = template.stream("select * from book", Book.class);
List<Book> result = new ArrayList<Book>();
while (iterator.hasNext()) {
result.add(iterator.next());
Iterator<Book> iterator = template.stream("SELECT * FROM book", Book.class);
assertThat(iterator, is(notNullValue(Iterator.class)));
List<Book> selectedBooks = new ArrayList<Book>();
for (Book book : toIterable(iterator)) {
selectedBooks.add(book);
}
assertThat(books.size(), is(20));
assertThat(books.get(0), is(instanceOf(Book.class)));
assertThat(selectedBooks.size(), is(equalTo(20)));
assertThat(selectedBooks.get(0), is(instanceOf(Book.class)));
}
<T> Iterable<T> toIterable(final Iterator<T> iterator) {
return new Iterable<T>() {
@Override public Iterator<T> iterator() {
return iterator;
}
};
}
}

View File

@@ -278,17 +278,20 @@ public abstract class QueryIntegrationTests extends AbstractSpringDataEmbeddedCa
@Test
public void findOptionalShouldReturnTargetType() {
Person saved = new Person();
saved.setFirstname(uuid());
saved.setLastname(uuid());
saved.setNumberOfChildren(1);
Person personToSave = new Person();
saved = personRepository.save(saved);
personToSave.setFirstname(uuid());
personToSave.setLastname(uuid());
personToSave.setNumberOfChildren(1);
Optional<Person> optional = personRepository.findOptionalWithLastnameAndFirstname(saved.getLastname(), saved.getFirstname());
personToSave = personRepository.save(personToSave);
assertTrue(optional.isPresent());
assertTrue(optional.get() instanceof Person);
Optional<Person> savedPerson = personRepository.findOptionalWithLastnameAndFirstname(
personToSave.getLastname(), personToSave.getFirstname());
assertThat(savedPerson, is(notNullValue(Optional.class)));
assertThat(savedPerson.isPresent(), is(true));
assertThat(savedPerson.get(), is(notNullValue(Person.class)));
}
@Test
@@ -296,26 +299,27 @@ public abstract class QueryIntegrationTests extends AbstractSpringDataEmbeddedCa
Optional<Person> optional = personRepository.findOptionalWithLastnameAndFirstname("not", "existent");
assertFalse(optional.isPresent());
assertThat(optional.isPresent(), is(false));
}
/**
* @see DATACASS-297
* @see <a href="DATACASS-297">https://jira.spring.io/browse/DATACASS-297</a>
*/
@Test
public void streamShouldReturnEntities() {
for (int i = 0; i < 100; i++) {
Person person = new Person();
person.setFirstname(uuid());
person.setLastname(uuid());
person.setNumberOfChildren(i);
personRepository.save(person);
}
Stream<Person> allPeople = personRepository.findAllPeople();
long count = allPeople.peek(new Consumer<Person>() {
@Override
public void accept(Person person) {
@@ -323,6 +327,6 @@ public abstract class QueryIntegrationTests extends AbstractSpringDataEmbeddedCa
}
}).count();
assertThat(count, is(100L));
assertThat(count, is(equalTo(100L)));
}
}