From 394af96b99c80be0d07d8ec534dc53cdc5e30c32 Mon Sep 17 00:00:00 2001 From: David T Webb Date: Mon, 17 Feb 2014 23:03:01 -0500 Subject: [PATCH] DATACASS-92 - COMPLETED Added RowValueProvider support for Collections Added Integration Test to prove support for CQL Create Table, Insert and Select Support for Collections. --- .../DefaultCassandraRowValueProvider.java | 25 ++- .../CollectionsRowValueProviderTest.java | 166 +++++++++++++++++ .../integration/simpletons/BookHistory.java | 153 ++++++++++++++++ .../integration/simpletons/BookReference.java | 170 ++++++++++++++++++ 4 files changed, 512 insertions(+), 2 deletions(-) create mode 100644 spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/collections/CollectionsRowValueProviderTest.java create mode 100644 spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/simpletons/BookHistory.java create mode 100644 spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/simpletons/BookReference.java diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/DefaultCassandraRowValueProvider.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/DefaultCassandraRowValueProvider.java index 886ef2a6c..342bc8193 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/DefaultCassandraRowValueProvider.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/DefaultCassandraRowValueProvider.java @@ -15,6 +15,8 @@ */ package org.springframework.data.cassandra.convert; +import java.util.List; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.data.cassandra.mapping.CassandraPersistentProperty; @@ -68,11 +70,30 @@ public class DefaultCassandraRowValueProvider implements CassandraRowValueProvid if (source.isNull(property.getColumnName())) { return null; } + DataType columnType = source.getColumnDefinitions().getType(columnName); - log.debug(columnType.getName().name()); + /* + * Handle the types of collections that are available + */ + if (columnType.isCollection()) { - // TODO DW Set, Map, List + List collectionTypes = columnType.getTypeArguments(); + if (collectionTypes.size() == 2) { + return (T) source + .getMap(columnName, collectionTypes.get(0).asJavaClass(), collectionTypes.get(1).asJavaClass()); + } + + if (columnType.equals(DataType.list(collectionTypes.get(0)))) { + return (T) source.getList(columnName, collectionTypes.get(0).asJavaClass()); + } + + if (columnType.equals(DataType.set(collectionTypes.get(0)))) { + return (T) source.getSet(columnName, collectionTypes.get(0).asJavaClass()); + } + + throw new IllegalStateException("Unknown Collection type encountered. Valid collections are Set, List and Map."); + } if (columnType.equals(DataType.text()) || columnType.equals(DataType.ascii()) || columnType.equals(DataType.varchar())) { diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/collections/CollectionsRowValueProviderTest.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/collections/CollectionsRowValueProviderTest.java new file mode 100644 index 000000000..30f3677a4 --- /dev/null +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/collections/CollectionsRowValueProviderTest.java @@ -0,0 +1,166 @@ +/* + * Copyright 2013-2014 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.cassandra.test.integration.collections; + +import static org.springframework.cassandra.core.keyspace.CreateKeyspaceSpecification.createKeyspace; + +import java.io.IOException; +import java.util.Arrays; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.cassandra.core.keyspace.CreateKeyspaceSpecification; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.cassandra.config.SchemaAction; +import org.springframework.data.cassandra.test.integration.simpletons.BookHistory; +import org.springframework.data.cassandra.test.integration.simpletons.BookReference; +import org.springframework.data.cassandra.test.integration.support.AbstractSpringDataEmbeddedCassandraIntegrationTest; +import org.springframework.data.cassandra.test.integration.support.TestConfig; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.datastax.driver.core.querybuilder.QueryBuilder; +import com.datastax.driver.core.querybuilder.Select; + +/** + * Tests the mapping of the collections types in Cassandra + * + * @author dwebb + * + */ +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration +public class CollectionsRowValueProviderTest extends AbstractSpringDataEmbeddedCassandraIntegrationTest { + + @Configuration + public static class Config extends TestConfig { + + @Override + public SchemaAction getSchemaAction() { + return SchemaAction.RECREATE; + } + + @Override + protected List getKeyspaceCreations() { + return Arrays.asList(createKeyspace().name(getKeyspaceName()).withSimpleReplication()); + } + + @Override + public String[] getEntityBasePackages() { + return new String[] { BookHistory.class.getPackage().getName() }; + } + } + + @Before + public void before() throws IOException { + recreateAllTables(); + } + + @Test + public void mapTest() { + + BookHistory b1 = new BookHistory(); + b1.setIsbn("123456-1"); + b1.setTitle("Spring Data Cassandra Guide"); + b1.setAuthor("Cassandra Guru"); + b1.setPages(521); + b1.setSaleDate(new Date()); + b1.setInStock(true); + + Map checkOutMap = new HashMap(); + checkOutMap.put("dwebb", 50); + checkOutMap.put("madams", 100); + checkOutMap.put("jmcpeek", 150); + + b1.setCheckOuts(checkOutMap); + + template.insert(b1); + + Select select = QueryBuilder.select().all().from("bookHistory"); + select.where(QueryBuilder.eq("isbn", "123456-1")); + + BookHistory b = template.selectOne(select.getQueryString(), BookHistory.class); + + Assert.assertNotNull(b.getCheckOuts()); + + log.info("Checkouts map data"); + for (String username : b.getCheckOuts().keySet()) { + log.info(username + " has " + b.getCheckOuts().get(username) + " checkouts of this book."); + } + + Assert.assertEquals(b.getTitle(), "Spring Data Cassandra Guide"); + Assert.assertEquals(b.getAuthor(), "Cassandra Guru"); + + } + + @Test + public void listSetTest() { + + BookReference b1 = new BookReference(); + b1.setIsbn("123456-1"); + b1.setTitle("Spring Data Cassandra Guide"); + b1.setAuthor("Cassandra Guru"); + b1.setPages(521); + b1.setSaleDate(new Date()); + b1.setInStock(true); + + Set refs = new HashSet(); + refs.add("Spring Data by O'Reilly"); + refs.add("Spring by Example"); + refs.add("Spring Recipies"); + b1.setReferences(refs); + + List marks = new LinkedList(); + marks.add(13); + marks.add(52); + marks.add(144); + b1.setBookmarks(marks); + + template.insert(b1); + + Select select = QueryBuilder.select().all().from("bookReference"); + select.where(QueryBuilder.eq("isbn", "123456-1")); + + BookReference b = template.selectOne(select.getQueryString(), BookReference.class); + + Assert.assertNotNull(b.getReferences()); + Assert.assertNotNull(b.getBookmarks()); + + log.info("Bookmark List Data"); + for (Integer mark : b.getBookmarks()) { + log.info("Bookmark set on page + " + mark); + } + + log.info("Reference Set Data"); + for (String ref : b.getReferences()) { + log.info("Reference -> " + ref); + } + + Assert.assertEquals(b.getTitle(), "Spring Data Cassandra Guide"); + Assert.assertEquals(b.getAuthor(), "Cassandra Guru"); + + } + +} diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/simpletons/BookHistory.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/simpletons/BookHistory.java new file mode 100644 index 000000000..7e5aa959e --- /dev/null +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/simpletons/BookHistory.java @@ -0,0 +1,153 @@ +/* + * Copyright 2013-2014 the original author or authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.cassandra.test.integration.simpletons; + +import java.util.Date; +import java.util.Map; + +import org.springframework.data.cassandra.mapping.PrimaryKey; +import org.springframework.data.cassandra.mapping.Table; + +/** + * Test POJO + * + * @author David Webb + * + */ +@Table("bookHistory") +public class BookHistory { + + @PrimaryKey + private String isbn; + + private String title; + private String author; + private int pages; + private Date saleDate; + private boolean isInStock; + private Map checkOuts; + + /** + * @return Returns the isbn. + */ + public String getIsbn() { + return isbn; + } + + /** + * @return Returns the saleDate. + */ + public Date getSaleDate() { + return saleDate; + } + + /** + * @param saleDate The saleDate to set. + */ + public void setSaleDate(Date saleDate) { + this.saleDate = saleDate; + } + + /** + * @return Returns the isInStock. + */ + public boolean isInStock() { + return isInStock; + } + + /** + * @param isInStock The isInStock to set. + */ + public void setInStock(boolean isInStock) { + this.isInStock = isInStock; + } + + /** + * @param isbn The isbn to set. + */ + public void setIsbn(String isbn) { + this.isbn = isbn; + } + + /** + * @return Returns the title. + */ + public String getTitle() { + return title; + } + + /** + * @param title The title to set. + */ + public void setTitle(String title) { + this.title = title; + } + + /** + * @return Returns the author. + */ + public String getAuthor() { + return author; + } + + /** + * @param author The author to set. + */ + public void setAuthor(String author) { + this.author = author; + } + + /** + * @return Returns the pages. + */ + public int getPages() { + return pages; + } + + /** + * @param pages The pages to set. + */ + public void setPages(int pages) { + this.pages = pages; + } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("isbn -> " + isbn).append("\n"); + sb.append("tile -> " + title).append("\n"); + sb.append("author -> " + author).append("\n"); + sb.append("pages -> " + pages).append("\n"); + return sb.toString(); + } + + /** + * @return Returns the checkOuts. + */ + public Map getCheckOuts() { + return checkOuts; + } + + /** + * @param checkOuts The checkOuts to set. + */ + public void setCheckOuts(Map checkOuts) { + this.checkOuts = checkOuts; + } +} diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/simpletons/BookReference.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/simpletons/BookReference.java new file mode 100644 index 000000000..314cf57b9 --- /dev/null +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/simpletons/BookReference.java @@ -0,0 +1,170 @@ +/* + * Copyright 2013-2014 the original author or authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.cassandra.test.integration.simpletons; + +import java.util.Date; +import java.util.List; +import java.util.Set; + +import org.springframework.data.cassandra.mapping.PrimaryKey; +import org.springframework.data.cassandra.mapping.Table; + +/** + * Test POJO + * + * @author David Webb + * + */ +@Table("bookReference") +public class BookReference { + + @PrimaryKey + private String isbn; + + private String title; + private String author; + private int pages; + private Date saleDate; + private boolean isInStock; + private Set references; + private List bookmarks; + + /** + * @return Returns the isbn. + */ + public String getIsbn() { + return isbn; + } + + /** + * @return Returns the saleDate. + */ + public Date getSaleDate() { + return saleDate; + } + + /** + * @param saleDate The saleDate to set. + */ + public void setSaleDate(Date saleDate) { + this.saleDate = saleDate; + } + + /** + * @return Returns the isInStock. + */ + public boolean isInStock() { + return isInStock; + } + + /** + * @param isInStock The isInStock to set. + */ + public void setInStock(boolean isInStock) { + this.isInStock = isInStock; + } + + /** + * @param isbn The isbn to set. + */ + public void setIsbn(String isbn) { + this.isbn = isbn; + } + + /** + * @return Returns the title. + */ + public String getTitle() { + return title; + } + + /** + * @param title The title to set. + */ + public void setTitle(String title) { + this.title = title; + } + + /** + * @return Returns the author. + */ + public String getAuthor() { + return author; + } + + /** + * @param author The author to set. + */ + public void setAuthor(String author) { + this.author = author; + } + + /** + * @return Returns the pages. + */ + public int getPages() { + return pages; + } + + /** + * @param pages The pages to set. + */ + public void setPages(int pages) { + this.pages = pages; + } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("isbn -> " + isbn).append("\n"); + sb.append("tile -> " + title).append("\n"); + sb.append("author -> " + author).append("\n"); + sb.append("pages -> " + pages).append("\n"); + return sb.toString(); + } + + /** + * @return Returns the references. + */ + public Set getReferences() { + return references; + } + + /** + * @param references The references to set. + */ + public void setReferences(Set references) { + this.references = references; + } + + /** + * @return Returns the bookmarks. + */ + public List getBookmarks() { + return bookmarks; + } + + /** + * @param bookmarks The bookmarks to set. + */ + public void setBookmarks(List bookmarks) { + this.bookmarks = bookmarks; + } + +}