Added check for mutated set so that the backingMap could contain all object values. The other option was to auto-refresh the instance's backing map when a getter is invoked for a valid property that isn't included in the backing map (which still may be handy/required for caching to work).
This commit is contained in:
parent
871c8d0c90
commit
a126607c09
3 changed files with 95 additions and 92 deletions
2
pom.xml
2
pom.xml
|
@ -5,7 +5,7 @@
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>net.helenus</groupId>
|
<groupId>net.helenus</groupId>
|
||||||
<artifactId>helenus-core</artifactId>
|
<artifactId>helenus-core</artifactId>
|
||||||
<version>2.0.13-SNAPSHOT</version>
|
<version>2.0.14-SNAPSHOT</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<name>helenus</name>
|
<name>helenus</name>
|
||||||
|
|
|
@ -15,21 +15,14 @@
|
||||||
*/
|
*/
|
||||||
package net.helenus.core.operation;
|
package net.helenus.core.operation;
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
import com.datastax.driver.core.ResultSet;
|
import com.datastax.driver.core.ResultSet;
|
||||||
import com.datastax.driver.core.querybuilder.BuiltStatement;
|
import com.datastax.driver.core.querybuilder.BuiltStatement;
|
||||||
import com.datastax.driver.core.querybuilder.Insert;
|
import com.datastax.driver.core.querybuilder.Insert;
|
||||||
import com.datastax.driver.core.querybuilder.QueryBuilder;
|
import com.datastax.driver.core.querybuilder.QueryBuilder;
|
||||||
|
|
||||||
import com.google.common.base.Predicates;
|
|
||||||
import com.google.common.collect.Lists;
|
|
||||||
import com.google.common.collect.Maps;
|
|
||||||
import net.helenus.core.AbstractSessionOperations;
|
import net.helenus.core.AbstractSessionOperations;
|
||||||
import net.helenus.core.Getter;
|
import net.helenus.core.Getter;
|
||||||
import net.helenus.core.reflect.HelenusPropertyNode;
|
import net.helenus.core.reflect.HelenusPropertyNode;
|
||||||
import net.helenus.core.reflect.MapExportable;
|
import net.helenus.core.reflect.MapExportable;
|
||||||
import net.helenus.mapping.ColumnType;
|
|
||||||
import net.helenus.mapping.HelenusEntity;
|
import net.helenus.mapping.HelenusEntity;
|
||||||
import net.helenus.mapping.HelenusProperty;
|
import net.helenus.mapping.HelenusProperty;
|
||||||
import net.helenus.mapping.MappingUtil;
|
import net.helenus.mapping.MappingUtil;
|
||||||
|
@ -37,36 +30,43 @@ import net.helenus.mapping.value.BeanColumnValueProvider;
|
||||||
import net.helenus.support.Fun;
|
import net.helenus.support.Fun;
|
||||||
import net.helenus.support.HelenusMappingException;
|
import net.helenus.support.HelenusMappingException;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
public final class InsertOperation extends AbstractOperation<ResultSet, InsertOperation> {
|
public final class InsertOperation extends AbstractOperation<ResultSet, InsertOperation> {
|
||||||
|
|
||||||
private HelenusEntity entity;
|
private HelenusEntity entity;
|
||||||
|
|
||||||
private final List<Fun.Tuple2<HelenusPropertyNode, Object>> values = new ArrayList<Fun.Tuple2<HelenusPropertyNode, Object>>();
|
private final List<Fun.Tuple2<HelenusPropertyNode, Object>> values = new ArrayList<Fun.Tuple2<HelenusPropertyNode, Object>>();
|
||||||
private boolean ifNotExists;
|
private boolean ifNotExists;
|
||||||
|
|
||||||
private int[] ttl;
|
private int[] ttl;
|
||||||
private long[] timestamp;
|
private long[] timestamp;
|
||||||
|
|
||||||
public InsertOperation(AbstractSessionOperations sessionOperations, boolean ifNotExists) {
|
public InsertOperation(AbstractSessionOperations sessionOperations, boolean ifNotExists) {
|
||||||
super(sessionOperations);
|
super(sessionOperations);
|
||||||
|
|
||||||
this.ifNotExists = ifNotExists;
|
this.ifNotExists = ifNotExists;
|
||||||
}
|
}
|
||||||
|
|
||||||
public InsertOperation(AbstractSessionOperations sessionOperations, HelenusEntity entity, Object pojo,
|
public InsertOperation(AbstractSessionOperations sessionOperations, HelenusEntity entity, Object pojo,
|
||||||
boolean ifNotExists) {
|
boolean ifNotExists) {
|
||||||
super(sessionOperations);
|
super(sessionOperations);
|
||||||
|
|
||||||
this.entity = entity;
|
this.entity = entity;
|
||||||
this.ifNotExists = ifNotExists;
|
this.ifNotExists = ifNotExists;
|
||||||
Set<String> keys = (pojo instanceof MapExportable) ? ((MapExportable)pojo).toMap().keySet() : null;
|
|
||||||
Collection<HelenusProperty> properties = entity.getOrderedProperties();
|
Collection<HelenusProperty> properties = entity.getOrderedProperties();
|
||||||
|
Set<String> keys = null;
|
||||||
|
|
||||||
|
if (pojo instanceof MapExportable) {
|
||||||
|
keys = ((MapExportable) pojo).mutated();
|
||||||
|
if (keys == null) {
|
||||||
|
keys = ((MapExportable) pojo).toMap().keySet();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (HelenusProperty prop : properties) {
|
for (HelenusProperty prop : properties) {
|
||||||
|
|
||||||
// Skip properties that are not in the map of the pojo we're storing. This creates a path
|
if (keys == null || keys.contains(prop.getPropertyName())) {
|
||||||
// for entity instances to be {in,up}serted without including all columns in the INSERT statement.
|
|
||||||
if (keys == null || keys.contains(prop.getPropertyName())) {
|
|
||||||
|
|
||||||
Object value = BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop);
|
Object value = BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop);
|
||||||
value = sessionOps.getValuePreparer().prepareColumnValue(value, prop);
|
value = sessionOps.getValuePreparer().prepareColumnValue(value, prop);
|
||||||
|
@ -78,91 +78,91 @@ public final class InsertOperation extends AbstractOperation<ResultSet, InsertOp
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public InsertOperation ifNotExists() {
|
public InsertOperation ifNotExists() {
|
||||||
this.ifNotExists = true;
|
this.ifNotExists = true;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public InsertOperation ifNotExists(boolean enable) {
|
public InsertOperation ifNotExists(boolean enable) {
|
||||||
this.ifNotExists = enable;
|
this.ifNotExists = enable;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public <V> InsertOperation value(Getter<V> getter, V val) {
|
public <V> InsertOperation value(Getter<V> getter, V val) {
|
||||||
|
|
||||||
Objects.requireNonNull(getter, "getter is empty");
|
Objects.requireNonNull(getter, "getter is empty");
|
||||||
|
|
||||||
if (val != null) {
|
if (val != null) {
|
||||||
HelenusPropertyNode node = MappingUtil.resolveMappingProperty(getter);
|
HelenusPropertyNode node = MappingUtil.resolveMappingProperty(getter);
|
||||||
Object value = sessionOps.getValuePreparer().prepareColumnValue(val, node.getProperty());
|
Object value = sessionOps.getValuePreparer().prepareColumnValue(val, node.getProperty());
|
||||||
|
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
values.add(Fun.Tuple2.of(node, value));
|
values.add(Fun.Tuple2.of(node, value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BuiltStatement buildStatement() {
|
public BuiltStatement buildStatement() {
|
||||||
|
|
||||||
values.forEach(t -> addPropertyNode(t._1));
|
values.forEach(t -> addPropertyNode(t._1));
|
||||||
|
|
||||||
if (values.isEmpty())
|
if (values.isEmpty())
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
if (entity == null) {
|
if (entity == null) {
|
||||||
throw new HelenusMappingException("unknown entity");
|
throw new HelenusMappingException("unknown entity");
|
||||||
}
|
}
|
||||||
|
|
||||||
Insert insert = QueryBuilder.insertInto(entity.getName().toCql());
|
Insert insert = QueryBuilder.insertInto(entity.getName().toCql());
|
||||||
|
|
||||||
if (ifNotExists) {
|
if (ifNotExists) {
|
||||||
insert.ifNotExists();
|
insert.ifNotExists();
|
||||||
}
|
}
|
||||||
|
|
||||||
values.forEach(t -> {
|
values.forEach(t -> {
|
||||||
insert.value(t._1.getColumnName(), t._2);
|
insert.value(t._1.getColumnName(), t._2);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (this.ttl != null) {
|
if (this.ttl != null) {
|
||||||
insert.using(QueryBuilder.ttl(this.ttl[0]));
|
insert.using(QueryBuilder.ttl(this.ttl[0]));
|
||||||
}
|
}
|
||||||
if (this.timestamp != null) {
|
if (this.timestamp != null) {
|
||||||
insert.using(QueryBuilder.timestamp(this.timestamp[0]));
|
insert.using(QueryBuilder.timestamp(this.timestamp[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
return insert;
|
return insert;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ResultSet transform(ResultSet resultSet) {
|
public ResultSet transform(ResultSet resultSet) {
|
||||||
return resultSet;
|
return resultSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
public InsertOperation usingTtl(int ttl) {
|
public InsertOperation usingTtl(int ttl) {
|
||||||
this.ttl = new int[1];
|
this.ttl = new int[1];
|
||||||
this.ttl[0] = ttl;
|
this.ttl[0] = ttl;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public InsertOperation usingTimestamp(long timestamp) {
|
public InsertOperation usingTimestamp(long timestamp) {
|
||||||
this.timestamp = new long[1];
|
this.timestamp = new long[1];
|
||||||
this.timestamp[0] = timestamp;
|
this.timestamp[0] = timestamp;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addPropertyNode(HelenusPropertyNode p) {
|
private void addPropertyNode(HelenusPropertyNode p) {
|
||||||
if (entity == null) {
|
if (entity == null) {
|
||||||
entity = p.getEntity();
|
entity = p.getEntity();
|
||||||
} else if (entity != p.getEntity()) {
|
} else if (entity != p.getEntity()) {
|
||||||
throw new HelenusMappingException("you can insert only single entity " + entity.getMappingInterface()
|
throw new HelenusMappingException("you can insert only single entity " + entity.getMappingInterface()
|
||||||
+ " or " + p.getEntity().getMappingInterface());
|
+ " or " + p.getEntity().getMappingInterface());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
package net.helenus.core.reflect;
|
package net.helenus.core.reflect;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
public interface MapExportable {
|
public interface MapExportable {
|
||||||
|
|
||||||
|
@ -23,4 +24,6 @@ public interface MapExportable {
|
||||||
|
|
||||||
Map<String, Object> toMap();
|
Map<String, Object> toMap();
|
||||||
|
|
||||||
|
default Set<String> mutated() { return null; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue