Set and UDTSet converter

This commit is contained in:
Albert Shift 2015-04-18 11:28:20 -07:00
parent 153c7cc7bf
commit f59bf9ec2f
8 changed files with 310 additions and 4 deletions

View file

@ -0,0 +1,49 @@
/*
* Copyright (C) 2015 Noorq, Inc.
*
* 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 com.noorq.casser.mapping.convert;
import java.nio.ByteBuffer;
import com.datastax.driver.core.UDTValue;
import com.datastax.driver.core.UserType;
import com.noorq.casser.core.SessionRepository;
import com.noorq.casser.mapping.CasserProperty;
import com.noorq.casser.mapping.value.UDTColumnValuePreparer;
public abstract class AbstractUDTValueWriter extends AbstractEntityValueWriter<UDTValue> {
protected final UserType userType;
protected final UDTColumnValuePreparer valuePreparer;
public AbstractUDTValueWriter(Class<?> iface, UserType userType, SessionRepository repository) {
super(iface);
this.userType = userType;
this.valuePreparer = new UDTColumnValuePreparer(userType, repository);
}
@Override
void writeColumn(UDTValue udtValue, Object value,
CasserProperty prop) {
ByteBuffer bytes = (ByteBuffer) valuePreparer.prepareColumnValue(value, prop);
if (bytes != null) {
udtValue.setBytesUnsafe(prop.getColumnName().getName(), bytes);
}
}
}

View file

@ -0,0 +1,56 @@
/*
* Copyright (C) 2015 Noorq, Inc.
*
* 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 com.noorq.casser.mapping.convert;
import java.util.Set;
import java.util.function.Function;
import com.datastax.driver.core.UDTValue;
import com.datastax.driver.core.UserType;
import com.google.common.collect.ImmutableSet;
import com.noorq.casser.core.SessionRepository;
public final class SetToUDTSetConverter extends AbstractUDTValueWriter implements Function<Object, Object> {
public SetToUDTSetConverter(Class<?> iface, UserType userType, SessionRepository repository) {
super(iface, userType, repository);
}
@Override
public Object apply(Object t) {
Set<Object> sourceSet = (Set<Object>) t;
ImmutableSet.Builder<UDTValue> builder = ImmutableSet.builder();
for (Object source : sourceSet) {
UDTValue outValue = null;
if (source != null) {
outValue = userType.newValue();
write(outValue, source);
}
builder.add(outValue);
}
return builder.build();
}
}

View file

@ -0,0 +1,71 @@
/*
* Copyright (C) 2015 Noorq, Inc.
*
* 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 com.noorq.casser.mapping.convert;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import com.datastax.driver.core.UDTValue;
import com.google.common.collect.ImmutableSet;
import com.noorq.casser.core.Casser;
import com.noorq.casser.core.SessionRepository;
import com.noorq.casser.mapping.CasserEntity;
import com.noorq.casser.mapping.value.UDTColumnValueProvider;
import com.noorq.casser.mapping.value.ValueProviderMap;
public final class UDTSetToSetConverter implements Function<Object, Object> {
private final Class<?> iface;
private final CasserEntity entity;
private final UDTColumnValueProvider valueProvider;
public UDTSetToSetConverter(Class<?> iface, SessionRepository repository) {
this.iface = iface;
this.entity = Casser.entity(iface);
this.valueProvider = new UDTColumnValueProvider(repository);
}
@Override
public Object apply(Object t) {
Set<UDTValue> sourceSet = (Set<UDTValue>) t;
ImmutableSet.Builder<Object> builder = ImmutableSet.builder();
for (UDTValue source : sourceSet) {
Object obj = null;
if (source != null) {
Map<String, Object> map = new ValueProviderMap(source,
valueProvider,
entity);
obj = Casser.map(iface, map);
}
builder.add(obj);
}
return builder.build();
}
}

View file

@ -28,20 +28,20 @@ import com.noorq.casser.mapping.value.ValueProviderMap;
public final class UDTValueToEntityConverter implements Function<UDTValue, Object> {
private final Class<?> iface;
private final SessionRepository repository;
private final CasserEntity entity;
private final UDTColumnValueProvider valueProvider;
public UDTValueToEntityConverter(Class<?> iface, SessionRepository repository) {
this.iface = iface;
this.repository = repository;
this.entity = Casser.entity(iface);
this.valueProvider = new UDTColumnValueProvider(repository);
}
@Override
public Object apply(UDTValue source) {
Map<String, Object> map = new ValueProviderMap(source,
new UDTColumnValueProvider(repository),
valueProvider,
entity);
return Casser.map(iface, map);

View file

@ -17,16 +17,23 @@ package com.noorq.casser.mapping.javatype;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.Optional;
import java.util.Set;
import java.util.function.Function;
import com.datastax.driver.core.DataType;
import com.datastax.driver.core.UDTValue;
import com.datastax.driver.core.UserType;
import com.noorq.casser.core.SessionRepository;
import com.noorq.casser.mapping.ColumnType;
import com.noorq.casser.mapping.IdentityName;
import com.noorq.casser.mapping.annotation.Types;
import com.noorq.casser.mapping.convert.SetToUDTSetConverter;
import com.noorq.casser.mapping.convert.UDTSetToSetConverter;
import com.noorq.casser.mapping.type.AbstractDataType;
import com.noorq.casser.mapping.type.DTDataType;
import com.noorq.casser.mapping.type.UDTSetDataType;
import com.noorq.casser.support.CasserMappingException;
import com.noorq.casser.support.Either;
public final class SetJavaType extends AbstractJavaType {
@ -67,5 +74,54 @@ public final class SetJavaType extends AbstractJavaType {
}
}
@Override
public Optional<Function<Object, Object>> resolveReadConverter(
AbstractDataType abstractDataType, SessionRepository repository) {
if (abstractDataType instanceof UDTSetDataType) {
UDTSetDataType dt = (UDTSetDataType) abstractDataType;
Class<Object> javaClass = (Class<Object>) dt.getUdtClasses()[0];
if (UDTValue.class.isAssignableFrom(javaClass)) {
return Optional.empty();
}
return Optional.of(new UDTSetToSetConverter(javaClass, repository));
}
return Optional.empty();
}
@Override
public Optional<Function<Object, Object>> resolveWriteConverter(
AbstractDataType abstractDataType, SessionRepository repository) {
if (abstractDataType instanceof UDTSetDataType) {
UDTSetDataType dt = (UDTSetDataType) abstractDataType;
Class<Object> javaClass = (Class<Object>) dt.getUdtClasses()[0];
if (UDTValue.class.isAssignableFrom(javaClass)) {
return Optional.empty();
}
UserType userType = repository.findUserType(dt.getUdtName().getName());
if (userType == null) {
throw new CasserMappingException("UserType not found for " + dt.getUdtName() + " with type " + javaClass);
}
return Optional.of(new SetToUDTSetConverter(javaClass, userType, repository));
}
return Optional.empty();
}
}

View file

@ -42,6 +42,10 @@ public final class UDTSetDataType extends AbstractDataType {
return new Class<?>[] { udtClass };
}
public IdentityName getUdtName() {
return udtName;
}
@Override
public void addColumn(Create create, IdentityName columnName) {
ensureSimpleColumn(columnName);

View file

@ -32,7 +32,7 @@ public interface Book {
Set<Author> reviewers();
Map<String, Section> contents();
Map<Integer, Section> contents();
Map<Section, String> notes();

View file

@ -15,6 +15,9 @@
*/
package com.noorq.casser.test.integration.core.udtcollection;
import java.util.HashSet;
import java.util.Set;
import org.junit.BeforeClass;
import org.junit.Test;
@ -38,5 +41,72 @@ public class UDTCollectionTest extends AbstractEmbeddedCassandraTest {
System.out.println(book);
}
@Test
public void testSetCRUID() {
int id = 555;
// CREATE
Set<Author> reviewers = new HashSet<Author>();
reviewers.add(new AuthorImpl("Alex", "San Jose"));
reviewers.add(new AuthorImpl("Bob", "San Francisco"));
session.insert()
.value(book::id, id)
.value(book::reviewers, reviewers)
.sync();
}
private static final class AuthorImpl implements Author {
String name;
String city;
AuthorImpl(String name, String city) {
this.name = name;
this.city = city;
}
@Override
public String name() {
return name;
}
@Override
public String city() {
return city;
}
}
private static final class SectionImpl implements Section {
String title;
int page;
SectionImpl(String title, int page) {
this.title = title;
this.page = page;
}
@Override
public String title() {
return title;
}
@Override
public int page() {
return page;
}
}
}