Formatting.
This commit is contained in:
parent
d19a9c741d
commit
c025dc35a7
37 changed files with 874 additions and 698 deletions
|
@ -25,7 +25,6 @@ import java.io.PrintStream;
|
|||
import java.util.List;
|
||||
import java.util.concurrent.Executor;
|
||||
import net.helenus.core.cache.Facet;
|
||||
import net.helenus.core.operation.Operation;
|
||||
import net.helenus.mapping.value.ColumnValuePreparer;
|
||||
import net.helenus.mapping.value.ColumnValueProvider;
|
||||
import net.helenus.support.Either;
|
||||
|
|
|
@ -17,8 +17,6 @@ package net.helenus.core;
|
|||
|
||||
import static net.helenus.core.HelenusSession.deleted;
|
||||
|
||||
import com.datastax.driver.core.BatchStatement;
|
||||
import com.datastax.driver.core.ResultSet;
|
||||
import com.diffplug.common.base.Errors;
|
||||
import com.google.common.base.Stopwatch;
|
||||
import com.google.common.collect.HashBasedTable;
|
||||
|
@ -285,8 +283,7 @@ public abstract class AbstractUnitOfWork<E extends Exception>
|
|||
if (!facet.fixed()) {
|
||||
if (facet.alone()) {
|
||||
String columnName = facet.name() + "==" + facet.value();
|
||||
if (result == null)
|
||||
result = cache.get(tableName, columnName);
|
||||
if (result == null) result = cache.get(tableName, columnName);
|
||||
cache.put(tableName, columnName, Either.left(value));
|
||||
}
|
||||
}
|
||||
|
@ -418,10 +415,15 @@ public abstract class AbstractUnitOfWork<E extends Exception>
|
|||
private void mergeCache(Table<String, String, Either<Object, List<Facet>>> from) {
|
||||
Table<String, String, Either<Object, List<Facet>>> to = this.cache;
|
||||
from.rowMap()
|
||||
.forEach((rowKey, columnMap) -> {
|
||||
columnMap.forEach((columnKey, value) -> {
|
||||
.forEach(
|
||||
(rowKey, columnMap) -> {
|
||||
columnMap.forEach(
|
||||
(columnKey, value) -> {
|
||||
if (to.contains(rowKey, columnKey)) {
|
||||
to.put(rowKey, columnKey, Either.left(
|
||||
to.put(
|
||||
rowKey,
|
||||
columnKey,
|
||||
Either.left(
|
||||
CacheUtil.merge(
|
||||
to.get(rowKey, columnKey).getLeft(),
|
||||
from.get(rowKey, columnKey).getLeft())));
|
||||
|
@ -453,5 +455,7 @@ public abstract class AbstractUnitOfWork<E extends Exception>
|
|||
return committed;
|
||||
}
|
||||
|
||||
public long committedAt() { return committedAt; }
|
||||
public long committedAt() {
|
||||
return committedAt;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -79,7 +79,8 @@ public final class Filter<V> {
|
|||
return new Filter<V>(node, postulate);
|
||||
}
|
||||
|
||||
public static <V> Filter<V> create(Getter<V> getter, HelenusPropertyNode node, Postulate<V> postulate) {
|
||||
public static <V> Filter<V> create(
|
||||
Getter<V> getter, HelenusPropertyNode node, Postulate<V> postulate) {
|
||||
Objects.requireNonNull(getter, "empty getter");
|
||||
Objects.requireNonNull(postulate, "empty operator");
|
||||
return new Filter<V>(node, postulate);
|
||||
|
|
|
@ -256,7 +256,8 @@ public class HelenusSession extends AbstractSessionOperations implements Closeab
|
|||
.collect(Collectors.toList());
|
||||
for (Object pojo : items) {
|
||||
HelenusEntity entity = Helenus.resolve(MappingUtil.getMappingInterface(pojo));
|
||||
Map<String, Object> valueMap = pojo instanceof MapExportable ? ((MapExportable) pojo).toMap() : null;
|
||||
Map<String, Object> valueMap =
|
||||
pojo instanceof MapExportable ? ((MapExportable) pojo).toMap() : null;
|
||||
if (entity.isCacheable()) {
|
||||
List<Facet> boundFacets = new ArrayList<>();
|
||||
for (Facet facet : entity.getFacets()) {
|
||||
|
@ -265,9 +266,11 @@ public class HelenusSession extends AbstractSessionOperations implements Closeab
|
|||
UnboundFacet.Binder binder = unboundFacet.binder();
|
||||
unboundFacet
|
||||
.getProperties()
|
||||
.forEach(prop -> {
|
||||
.forEach(
|
||||
prop -> {
|
||||
if (valueMap == null) {
|
||||
Object value = BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop);
|
||||
Object value =
|
||||
BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop);
|
||||
binder.setValueForProperty(prop, value.toString());
|
||||
} else {
|
||||
Object v = valueMap.get(prop.getPropertyName());
|
||||
|
@ -390,7 +393,9 @@ public class HelenusSession extends AbstractSessionOperations implements Closeab
|
|||
HelenusEntity entity = Helenus.resolve(pojo);
|
||||
Class<?> entityClass = entity.getMappingInterface();
|
||||
|
||||
return new SelectOperation<E>(this, entity,
|
||||
return new SelectOperation<E>(
|
||||
this,
|
||||
entity,
|
||||
(r) -> {
|
||||
Map<String, Object> map = new ValueProviderMap(r, valueProvider, entity);
|
||||
return (E) Helenus.map(entityClass, map);
|
||||
|
@ -402,7 +407,9 @@ public class HelenusSession extends AbstractSessionOperations implements Closeab
|
|||
ColumnValueProvider valueProvider = getValueProvider();
|
||||
HelenusEntity entity = Helenus.entity(entityClass);
|
||||
|
||||
return new SelectOperation<E>(this, entity,
|
||||
return new SelectOperation<E>(
|
||||
this,
|
||||
entity,
|
||||
(r) -> {
|
||||
Map<String, Object> map = new ValueProviderMap(r, valueProvider, entity);
|
||||
return (E) Helenus.map(entityClass, map);
|
||||
|
@ -417,7 +424,9 @@ public class HelenusSession extends AbstractSessionOperations implements Closeab
|
|||
Objects.requireNonNull(entityClass, "entityClass is empty");
|
||||
HelenusEntity entity = Helenus.entity(entityClass);
|
||||
|
||||
return new SelectOperation<E>(this, entity,
|
||||
return new SelectOperation<E>(
|
||||
this,
|
||||
entity,
|
||||
(r) -> {
|
||||
Map<String, Object> map = new ValueProviderMap(r, valueProvider, entity);
|
||||
return (E) Helenus.map(entityClass, map);
|
||||
|
@ -425,7 +434,8 @@ public class HelenusSession extends AbstractSessionOperations implements Closeab
|
|||
}
|
||||
|
||||
public <E> SelectOperation<Row> selectAll(E pojo) {
|
||||
Objects.requireNonNull(pojo, "supplied object must be a dsl for a registered entity but cannot be null");
|
||||
Objects.requireNonNull(
|
||||
pojo, "supplied object must be a dsl for a registered entity but cannot be null");
|
||||
HelenusEntity entity = Helenus.resolve(pojo);
|
||||
return new SelectOperation<Row>(this, entity);
|
||||
}
|
||||
|
@ -440,7 +450,8 @@ public class HelenusSession extends AbstractSessionOperations implements Closeab
|
|||
Objects.requireNonNull(getter1, "field 1 is empty");
|
||||
|
||||
HelenusPropertyNode p1 = MappingUtil.resolveMappingProperty(getter1);
|
||||
return new SelectOperation<Tuple1<V1>>(this, new Mappers.Mapper1<V1>(getValueProvider(), p1), p1);
|
||||
return new SelectOperation<Tuple1<V1>>(
|
||||
this, new Mappers.Mapper1<V1>(getValueProvider(), p1), p1);
|
||||
}
|
||||
|
||||
public <V1, V2> SelectOperation<Tuple2<V1, V2>> select(Getter<V1> getter1, Getter<V2> getter2) {
|
||||
|
@ -449,7 +460,8 @@ public class HelenusSession extends AbstractSessionOperations implements Closeab
|
|||
|
||||
HelenusPropertyNode p1 = MappingUtil.resolveMappingProperty(getter1);
|
||||
HelenusPropertyNode p2 = MappingUtil.resolveMappingProperty(getter2);
|
||||
return new SelectOperation<Fun.Tuple2<V1, V2>>(this, new Mappers.Mapper2<V1, V2>(getValueProvider(), p1, p2), p1, p2);
|
||||
return new SelectOperation<Fun.Tuple2<V1, V2>>(
|
||||
this, new Mappers.Mapper2<V1, V2>(getValueProvider(), p1, p2), p1, p2);
|
||||
}
|
||||
|
||||
public <V1, V2, V3> SelectOperation<Fun.Tuple3<V1, V2, V3>> select(
|
||||
|
@ -723,7 +735,8 @@ public class HelenusSession extends AbstractSessionOperations implements Closeab
|
|||
}
|
||||
|
||||
public <T> InsertOperation<T> upsert(T pojo) {
|
||||
Objects.requireNonNull(pojo,
|
||||
Objects.requireNonNull(
|
||||
pojo,
|
||||
"supplied object must be either an instance of the entity class or a dsl for it, but cannot be null");
|
||||
HelenusEntity entity = null;
|
||||
try {
|
||||
|
|
|
@ -77,14 +77,16 @@ public final class TableOperations {
|
|||
}
|
||||
|
||||
public void createView(HelenusEntity entity) {
|
||||
sessionOps.execute(SchemaUtil.createMaterializedView(
|
||||
sessionOps.execute(
|
||||
SchemaUtil.createMaterializedView(
|
||||
sessionOps.usingKeyspace(), entity.getName().toCql(), entity));
|
||||
// executeBatch(SchemaUtil.createIndexes(entity)); NOTE: Unfortunately C* 3.10 does not yet support 2i on materialized views.
|
||||
}
|
||||
|
||||
public void dropView(HelenusEntity entity) {
|
||||
sessionOps.execute(
|
||||
SchemaUtil.dropMaterializedView(sessionOps.usingKeyspace(), entity.getName().toCql(), entity));
|
||||
SchemaUtil.dropMaterializedView(
|
||||
sessionOps.usingKeyspace(), entity.getName().toCql(), entity));
|
||||
}
|
||||
|
||||
public void updateView(TableMetadata tmd, HelenusEntity entity) {
|
||||
|
|
|
@ -15,12 +15,10 @@
|
|||
*/
|
||||
package net.helenus.core;
|
||||
|
||||
import com.datastax.driver.core.Statement;
|
||||
import com.google.common.base.Stopwatch;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import net.helenus.core.cache.Facet;
|
||||
import net.helenus.core.operation.AbstractOperation;
|
||||
|
||||
|
|
|
@ -30,7 +30,9 @@ public class BoundFacet extends Facet<String> {
|
|||
this.properties.put(property, value);
|
||||
}
|
||||
|
||||
public Set<HelenusProperty> getProperties() { return properties.keySet(); }
|
||||
public Set<HelenusProperty> getProperties() {
|
||||
return properties.keySet();
|
||||
}
|
||||
|
||||
public BoundFacet(String name, Map<HelenusProperty, Object> properties) {
|
||||
super(
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
package net.helenus.core.cache;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import net.helenus.core.Helenus;
|
||||
import net.helenus.core.reflect.Entity;
|
||||
import net.helenus.core.reflect.MapExportable;
|
||||
|
@ -7,13 +12,6 @@ import net.helenus.mapping.HelenusEntity;
|
|||
import net.helenus.mapping.HelenusProperty;
|
||||
import net.helenus.mapping.MappingUtil;
|
||||
import net.helenus.mapping.value.BeanColumnValueProvider;
|
||||
import net.helenus.support.HelenusException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class CacheUtil {
|
||||
|
||||
|
@ -28,7 +26,8 @@ public class CacheUtil {
|
|||
return out;
|
||||
}
|
||||
|
||||
private static void kCombinations(List<String> items, int n, int k, String[] arr, List<String[]> out) {
|
||||
private static void kCombinations(
|
||||
List<String> items, int n, int k, String[] arr, List<String[]> out) {
|
||||
if (k == 0) {
|
||||
out.add(arr.clone());
|
||||
} else {
|
||||
|
@ -42,7 +41,8 @@ public class CacheUtil {
|
|||
public static List<String> flatKeys(String table, List<Facet> facets) {
|
||||
return flattenFacets(facets)
|
||||
.stream()
|
||||
.map(combination -> {
|
||||
.map(
|
||||
combination -> {
|
||||
return table + "." + Arrays.toString(combination);
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
|
@ -61,14 +61,18 @@ public class CacheUtil {
|
|||
})
|
||||
.collect(Collectors.toList()));
|
||||
// TODO(gburd): rework so as to not generate the combinations at all rather than filter
|
||||
facets = facets.stream()
|
||||
facets =
|
||||
facets
|
||||
.stream()
|
||||
.filter(f -> !f.fixed())
|
||||
.filter(f -> !f.alone() || !f.combined())
|
||||
.collect(Collectors.toList());
|
||||
for (Facet facet : facets) {
|
||||
combinations = combinations
|
||||
combinations =
|
||||
combinations
|
||||
.stream()
|
||||
.filter(combo -> {
|
||||
.filter(
|
||||
combo -> {
|
||||
// When used alone, this facet is not distinct so don't use it as a key.
|
||||
if (combo.length == 1) {
|
||||
if (!facet.alone() && combo[0].startsWith(facet.name() + "==")) {
|
||||
|
@ -91,9 +95,7 @@ public class CacheUtil {
|
|||
return combinations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge changed values in the map behind `from` into `to`.
|
||||
*/
|
||||
/** Merge changed values in the map behind `from` into `to`. */
|
||||
public static Object merge(Object t, Object f) {
|
||||
HelenusEntity entity = Helenus.resolve(MappingUtil.getMappingInterface(t));
|
||||
|
||||
|
@ -101,7 +103,10 @@ public class CacheUtil {
|
|||
if (f == null) return t;
|
||||
if (t == null) return f;
|
||||
|
||||
if (t instanceof MapExportable && t instanceof Entity && f instanceof MapExportable && f instanceof Entity) {
|
||||
if (t instanceof MapExportable
|
||||
&& t instanceof Entity
|
||||
&& f instanceof MapExportable
|
||||
&& f instanceof Entity) {
|
||||
Entity to = (Entity) t;
|
||||
Entity from = (Entity) f;
|
||||
Map<String, Object> toValueMap = ((MapExportable) to).toMap();
|
||||
|
@ -128,8 +133,9 @@ public class CacheUtil {
|
|||
if (toVal == fromVal) {
|
||||
// Case: object identity
|
||||
// Goal: ensure write time and ttl are also in sync
|
||||
if (fromWriteTime != null && fromWriteTime != 0L &&
|
||||
(toWriteTime == null || fromWriteTime > toWriteTime)) {
|
||||
if (fromWriteTime != null
|
||||
&& fromWriteTime != 0L
|
||||
&& (toWriteTime == null || fromWriteTime > toWriteTime)) {
|
||||
((MapExportable) to).put(writeTimeKey, fromWriteTime);
|
||||
}
|
||||
if (fromTtl > 0 && fromTtl > toTtl) {
|
||||
|
@ -207,5 +213,7 @@ public class CacheUtil {
|
|||
return "_" + columnName + "_writeTime";
|
||||
}
|
||||
|
||||
public static String ttlKey(String columnName) { return "_" + columnName + "_ttl"; }
|
||||
public static String ttlKey(String columnName) {
|
||||
return "_" + columnName + "_ttl";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,6 +58,11 @@ public class Facet<T> {
|
|||
this.combined = combined;
|
||||
}
|
||||
|
||||
public boolean alone() { return alone; }
|
||||
public boolean combined() { return combined; }
|
||||
public boolean alone() {
|
||||
return alone;
|
||||
}
|
||||
|
||||
public boolean combined() {
|
||||
return combined;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,8 @@ import java.util.Map;
|
|||
import net.helenus.core.*;
|
||||
import net.helenus.mapping.HelenusProperty;
|
||||
|
||||
public abstract class AbstractFilterStreamOperation<E, O extends AbstractFilterStreamOperation<E, O>>
|
||||
public abstract class AbstractFilterStreamOperation<
|
||||
E, O extends AbstractFilterStreamOperation<E, O>>
|
||||
extends AbstractStreamOperation<E, O> {
|
||||
|
||||
protected Map<HelenusProperty, Filter<?>> filters = null;
|
||||
|
@ -41,8 +42,7 @@ public abstract class AbstractFilterStreamOperation<E, O extends AbstractFilterS
|
|||
|
||||
public <V> O where(Getter<V> getter, Operator operator, V val) {
|
||||
|
||||
if (val != null)
|
||||
addFilter(Filter.create(getter, operator, val));
|
||||
if (val != null) addFilter(Filter.create(getter, operator, val));
|
||||
|
||||
return (O) this;
|
||||
}
|
||||
|
@ -63,8 +63,7 @@ public abstract class AbstractFilterStreamOperation<E, O extends AbstractFilterS
|
|||
|
||||
public <V> O and(Getter<V> getter, Operator operator, V val) {
|
||||
|
||||
if (val != null)
|
||||
addFilter(Filter.create(getter, operator, val));
|
||||
if (val != null) addFilter(Filter.create(getter, operator, val));
|
||||
|
||||
return (O) this;
|
||||
}
|
||||
|
@ -85,8 +84,7 @@ public abstract class AbstractFilterStreamOperation<E, O extends AbstractFilterS
|
|||
|
||||
public <V> O onlyIf(Getter<V> getter, Operator operator, V val) {
|
||||
|
||||
if (val != null)
|
||||
addIfFilter(Filter.create(getter, operator, val));
|
||||
if (val != null) addIfFilter(Filter.create(getter, operator, val));
|
||||
|
||||
return (O) this;
|
||||
}
|
||||
|
|
|
@ -20,8 +20,6 @@ import com.datastax.driver.core.ResultSet;
|
|||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.CompletionException;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import com.datastax.driver.core.Statement;
|
||||
import net.helenus.core.AbstractSessionOperations;
|
||||
import net.helenus.core.UnitOfWork;
|
||||
|
||||
|
@ -41,8 +39,15 @@ public abstract class AbstractOperation<E, O extends AbstractOperation<E, O>>
|
|||
public E sync() throws TimeoutException {
|
||||
final Timer.Context context = requestLatency.time();
|
||||
try {
|
||||
ResultSet resultSet = this.execute(sessionOps,null, traceContext, queryExecutionTimeout, queryTimeoutUnits,
|
||||
showValues,false);
|
||||
ResultSet resultSet =
|
||||
this.execute(
|
||||
sessionOps,
|
||||
null,
|
||||
traceContext,
|
||||
queryExecutionTimeout,
|
||||
queryTimeoutUnits,
|
||||
showValues,
|
||||
false);
|
||||
return transform(resultSet);
|
||||
} finally {
|
||||
context.stop();
|
||||
|
@ -54,7 +59,11 @@ public abstract class AbstractOperation<E, O extends AbstractOperation<E, O>>
|
|||
|
||||
final Timer.Context context = requestLatency.time();
|
||||
try {
|
||||
ResultSet resultSet = execute(sessionOps, uow, traceContext,
|
||||
ResultSet resultSet =
|
||||
execute(
|
||||
sessionOps,
|
||||
uow,
|
||||
traceContext,
|
||||
queryExecutionTimeout,
|
||||
queryTimeoutUnits,
|
||||
showValues,
|
||||
|
|
|
@ -109,7 +109,8 @@ public abstract class AbstractOptionalOperation<E, O extends AbstractOptionalOpe
|
|||
if (updateCache && result.isPresent()) {
|
||||
E r = result.get();
|
||||
Class<?> resultClass = r.getClass();
|
||||
if (!(resultClass.getEnclosingClass() != null && resultClass.getEnclosingClass() == Fun.class)) {
|
||||
if (!(resultClass.getEnclosingClass() != null
|
||||
&& resultClass.getEnclosingClass() == Fun.class)) {
|
||||
List<Facet> facets = getFacets();
|
||||
if (facets != null && facets.size() > 1) {
|
||||
sessionOps.updateCache(r, facets);
|
||||
|
@ -210,8 +211,15 @@ public abstract class AbstractOptionalOperation<E, O extends AbstractOptionalOpe
|
|||
} else {
|
||||
|
||||
// Formulate the query and execute it against the Cassandra cluster.
|
||||
ResultSet resultSet = execute(sessionOps, uow, traceContext, queryExecutionTimeout, queryTimeoutUnits,
|
||||
showValues, true);
|
||||
ResultSet resultSet =
|
||||
execute(
|
||||
sessionOps,
|
||||
uow,
|
||||
traceContext,
|
||||
queryExecutionTimeout,
|
||||
queryTimeoutUnits,
|
||||
showValues,
|
||||
true);
|
||||
|
||||
// Transform the query result set into the desired shape.
|
||||
result = transform(resultSet);
|
||||
|
|
|
@ -328,7 +328,8 @@ public abstract class AbstractStatementOperation<E, O extends AbstractStatementO
|
|||
|
||||
protected Object cacheUpdate(UnitOfWork<?> uow, E pojo, List<Facet> identifyingFacets) {
|
||||
List<Facet> facets = new ArrayList<>();
|
||||
Map<String, Object> valueMap = pojo instanceof MapExportable ? ((MapExportable) pojo).toMap() : null;
|
||||
Map<String, Object> valueMap =
|
||||
pojo instanceof MapExportable ? ((MapExportable) pojo).toMap() : null;
|
||||
|
||||
for (Facet facet : identifyingFacets) {
|
||||
if (facet instanceof UnboundFacet) {
|
||||
|
|
|
@ -114,7 +114,8 @@ public abstract class AbstractStreamOperation<E, O extends AbstractStreamOperati
|
|||
resultStream.forEach(
|
||||
result -> {
|
||||
Class<?> resultClass = result.getClass();
|
||||
if (!(resultClass.getEnclosingClass() != null && resultClass.getEnclosingClass() == Fun.class)) {
|
||||
if (!(resultClass.getEnclosingClass() != null
|
||||
&& resultClass.getEnclosingClass() == Fun.class)) {
|
||||
sessionOps.updateCache(result, facets);
|
||||
}
|
||||
again.add(result);
|
||||
|
@ -209,8 +210,15 @@ public abstract class AbstractStreamOperation<E, O extends AbstractStreamOperati
|
|||
|
||||
// Check to see if we fetched the object from the cache
|
||||
if (resultStream == null) {
|
||||
ResultSet resultSet = execute(sessionOps, uow, traceContext, queryExecutionTimeout, queryTimeoutUnits,
|
||||
showValues, true);
|
||||
ResultSet resultSet =
|
||||
execute(
|
||||
sessionOps,
|
||||
uow,
|
||||
traceContext,
|
||||
queryExecutionTimeout,
|
||||
queryTimeoutUnits,
|
||||
showValues,
|
||||
true);
|
||||
resultStream = transform(resultSet);
|
||||
}
|
||||
|
||||
|
|
|
@ -19,14 +19,13 @@ import com.codahale.metrics.Timer;
|
|||
import com.datastax.driver.core.BatchStatement;
|
||||
import com.datastax.driver.core.ResultSet;
|
||||
import com.google.common.base.Stopwatch;
|
||||
import net.helenus.core.AbstractSessionOperations;
|
||||
import net.helenus.core.UnitOfWork;
|
||||
import net.helenus.support.HelenusException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.stream.Collectors;
|
||||
import net.helenus.core.AbstractSessionOperations;
|
||||
import net.helenus.core.UnitOfWork;
|
||||
import net.helenus.support.HelenusException;
|
||||
|
||||
public class BatchOperation extends Operation<Long> {
|
||||
private BatchStatement batch = null;
|
||||
|
@ -45,7 +44,8 @@ public class BatchOperation extends Operation<Long> {
|
|||
@Override
|
||||
public BatchStatement buildStatement(boolean cached) {
|
||||
batch = new BatchStatement();
|
||||
batch.addAll(operations.stream().map(o -> o.buildStatement(cached)).collect(Collectors.toList()));
|
||||
batch.addAll(
|
||||
operations.stream().map(o -> o.buildStatement(cached)).collect(Collectors.toList()));
|
||||
batch.setConsistencyLevel(sessionOps.getDefaultConsistencyLevel());
|
||||
timestamp = System.nanoTime();
|
||||
batch.setDefaultTimestamp(timestamp);
|
||||
|
@ -68,7 +68,15 @@ public class BatchOperation extends Operation<Long> {
|
|||
try {
|
||||
timestamp = System.nanoTime();
|
||||
batch.setDefaultTimestamp(timestamp);
|
||||
ResultSet resultSet = this.execute(sessionOps, null, traceContext, queryExecutionTimeout, queryTimeoutUnits, showValues, false);
|
||||
ResultSet resultSet =
|
||||
this.execute(
|
||||
sessionOps,
|
||||
null,
|
||||
traceContext,
|
||||
queryExecutionTimeout,
|
||||
queryTimeoutUnits,
|
||||
showValues,
|
||||
false);
|
||||
if (!resultSet.wasApplied()) {
|
||||
throw new HelenusException("Failed to apply batch.");
|
||||
}
|
||||
|
@ -80,14 +88,21 @@ public class BatchOperation extends Operation<Long> {
|
|||
|
||||
public Long sync(UnitOfWork<?> uow) throws TimeoutException {
|
||||
if (operations.size() == 0) return 0L;
|
||||
if (uow == null)
|
||||
return sync();
|
||||
if (uow == null) return sync();
|
||||
|
||||
final Timer.Context context = requestLatency.time();
|
||||
final Stopwatch timer = Stopwatch.createStarted();
|
||||
try {
|
||||
uow.recordCacheAndDatabaseOperationCount(0, 1);
|
||||
ResultSet resultSet = this.execute(sessionOps, uow, traceContext, queryExecutionTimeout, queryTimeoutUnits, showValues, false);
|
||||
ResultSet resultSet =
|
||||
this.execute(
|
||||
sessionOps,
|
||||
uow,
|
||||
traceContext,
|
||||
queryExecutionTimeout,
|
||||
queryTimeoutUnits,
|
||||
showValues,
|
||||
false);
|
||||
if (!resultSet.wasApplied()) {
|
||||
throw new HelenusException("Failed to apply batch.");
|
||||
}
|
||||
|
@ -110,9 +125,15 @@ public class BatchOperation extends Operation<Long> {
|
|||
public String toString(boolean showValues) {
|
||||
StringBuilder s = new StringBuilder();
|
||||
s.append("BEGIN ");
|
||||
if (!logged) { s.append("UN"); }
|
||||
if (!logged) {
|
||||
s.append("UN");
|
||||
}
|
||||
s.append("LOGGED BATCH; ");
|
||||
s.append(operations.stream().map(o -> Operation.queryString(o.buildStatement(showValues), showValues)).collect(Collectors.joining(" ")));
|
||||
s.append(
|
||||
operations
|
||||
.stream()
|
||||
.map(o -> Operation.queryString(o.buildStatement(showValues), showValues))
|
||||
.collect(Collectors.joining(" ")));
|
||||
s.append(" APPLY BATCH;");
|
||||
return s.toString();
|
||||
}
|
||||
|
|
|
@ -19,6 +19,10 @@ import com.datastax.driver.core.ResultSet;
|
|||
import com.datastax.driver.core.querybuilder.BuiltStatement;
|
||||
import com.datastax.driver.core.querybuilder.Insert;
|
||||
import com.datastax.driver.core.querybuilder.QueryBuilder;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import net.helenus.core.AbstractSessionOperations;
|
||||
import net.helenus.core.Getter;
|
||||
import net.helenus.core.Helenus;
|
||||
|
@ -38,14 +42,10 @@ import net.helenus.support.Fun;
|
|||
import net.helenus.support.HelenusException;
|
||||
import net.helenus.support.HelenusMappingException;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public final class InsertOperation<T> extends AbstractOperation<T, InsertOperation<T>> {
|
||||
|
||||
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 final T pojo;
|
||||
private final Class<?> resultType;
|
||||
private HelenusEntity entity;
|
||||
|
@ -63,7 +63,11 @@ public final class InsertOperation<T> extends AbstractOperation<T, InsertOperati
|
|||
this.resultType = ResultSet.class;
|
||||
}
|
||||
|
||||
public InsertOperation(AbstractSessionOperations sessionOperations, HelenusEntity entity, Class<?> resultType, boolean ifNotExists) {
|
||||
public InsertOperation(
|
||||
AbstractSessionOperations sessionOperations,
|
||||
HelenusEntity entity,
|
||||
Class<?> resultType,
|
||||
boolean ifNotExists) {
|
||||
super(sessionOperations);
|
||||
|
||||
this.ifNotExists = ifNotExists;
|
||||
|
@ -72,7 +76,8 @@ public final class InsertOperation<T> extends AbstractOperation<T, InsertOperati
|
|||
this.entity = entity;
|
||||
}
|
||||
|
||||
public InsertOperation(AbstractSessionOperations sessionOperations, Class<?> resultType, boolean ifNotExists) {
|
||||
public InsertOperation(
|
||||
AbstractSessionOperations sessionOperations, Class<?> resultType, boolean ifNotExists) {
|
||||
super(sessionOperations);
|
||||
|
||||
this.ifNotExists = ifNotExists;
|
||||
|
@ -80,8 +85,12 @@ public final class InsertOperation<T> extends AbstractOperation<T, InsertOperati
|
|||
this.resultType = resultType;
|
||||
}
|
||||
|
||||
public InsertOperation(AbstractSessionOperations sessionOperations, HelenusEntity entity, T pojo,
|
||||
Set<String> mutations, boolean ifNotExists) {
|
||||
public InsertOperation(
|
||||
AbstractSessionOperations sessionOperations,
|
||||
HelenusEntity entity,
|
||||
T pojo,
|
||||
Set<String> mutations,
|
||||
boolean ifNotExists) {
|
||||
super(sessionOperations);
|
||||
|
||||
this.entity = entity;
|
||||
|
@ -144,16 +153,28 @@ public final class InsertOperation<T> extends AbstractOperation<T, InsertOperati
|
|||
|
||||
@Override
|
||||
public BuiltStatement buildStatement(boolean cached) {
|
||||
List<HelenusEntity> entities = values.stream().map(t -> t._1.getProperty().getEntity()).distinct().collect(Collectors.toList());
|
||||
List<HelenusEntity> entities =
|
||||
values
|
||||
.stream()
|
||||
.map(t -> t._1.getProperty().getEntity())
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
if (entities.size() != 1) {
|
||||
throw new HelenusMappingException("you can insert only single entity at a time, found: "
|
||||
+ entities.stream().map(e -> e.getMappingInterface().toString()).collect(Collectors.joining(", ")));
|
||||
throw new HelenusMappingException(
|
||||
"you can insert only single entity at a time, found: "
|
||||
+ entities
|
||||
.stream()
|
||||
.map(e -> e.getMappingInterface().toString())
|
||||
.collect(Collectors.joining(", ")));
|
||||
}
|
||||
HelenusEntity entity = entities.get(0);
|
||||
if (this.entity != null) {
|
||||
if (this.entity != entity) {
|
||||
throw new HelenusMappingException("you can insert only single entity at a time, found: " +
|
||||
this.entity.getMappingInterface().toString() + ", " + entity.getMappingInterface().toString());
|
||||
throw new HelenusMappingException(
|
||||
"you can insert only single entity at a time, found: "
|
||||
+ this.entity.getMappingInterface().toString()
|
||||
+ ", "
|
||||
+ entity.getMappingInterface().toString());
|
||||
}
|
||||
} else {
|
||||
this.entity = entity;
|
||||
|
@ -203,8 +224,8 @@ public final class InsertOperation<T> extends AbstractOperation<T, InsertOperati
|
|||
if (backingMap.containsKey(key)) {
|
||||
// Some values man need to be converted (e.g. from String to Enum). This is done
|
||||
// within the BeanColumnValueProvider below.
|
||||
Optional<Function<Object, Object>> converter = prop.getReadConverter(
|
||||
sessionOps.getSessionRepository());
|
||||
Optional<Function<Object, Object>> converter =
|
||||
prop.getReadConverter(sessionOps.getSessionRepository());
|
||||
if (converter.isPresent()) {
|
||||
backingMap.put(key, converter.get().apply(backingMap.get(key)));
|
||||
}
|
||||
|
@ -212,7 +233,8 @@ public final class InsertOperation<T> extends AbstractOperation<T, InsertOperati
|
|||
// If we started this operation with an instance of this type, use values from
|
||||
// that.
|
||||
if (pojo != null) {
|
||||
backingMap.put(key, BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop, immutable));
|
||||
backingMap.put(
|
||||
key, BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop, immutable));
|
||||
} else {
|
||||
// Otherwise we'll use default values for the property type if available.
|
||||
Class<?> propType = prop.getJavaType();
|
||||
|
@ -265,9 +287,12 @@ public final class InsertOperation<T> extends AbstractOperation<T, InsertOperati
|
|||
|
||||
protected void adjustTtlAndWriteTime(MapExportable pojo) {
|
||||
if (ttl != null || writeTime != 0L) {
|
||||
List<String> columnNames = values.stream()
|
||||
List<String> columnNames =
|
||||
values
|
||||
.stream()
|
||||
.map(t -> t._1.getProperty())
|
||||
.filter(prop -> {
|
||||
.filter(
|
||||
prop -> {
|
||||
switch (prop.getColumnType()) {
|
||||
case PARTITION_KEY:
|
||||
case CLUSTERING_COLUMN:
|
||||
|
@ -294,7 +319,7 @@ public final class InsertOperation<T> extends AbstractOperation<T, InsertOperati
|
|||
public T sync() throws TimeoutException {
|
||||
T result = super.sync();
|
||||
if (entity.isCacheable() && result != null) {
|
||||
adjustTtlAndWriteTime((MapExportable)result);
|
||||
adjustTtlAndWriteTime((MapExportable) result);
|
||||
sessionOps.updateCache(result, bindFacetValues());
|
||||
}
|
||||
return result;
|
||||
|
|
|
@ -92,8 +92,15 @@ public abstract class Operation<E> {
|
|||
return query;
|
||||
}
|
||||
|
||||
public ResultSet execute(AbstractSessionOperations session, UnitOfWork uow, TraceContext traceContext,
|
||||
long timeout, TimeUnit units, boolean showValues, boolean cached) throws TimeoutException {
|
||||
public ResultSet execute(
|
||||
AbstractSessionOperations session,
|
||||
UnitOfWork uow,
|
||||
TraceContext traceContext,
|
||||
long timeout,
|
||||
TimeUnit units,
|
||||
boolean showValues,
|
||||
boolean cached)
|
||||
throws TimeoutException {
|
||||
|
||||
// Start recording in a Zipkin sub-span our execution time to perform this operation.
|
||||
Tracer tracer = session.getZipkinTracer();
|
||||
|
@ -111,11 +118,17 @@ public abstract class Operation<E> {
|
|||
|
||||
Statement statement = options(buildStatement(cached));
|
||||
|
||||
if (session.isShowCql() ) {
|
||||
String stmt = (this instanceof BatchOperation) ? queryString((BatchOperation)this, showValues) : queryString(statement, showValues);
|
||||
if (session.isShowCql()) {
|
||||
String stmt =
|
||||
(this instanceof BatchOperation)
|
||||
? queryString((BatchOperation) this, showValues)
|
||||
: queryString(statement, showValues);
|
||||
session.getPrintStream().println(stmt);
|
||||
} else if (LOG.isDebugEnabled()) {
|
||||
String stmt = (this instanceof BatchOperation) ? queryString((BatchOperation)this, showValues) : queryString(statement, showValues);
|
||||
String stmt =
|
||||
(this instanceof BatchOperation)
|
||||
? queryString((BatchOperation) this, showValues)
|
||||
: queryString(statement, showValues);
|
||||
LOG.info("CQL> " + stmt);
|
||||
}
|
||||
|
||||
|
@ -135,7 +148,9 @@ public abstract class Operation<E> {
|
|||
.map(InetAddress::toString)
|
||||
.collect(Collectors.joining(", "));
|
||||
ConsistencyLevel cl = ei.getAchievedConsistencyLevel();
|
||||
if (cl == null) { cl = statement.getConsistencyLevel(); }
|
||||
if (cl == null) {
|
||||
cl = statement.getConsistencyLevel();
|
||||
}
|
||||
int se = ei.getSpeculativeExecutions();
|
||||
String warn = ei.getWarnings().stream().collect(Collectors.joining(", "));
|
||||
String ri =
|
||||
|
@ -148,7 +163,8 @@ public abstract class Operation<E> {
|
|||
qh.getRack(),
|
||||
(cl != null)
|
||||
? (" consistency: "
|
||||
+ cl.name() + " "
|
||||
+ cl.name()
|
||||
+ " "
|
||||
+ (cl.isDCLocal() ? " DC " : "")
|
||||
+ (cl.isSerial() ? " SC " : ""))
|
||||
: "",
|
||||
|
@ -188,7 +204,8 @@ public abstract class Operation<E> {
|
|||
timerString = String.format(" %s ", timer.toString());
|
||||
}
|
||||
LOG.info(
|
||||
String.format("%s%s%s", uowString, timerString, Operation.queryString(statement, showValues)));
|
||||
String.format(
|
||||
"%s%s%s", uowString, timerString, Operation.queryString(statement, showValues)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -65,5 +65,7 @@ public final class SelectFirstOperation<E>
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean ignoreCache() { return delegate.ignoreCache(); }
|
||||
public boolean ignoreCache() {
|
||||
return delegate.ignoreCache();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,5 +58,7 @@ public final class SelectFirstTransformingOperation<R, E>
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean ignoreCache() { return delegate.ignoreCache(); }
|
||||
public boolean ignoreCache() {
|
||||
return delegate.ignoreCache();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,7 +23,6 @@ import com.datastax.driver.core.querybuilder.QueryBuilder;
|
|||
import com.datastax.driver.core.querybuilder.Select;
|
||||
import com.datastax.driver.core.querybuilder.Select.Selection;
|
||||
import com.datastax.driver.core.querybuilder.Select.Where;
|
||||
import com.google.common.collect.Iterables;
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Stream;
|
||||
|
@ -97,7 +96,10 @@ public final class SelectOperation<E> extends AbstractFilterStreamOperation<E, S
|
|||
this.implementsEntityType = Entity.class.isAssignableFrom(entity.getMappingInterface());
|
||||
}
|
||||
|
||||
public SelectOperation(AbstractSessionOperations sessionOperations, HelenusEntity entity, Function<Row, E> rowMapper) {
|
||||
public SelectOperation(
|
||||
AbstractSessionOperations sessionOperations,
|
||||
HelenusEntity entity,
|
||||
Function<Row, E> rowMapper) {
|
||||
|
||||
super(sessionOperations);
|
||||
this.rowMapper = rowMapper;
|
||||
|
@ -112,7 +114,9 @@ public final class SelectOperation<E> extends AbstractFilterStreamOperation<E, S
|
|||
this.implementsEntityType = Entity.class.isAssignableFrom(entity.getMappingInterface());
|
||||
}
|
||||
|
||||
public SelectOperation(AbstractSessionOperations sessionOperations, Function<Row, E> rowMapper,
|
||||
public SelectOperation(
|
||||
AbstractSessionOperations sessionOperations,
|
||||
Function<Row, E> rowMapper,
|
||||
HelenusPropertyNode... props) {
|
||||
|
||||
super(sessionOperations);
|
||||
|
@ -310,7 +314,9 @@ public final class SelectOperation<E> extends AbstractFilterStreamOperation<E, S
|
|||
for (Filter<?> filter : filters.values()) {
|
||||
where.and(filter.getClause(sessionOps.getValuePreparer()));
|
||||
HelenusProperty filterProp = filter.getNode().getProperty();
|
||||
HelenusProperty prop = props.stream()
|
||||
HelenusProperty prop =
|
||||
props
|
||||
.stream()
|
||||
.map(HelenusPropertyNode::getProperty)
|
||||
.filter(thisProp -> thisProp.getPropertyName().equals(filterProp.getPropertyName()))
|
||||
.findFirst()
|
||||
|
|
|
@ -58,8 +58,12 @@ public final class SelectTransformingOperation<R, E>
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean isSessionCacheable() { return delegate.isSessionCacheable(); }
|
||||
public boolean isSessionCacheable() {
|
||||
return delegate.isSessionCacheable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean ignoreCache() { return delegate.ignoreCache(); }
|
||||
public boolean ignoreCache() {
|
||||
return delegate.ignoreCache();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,13 +34,10 @@ import net.helenus.mapping.HelenusEntity;
|
|||
import net.helenus.mapping.HelenusProperty;
|
||||
import net.helenus.mapping.MappingUtil;
|
||||
import net.helenus.mapping.value.BeanColumnValueProvider;
|
||||
import net.helenus.mapping.value.ValueProviderMap;
|
||||
import net.helenus.support.HelenusException;
|
||||
import net.helenus.support.HelenusMappingException;
|
||||
import net.helenus.support.Immutables;
|
||||
|
||||
import static net.helenus.mapping.ColumnType.CLUSTERING_COLUMN;
|
||||
import static net.helenus.mapping.ColumnType.PARTITION_KEY;
|
||||
|
||||
public final class UpdateOperation<E> extends AbstractFilterOperation<E, UpdateOperation<E>> {
|
||||
|
||||
|
@ -110,7 +107,7 @@ public final class UpdateOperation<E> extends AbstractFilterOperation<E, UpdateO
|
|||
if (pojo != null) {
|
||||
if (!BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop).equals(v)) {
|
||||
String key = prop.getPropertyName();
|
||||
((MapExportable)pojo).put(key, v);
|
||||
((MapExportable) pojo).put(key, v);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -421,7 +418,8 @@ public final class UpdateOperation<E> extends AbstractFilterOperation<E, UpdateO
|
|||
|
||||
Object valueObj = value;
|
||||
|
||||
Optional<Function<Object, Object>> converter = prop.getWriteConverter(sessionOps.getSessionRepository());
|
||||
Optional<Function<Object, Object>> converter =
|
||||
prop.getWriteConverter(sessionOps.getSessionRepository());
|
||||
if (converter.isPresent()) {
|
||||
List convertedList = (List) converter.get().apply(Immutables.listOf(value));
|
||||
valueObj = convertedList.get(0);
|
||||
|
@ -436,7 +434,8 @@ public final class UpdateOperation<E> extends AbstractFilterOperation<E, UpdateO
|
|||
|
||||
List valueObj = value;
|
||||
|
||||
Optional<Function<Object, Object>> converter = prop.getWriteConverter(sessionOps.getSessionRepository());
|
||||
Optional<Function<Object, Object>> converter =
|
||||
prop.getWriteConverter(sessionOps.getSessionRepository());
|
||||
if (converter.isPresent()) {
|
||||
valueObj = (List) converter.get().apply(value);
|
||||
}
|
||||
|
@ -581,7 +580,8 @@ public final class UpdateOperation<E> extends AbstractFilterOperation<E, UpdateO
|
|||
HelenusProperty prop = p.getProperty();
|
||||
Object valueObj = value;
|
||||
|
||||
Optional<Function<Object, Object>> converter = prop.getWriteConverter(sessionOps.getSessionRepository());
|
||||
Optional<Function<Object, Object>> converter =
|
||||
prop.getWriteConverter(sessionOps.getSessionRepository());
|
||||
if (converter.isPresent()) {
|
||||
Set convertedSet = (Set) converter.get().apply(Immutables.setOf(value));
|
||||
valueObj = convertedSet.iterator().next();
|
||||
|
@ -595,7 +595,8 @@ public final class UpdateOperation<E> extends AbstractFilterOperation<E, UpdateO
|
|||
HelenusProperty prop = p.getProperty();
|
||||
Set valueObj = value;
|
||||
|
||||
Optional<Function<Object, Object>> converter = prop.getWriteConverter(sessionOps.getSessionRepository());
|
||||
Optional<Function<Object, Object>> converter =
|
||||
prop.getWriteConverter(sessionOps.getSessionRepository());
|
||||
if (converter.isPresent()) {
|
||||
valueObj = (Set) converter.get().apply(value);
|
||||
}
|
||||
|
@ -634,9 +635,11 @@ public final class UpdateOperation<E> extends AbstractFilterOperation<E, UpdateO
|
|||
facet = null;
|
||||
}
|
||||
|
||||
Optional<Function<Object, Object>> converter = prop.getWriteConverter(sessionOps.getSessionRepository());
|
||||
Optional<Function<Object, Object>> converter =
|
||||
prop.getWriteConverter(sessionOps.getSessionRepository());
|
||||
if (converter.isPresent()) {
|
||||
Map<Object, Object> convertedMap = (Map<Object, Object>) converter.get().apply(Immutables.mapOf(key, value));
|
||||
Map<Object, Object> convertedMap =
|
||||
(Map<Object, Object>) converter.get().apply(Immutables.mapOf(key, value));
|
||||
for (Map.Entry<Object, Object> e : convertedMap.entrySet()) {
|
||||
assignments.put(QueryBuilder.put(p.getColumnName(), e.getKey(), e.getValue()), facet);
|
||||
}
|
||||
|
@ -672,7 +675,8 @@ public final class UpdateOperation<E> extends AbstractFilterOperation<E, UpdateO
|
|||
facet = null;
|
||||
}
|
||||
|
||||
Optional<Function<Object, Object>> converter = prop.getWriteConverter(sessionOps.getSessionRepository());
|
||||
Optional<Function<Object, Object>> converter =
|
||||
prop.getWriteConverter(sessionOps.getSessionRepository());
|
||||
if (converter.isPresent()) {
|
||||
Map convertedMap = (Map) converter.get().apply(map);
|
||||
assignments.put(QueryBuilder.putAll(p.getColumnName(), convertedMap), facet);
|
||||
|
@ -789,7 +793,7 @@ public final class UpdateOperation<E> extends AbstractFilterOperation<E, UpdateO
|
|||
adjustTtlAndWriteTime(draft);
|
||||
} else if (pojo != null) {
|
||||
sessionOps.updateCache(pojo, bindFacetValues());
|
||||
adjustTtlAndWriteTime((MapExportable)pojo);
|
||||
adjustTtlAndWriteTime((MapExportable) pojo);
|
||||
} else {
|
||||
sessionOps.cacheEvict(bindFacetValues());
|
||||
}
|
||||
|
@ -811,7 +815,7 @@ public final class UpdateOperation<E> extends AbstractFilterOperation<E, UpdateO
|
|||
cacheUpdate(uow, result, bindFacetValues());
|
||||
} else if (pojo != null) {
|
||||
cacheUpdate(uow, (E) pojo, bindFacetValues());
|
||||
adjustTtlAndWriteTime((MapExportable)pojo);
|
||||
adjustTtlAndWriteTime((MapExportable) pojo);
|
||||
return (E) pojo;
|
||||
}
|
||||
return result;
|
||||
|
@ -828,7 +832,7 @@ public final class UpdateOperation<E> extends AbstractFilterOperation<E, UpdateO
|
|||
adjustTtlAndWriteTime(draft);
|
||||
} else if (pojo != null) {
|
||||
result = (E) pojo;
|
||||
adjustTtlAndWriteTime((MapExportable)pojo);
|
||||
adjustTtlAndWriteTime((MapExportable) pojo);
|
||||
} else {
|
||||
result = null;
|
||||
}
|
||||
|
|
|
@ -21,9 +21,19 @@ public interface Entity {
|
|||
String WRITTEN_AT_METHOD = "writtenAt";
|
||||
String TTL_OF_METHOD = "ttlOf";
|
||||
|
||||
default Long writtenAt(Getter getter) { return 0L; }
|
||||
default Long writtenAt(String prop) { return 0L; };
|
||||
default Long writtenAt(Getter getter) {
|
||||
return 0L;
|
||||
}
|
||||
|
||||
default Integer ttlOf(Getter getter) { return 0; };
|
||||
default Integer ttlOf(String prop) {return 0; };
|
||||
default Long writtenAt(String prop) {
|
||||
return 0L;
|
||||
};
|
||||
|
||||
default Integer ttlOf(Getter getter) {
|
||||
return 0;
|
||||
};
|
||||
|
||||
default Integer ttlOf(String prop) {
|
||||
return 0;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -15,17 +15,20 @@
|
|||
*/
|
||||
package net.helenus.core.reflect;
|
||||
|
||||
import net.helenus.core.Getter;
|
||||
|
||||
import java.util.Map;
|
||||
import net.helenus.core.Getter;
|
||||
|
||||
public interface MapExportable {
|
||||
String TO_MAP_METHOD = "toMap";
|
||||
String PUT_METHOD = "put";
|
||||
|
||||
Map<String, Object> toMap();
|
||||
default Map<String, Object> toMap(boolean mutable) { return null; }
|
||||
default void put(String key, Object value) { }
|
||||
default <T> void put(Getter<T> getter, T value) { }
|
||||
|
||||
default Map<String, Object> toMap(boolean mutable) {
|
||||
return null;
|
||||
}
|
||||
|
||||
default void put(String key, Object value) {}
|
||||
|
||||
default <T> void put(Getter<T> getter, T value) {}
|
||||
}
|
||||
|
|
|
@ -15,14 +15,6 @@
|
|||
*/
|
||||
package net.helenus.core.reflect;
|
||||
|
||||
import net.helenus.core.Getter;
|
||||
import net.helenus.core.Helenus;
|
||||
import net.helenus.core.cache.CacheUtil;
|
||||
import net.helenus.mapping.MappingUtil;
|
||||
import net.helenus.mapping.annotation.Transient;
|
||||
import net.helenus.mapping.value.ValueProviderMap;
|
||||
import net.helenus.support.HelenusException;
|
||||
|
||||
import java.io.InvalidObjectException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectStreamException;
|
||||
|
@ -36,6 +28,13 @@ import java.util.Collections;
|
|||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import net.helenus.core.Getter;
|
||||
import net.helenus.core.Helenus;
|
||||
import net.helenus.core.cache.CacheUtil;
|
||||
import net.helenus.mapping.MappingUtil;
|
||||
import net.helenus.mapping.annotation.Transient;
|
||||
import net.helenus.mapping.value.ValueProviderMap;
|
||||
import net.helenus.support.HelenusException;
|
||||
|
||||
public class MapperInvocationHandler<E> implements InvocationHandler, Serializable {
|
||||
private static final long serialVersionUID = -7044209982830584984L;
|
||||
|
@ -101,7 +100,7 @@ public class MapperInvocationHandler<E> implements InvocationHandler, Serializab
|
|||
}
|
||||
}
|
||||
if (otherObj instanceof MapExportable) {
|
||||
return MappingUtil.compareMaps((MapExportable)otherObj, src);
|
||||
return MappingUtil.compareMaps((MapExportable) otherObj, src);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -111,7 +110,7 @@ public class MapperInvocationHandler<E> implements InvocationHandler, Serializab
|
|||
if (args[0] instanceof String) {
|
||||
key = (String) args[0];
|
||||
} else if (args[0] instanceof Getter) {
|
||||
key = MappingUtil.resolveMappingProperty((Getter)args[0]).getProperty().getPropertyName();
|
||||
key = MappingUtil.resolveMappingProperty((Getter) args[0]).getProperty().getPropertyName();
|
||||
} else {
|
||||
key = null;
|
||||
}
|
||||
|
@ -128,14 +127,19 @@ public class MapperInvocationHandler<E> implements InvocationHandler, Serializab
|
|||
if (Entity.WRITTEN_AT_METHOD.equals(methodName) && method.getParameterCount() == 1) {
|
||||
final String key;
|
||||
if (args[0] instanceof String) {
|
||||
key = CacheUtil.writeTimeKey((String)args[0]);
|
||||
key = CacheUtil.writeTimeKey((String) args[0]);
|
||||
} else if (args[0] instanceof Getter) {
|
||||
Getter getter = (Getter)args[0];
|
||||
key = CacheUtil.writeTimeKey(MappingUtil.resolveMappingProperty(getter).getProperty().getColumnName().toCql(false));
|
||||
Getter getter = (Getter) args[0];
|
||||
key =
|
||||
CacheUtil.writeTimeKey(
|
||||
MappingUtil.resolveMappingProperty(getter)
|
||||
.getProperty()
|
||||
.getColumnName()
|
||||
.toCql(false));
|
||||
} else {
|
||||
return 0L;
|
||||
}
|
||||
Long v = (Long)src.get(key);
|
||||
Long v = (Long) src.get(key);
|
||||
if (v != null) {
|
||||
return v;
|
||||
}
|
||||
|
@ -145,14 +149,19 @@ public class MapperInvocationHandler<E> implements InvocationHandler, Serializab
|
|||
if (Entity.TTL_OF_METHOD.equals(methodName) && method.getParameterCount() == 1) {
|
||||
final String key;
|
||||
if (args[0] instanceof String) {
|
||||
key = CacheUtil.ttlKey((String)args[0]);
|
||||
key = CacheUtil.ttlKey((String) args[0]);
|
||||
} else if (args[0] instanceof Getter) {
|
||||
Getter getter = (Getter)args[0];
|
||||
key = CacheUtil.ttlKey(MappingUtil.resolveMappingProperty(getter).getProperty().getColumnName().toCql(false));
|
||||
Getter getter = (Getter) args[0];
|
||||
key =
|
||||
CacheUtil.ttlKey(
|
||||
MappingUtil.resolveMappingProperty(getter)
|
||||
.getProperty()
|
||||
.getColumnName()
|
||||
.toCql(false));
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
int v[] = (int[])src.get(key);
|
||||
int v[] = (int[]) src.get(key);
|
||||
if (v != null) {
|
||||
return v[0];
|
||||
}
|
||||
|
@ -185,7 +194,9 @@ public class MapperInvocationHandler<E> implements InvocationHandler, Serializab
|
|||
|
||||
if (MapExportable.TO_MAP_METHOD.equals(methodName)) {
|
||||
if (method.getParameterCount() == 1 && args[0] instanceof Boolean) {
|
||||
if ((boolean)args[0] == true) { return src; }
|
||||
if ((boolean) args[0] == true) {
|
||||
return src;
|
||||
}
|
||||
}
|
||||
return Collections.unmodifiableMap(src);
|
||||
}
|
||||
|
|
|
@ -117,7 +117,8 @@ public final class HelenusMappingEntity implements HelenusEntity {
|
|||
if (iface.getDeclaredAnnotation(MaterializedView.class) == null) {
|
||||
facetsBuilder.add(new Facet("table", name.toCql()).setFixed());
|
||||
} else {
|
||||
facetsBuilder.add(new Facet("table", Helenus.entity(iface.getInterfaces()[0]).getName().toCql())
|
||||
facetsBuilder.add(
|
||||
new Facet("table", Helenus.entity(iface.getInterfaces()[0]).getName().toCql())
|
||||
.setFixed());
|
||||
}
|
||||
for (HelenusProperty prop : orderedProps) {
|
||||
|
@ -131,7 +132,8 @@ public final class HelenusMappingEntity implements HelenusEntity {
|
|||
facetsBuilder.add(new UnboundFacet(primaryKeyProperties));
|
||||
primaryKeyProperties = null;
|
||||
}
|
||||
for (ConstraintValidator<?, ?> constraint : MappingUtil.getValidators(prop.getGetterMethod())) {
|
||||
for (ConstraintValidator<?, ?> constraint :
|
||||
MappingUtil.getValidators(prop.getGetterMethod())) {
|
||||
if (constraint.getClass().isAssignableFrom(DistinctValidator.class)) {
|
||||
DistinctValidator validator = (DistinctValidator) constraint;
|
||||
String[] values = validator.constraintAnnotation.value();
|
||||
|
|
|
@ -129,9 +129,13 @@ public final class MappingUtil {
|
|||
}
|
||||
|
||||
public static HelenusProperty getPropertyForColumn(HelenusEntity entity, String name) {
|
||||
if (name == null)
|
||||
return null;
|
||||
return entity.getOrderedProperties().stream().filter(p -> p.getColumnName().equals(name)).findFirst().orElse(null);
|
||||
if (name == null) return null;
|
||||
return entity
|
||||
.getOrderedProperties()
|
||||
.stream()
|
||||
.filter(p -> p.getColumnName().equals(name))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
public static String getDefaultColumnName(Method getter) {
|
||||
|
@ -331,22 +335,24 @@ public final class MappingUtil {
|
|||
|
||||
public static boolean compareMaps(MapExportable me, Map<String, Object> m2) {
|
||||
Map<String, Object> m1 = me.toMap();
|
||||
List<String> matching = m2.entrySet()
|
||||
List<String> matching =
|
||||
m2.entrySet()
|
||||
.stream()
|
||||
.filter(e -> !e.getKey().matches("^_.*_(ttl|writeTime)$"))
|
||||
.filter(e -> {
|
||||
.filter(
|
||||
e -> {
|
||||
String k = e.getKey();
|
||||
if (m1.containsKey(k)) {
|
||||
Object o1 = e.getValue();
|
||||
Object o2 = m1.get(k);
|
||||
if (o1 == o2 || o1.equals(o2))
|
||||
return true;
|
||||
if (o1 == o2 || o1.equals(o2)) return true;
|
||||
}
|
||||
return false;
|
||||
})
|
||||
.map(e -> e.getKey())
|
||||
.collect(Collectors.toList());
|
||||
List<String> divergent = m1.entrySet()
|
||||
List<String> divergent =
|
||||
m1.entrySet()
|
||||
.stream()
|
||||
.filter(e -> !e.getKey().matches("^_.*_(ttl|writeTime)$"))
|
||||
.filter(e -> !matching.contains(e.getKey()))
|
||||
|
@ -354,5 +360,4 @@ public final class MappingUtil {
|
|||
.collect(Collectors.toList());
|
||||
return divergent.size() > 0 ? false : true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -238,7 +238,6 @@ public final class Constraints {
|
|||
boolean alone() default true;
|
||||
|
||||
boolean combined() default true;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -48,5 +48,4 @@ public final class DistinctValidator
|
|||
public boolean combined() {
|
||||
return annotation == null ? true : annotation.combined();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -25,7 +25,8 @@ public enum BeanColumnValueProvider implements ColumnValueProvider {
|
|||
INSTANCE;
|
||||
|
||||
@Override
|
||||
public <V> V getColumnValue(Object bean, int columnIndexUnused, HelenusProperty property, boolean immutable) {
|
||||
public <V> V getColumnValue(
|
||||
Object bean, int columnIndexUnused, HelenusProperty property, boolean immutable) {
|
||||
|
||||
Method getter = property.getGetterMethod();
|
||||
|
||||
|
|
|
@ -40,7 +40,8 @@ public final class RowColumnValueProvider implements ColumnValueProvider {
|
|||
}
|
||||
|
||||
@Override
|
||||
public <V> V getColumnValue(Object sourceObj, int columnIndex, HelenusProperty property, boolean immutable) {
|
||||
public <V> V getColumnValue(
|
||||
Object sourceObj, int columnIndex, HelenusProperty property, boolean immutable) {
|
||||
|
||||
Row source = (Row) sourceObj;
|
||||
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
package net.helenus.mapping.value;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
@ -154,8 +153,9 @@ public final class ValueProviderMap implements Map<String, Object> {
|
|||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || !(o.getClass().isAssignableFrom(Map.class) || o.getClass().getSimpleName().equals("UnmodifiableMap")))
|
||||
return false;
|
||||
if (o == null
|
||||
|| !(o.getClass().isAssignableFrom(Map.class)
|
||||
|| o.getClass().getSimpleName().equals("UnmodifiableMap"))) return false;
|
||||
|
||||
Map that = (Map) o;
|
||||
if (this.size() != that.size()) return false;
|
||||
|
|
|
@ -79,7 +79,8 @@ public class EntityDraftBuilderTest extends AbstractEmbeddedCassandraTest {
|
|||
@Test
|
||||
public void testFoo() throws Exception {
|
||||
|
||||
Supply s1 = session
|
||||
Supply s1 =
|
||||
session
|
||||
.<Supply>select(Supply.class)
|
||||
.where(supply::id, eq(id))
|
||||
.and(supply::region, eq(region))
|
||||
|
@ -88,7 +89,8 @@ public class EntityDraftBuilderTest extends AbstractEmbeddedCassandraTest {
|
|||
.orElse(null);
|
||||
|
||||
// List
|
||||
Supply s2 = session
|
||||
Supply s2 =
|
||||
session
|
||||
.<Supply>update(s1.update())
|
||||
.and(supply::region, eq(region))
|
||||
.prepend(supply::suppliers, "Pignose Supply, LLC.")
|
||||
|
@ -111,7 +113,8 @@ public class EntityDraftBuilderTest extends AbstractEmbeddedCassandraTest {
|
|||
Supply s1, s2, s3, s4, s5;
|
||||
Supply.Draft d1;
|
||||
|
||||
s1 = session
|
||||
s1 =
|
||||
session
|
||||
.<Supply>select(Supply.class)
|
||||
.where(supply::id, eq(id))
|
||||
.and(supply::region, eq(region))
|
||||
|
@ -119,8 +122,9 @@ public class EntityDraftBuilderTest extends AbstractEmbeddedCassandraTest {
|
|||
.sync()
|
||||
.orElse(null);
|
||||
|
||||
try(UnitOfWork uow1 = session.begin()) {
|
||||
s2 = session
|
||||
try (UnitOfWork uow1 = session.begin()) {
|
||||
s2 =
|
||||
session
|
||||
.<Supply>select(Supply.class)
|
||||
.where(supply::id, eq(id))
|
||||
.and(supply::region, eq(region))
|
||||
|
@ -128,8 +132,9 @@ public class EntityDraftBuilderTest extends AbstractEmbeddedCassandraTest {
|
|||
.sync(uow1)
|
||||
.orElse(null);
|
||||
|
||||
try(UnitOfWork uow2 = session.begin(uow1)) {
|
||||
s3 = session
|
||||
try (UnitOfWork uow2 = session.begin(uow1)) {
|
||||
s3 =
|
||||
session
|
||||
.<Supply>select(Supply.class)
|
||||
.where(supply::id, eq(id))
|
||||
.and(supply::region, eq(region))
|
||||
|
@ -137,18 +142,16 @@ public class EntityDraftBuilderTest extends AbstractEmbeddedCassandraTest {
|
|||
.sync(uow2)
|
||||
.orElse(null);
|
||||
|
||||
d1 = s3.update()
|
||||
.setCode("WIDGET-002-UPDATED");
|
||||
d1 = s3.update().setCode("WIDGET-002-UPDATED");
|
||||
|
||||
s4 = session.update(d1)
|
||||
.usingTtl(20)
|
||||
.defaultTimestamp(System.currentTimeMillis())
|
||||
.sync(uow2);
|
||||
s4 =
|
||||
session.update(d1).usingTtl(20).defaultTimestamp(System.currentTimeMillis()).sync(uow2);
|
||||
|
||||
uow2.commit();
|
||||
}
|
||||
|
||||
s5 = session
|
||||
s5 =
|
||||
session
|
||||
.<Supply>select(Supply.class)
|
||||
.where(supply::id, eq(id))
|
||||
.and(supply::region, eq(region))
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package net.helenus.test.integration.core.draft;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import net.helenus.core.AbstractAuditedEntityDraft;
|
||||
import net.helenus.core.Helenus;
|
||||
|
@ -92,6 +91,5 @@ public interface Inventory extends Entity, Drafted<Inventory> {
|
|||
mutate(inventory::NORAM, count);
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -208,12 +208,8 @@ public class SimpleUserTest extends AbstractEmbeddedCassandraTest {
|
|||
}
|
||||
|
||||
public void testFunTuple() throws TimeoutException {
|
||||
Fun.Tuple1<String> tf = session
|
||||
.select(user::name)
|
||||
.where(user::id, eq(100L))
|
||||
.single()
|
||||
.sync()
|
||||
.orElse(null);
|
||||
Fun.Tuple1<String> tf =
|
||||
session.select(user::name).where(user::id, eq(100L)).single().sync().orElse(null);
|
||||
if (tf != null) {
|
||||
Assert.assertEquals(Fun.class, tf.getClass().getEnclosingClass());
|
||||
String name = tf._1;
|
||||
|
|
|
@ -19,7 +19,6 @@ import static net.helenus.core.Query.eq;
|
|||
|
||||
import com.datastax.driver.core.ConsistencyLevel;
|
||||
import com.datastax.driver.core.utils.UUIDs;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.UUID;
|
||||
import net.bytebuddy.utility.RandomString;
|
||||
|
@ -28,7 +27,6 @@ import net.helenus.core.HelenusSession;
|
|||
import net.helenus.core.UnitOfWork;
|
||||
import net.helenus.core.annotation.Cacheable;
|
||||
import net.helenus.core.reflect.Entity;
|
||||
import net.helenus.core.reflect.MapExportable;
|
||||
import net.helenus.mapping.annotation.Constraints;
|
||||
import net.helenus.mapping.annotation.Index;
|
||||
import net.helenus.mapping.annotation.PartitionKey;
|
||||
|
@ -53,10 +51,10 @@ interface Widget extends Entity {
|
|||
|
||||
String b();
|
||||
|
||||
@Constraints.Distinct(alone=false)
|
||||
@Constraints.Distinct(alone = false)
|
||||
String c();
|
||||
|
||||
@Constraints.Distinct(combined=false)
|
||||
@Constraints.Distinct(combined = false)
|
||||
String d();
|
||||
}
|
||||
|
||||
|
@ -132,7 +130,8 @@ public class UnitOfWorkTest extends AbstractEmbeddedCassandraTest {
|
|||
|
||||
// This should inserted Widget, and not cache it in uow1.
|
||||
try (UnitOfWork uow1 = session.begin()) {
|
||||
w1 = session
|
||||
w1 =
|
||||
session
|
||||
.<Widget>insert(widget)
|
||||
.value(widget::id, key1)
|
||||
.value(widget::name, RandomString.make(20))
|
||||
|
@ -146,7 +145,8 @@ public class UnitOfWorkTest extends AbstractEmbeddedCassandraTest {
|
|||
|
||||
// A "SELECT * FROM widget" query does not contain enough information to fetch an item from cache.
|
||||
// This will miss, until we implement a statement cache.
|
||||
w1a = session
|
||||
w1a =
|
||||
session
|
||||
.<Widget>selectAll(Widget.class)
|
||||
.sync(uow2)
|
||||
.filter(w -> w.id().equals(key1))
|
||||
|
@ -155,7 +155,8 @@ public class UnitOfWorkTest extends AbstractEmbeddedCassandraTest {
|
|||
Assert.assertTrue(w1.equals(w1a));
|
||||
|
||||
// This should read from uow1's cache and return the same Widget.
|
||||
w2 = session
|
||||
w2 =
|
||||
session
|
||||
.<Widget>select(widget)
|
||||
.where(widget::id, eq(key1))
|
||||
.single()
|
||||
|
@ -164,7 +165,8 @@ public class UnitOfWorkTest extends AbstractEmbeddedCassandraTest {
|
|||
|
||||
Assert.assertEquals(w1, w2);
|
||||
|
||||
w3 = session
|
||||
w3 =
|
||||
session
|
||||
.<Widget>insert(widget)
|
||||
.value(widget::id, key2)
|
||||
.value(widget::name, RandomString.make(20))
|
||||
|
@ -182,7 +184,8 @@ public class UnitOfWorkTest extends AbstractEmbeddedCassandraTest {
|
|||
}
|
||||
|
||||
// This should read from the cache and get the same instance of a Widget.
|
||||
w4 = session
|
||||
w4 =
|
||||
session
|
||||
.<Widget>select(widget)
|
||||
.where(widget::a, eq(w3.a()))
|
||||
.and(widget::b, eq(w3.b()))
|
||||
|
@ -261,11 +264,8 @@ public class UnitOfWorkTest extends AbstractEmbeddedCassandraTest {
|
|||
Assert.assertEquals(w1, w2);
|
||||
|
||||
// This should remove the object from the session cache.
|
||||
w3 = session
|
||||
.<Widget>update(w2)
|
||||
.set(widget::name, "Bill")
|
||||
.where(widget::id, eq(key))
|
||||
.sync(uow);
|
||||
w3 =
|
||||
session.<Widget>update(w2).set(widget::name, "Bill").where(widget::id, eq(key)).sync(uow);
|
||||
|
||||
// Fetch from session cache will cache miss (as it was updated) and trigger a SELECT.
|
||||
w4 = session.<Widget>select(widget).where(widget::id, eq(key)).single().sync().orElse(null);
|
||||
|
@ -324,14 +324,15 @@ public class UnitOfWorkTest extends AbstractEmbeddedCassandraTest {
|
|||
try (UnitOfWork uow = session.begin()) {
|
||||
|
||||
// This should read from the database and return a Widget.
|
||||
w2 = session.<Widget>select(widget).where(widget::id, eq(key)).single().sync(uow).orElse(null);
|
||||
w2 =
|
||||
session.<Widget>select(widget).where(widget::id, eq(key)).single().sync(uow).orElse(null);
|
||||
|
||||
// This should remove the object from the cache.
|
||||
session.delete(widget).where(widget::id, eq(key))
|
||||
.sync(uow);
|
||||
session.delete(widget).where(widget::id, eq(key)).sync(uow);
|
||||
|
||||
// This should fail to read from the cache.
|
||||
w3 = session.<Widget>select(widget).where(widget::id, eq(key)).single().sync(uow).orElse(null);
|
||||
w3 =
|
||||
session.<Widget>select(widget).where(widget::id, eq(key)).single().sync(uow).orElse(null);
|
||||
|
||||
Assert.assertEquals(null, w3);
|
||||
|
||||
|
@ -343,13 +344,7 @@ public class UnitOfWorkTest extends AbstractEmbeddedCassandraTest {
|
|||
});
|
||||
}
|
||||
|
||||
w4 =
|
||||
session
|
||||
.<Widget>select(widget)
|
||||
.where(widget::id, eq(key))
|
||||
.single()
|
||||
.sync()
|
||||
.orElse(null);
|
||||
w4 = session.<Widget>select(widget).where(widget::id, eq(key)).single().sync().orElse(null);
|
||||
|
||||
Assert.assertEquals(null, w4);
|
||||
}
|
||||
|
@ -361,7 +356,9 @@ public class UnitOfWorkTest extends AbstractEmbeddedCassandraTest {
|
|||
UUID key = UUIDs.timeBased();
|
||||
|
||||
try (UnitOfWork uow = session.begin()) {
|
||||
w1 = session.<Widget>upsert(widget)
|
||||
w1 =
|
||||
session
|
||||
.<Widget>upsert(widget)
|
||||
.value(widget::id, key)
|
||||
.value(widget::name, RandomString.make(20))
|
||||
.value(widget::a, RandomString.make(10))
|
||||
|
@ -371,7 +368,9 @@ public class UnitOfWorkTest extends AbstractEmbeddedCassandraTest {
|
|||
.batch(uow);
|
||||
Assert.assertTrue(0L == w1.writtenAt(widget::name));
|
||||
Assert.assertTrue(0 == w1.ttlOf(widget::name));
|
||||
w2 = session.<Widget>update(w1)
|
||||
w2 =
|
||||
session
|
||||
.<Widget>update(w1)
|
||||
.set(widget::name, RandomString.make(10))
|
||||
.where(widget::id, eq(key))
|
||||
.usingTtl(30)
|
||||
|
@ -379,7 +378,9 @@ public class UnitOfWorkTest extends AbstractEmbeddedCassandraTest {
|
|||
Assert.assertEquals(w1, w2);
|
||||
Assert.assertTrue(0L == w2.writtenAt(widget::name));
|
||||
Assert.assertTrue(30 == w1.ttlOf(widget::name));
|
||||
w3 = session.<Widget>select(Widget.class)
|
||||
w3 =
|
||||
session
|
||||
.<Widget>select(Widget.class)
|
||||
.where(widget::id, eq(key))
|
||||
.single()
|
||||
.sync(uow)
|
||||
|
@ -388,7 +389,9 @@ public class UnitOfWorkTest extends AbstractEmbeddedCassandraTest {
|
|||
Assert.assertTrue(0L == w3.writtenAt(widget::name));
|
||||
Assert.assertTrue(30 <= w3.ttlOf(widget::name));
|
||||
|
||||
w6 = session.<Widget>upsert(widget)
|
||||
w6 =
|
||||
session
|
||||
.<Widget>upsert(widget)
|
||||
.value(widget::id, UUIDs.timeBased())
|
||||
.value(widget::name, RandomString.make(20))
|
||||
.value(widget::a, RandomString.make(10))
|
||||
|
@ -403,7 +406,9 @@ public class UnitOfWorkTest extends AbstractEmbeddedCassandraTest {
|
|||
String date = d.toString();
|
||||
}
|
||||
// 'c' is distinct, but not on it's own so this should miss cache
|
||||
w4 = session.<Widget>select(Widget.class)
|
||||
w4 =
|
||||
session
|
||||
.<Widget>select(Widget.class)
|
||||
.where(widget::c, eq(w3.c()))
|
||||
.single()
|
||||
.sync()
|
||||
|
@ -413,7 +418,9 @@ public class UnitOfWorkTest extends AbstractEmbeddedCassandraTest {
|
|||
//Assert.assertTrue(at == committedAt);
|
||||
int ttl4 = w4.ttlOf(widget::name);
|
||||
Assert.assertTrue(ttl4 <= 30);
|
||||
w5 = session.<Widget>select(Widget.class)
|
||||
w5 =
|
||||
session
|
||||
.<Widget>select(Widget.class)
|
||||
.where(widget::id, eq(key))
|
||||
.uncached()
|
||||
.single()
|
||||
|
@ -433,7 +440,9 @@ public class UnitOfWorkTest extends AbstractEmbeddedCassandraTest {
|
|||
|
||||
try (UnitOfWork uow = session.begin()) {
|
||||
// This should inserted Widget, but not cache it.
|
||||
w1 = session.<Widget>insert(widget)
|
||||
w1 =
|
||||
session
|
||||
.<Widget>insert(widget)
|
||||
.value(widget::id, key1)
|
||||
.value(widget::name, RandomString.make(20))
|
||||
.sync(uow);
|
||||
|
@ -451,12 +460,16 @@ public class UnitOfWorkTest extends AbstractEmbeddedCassandraTest {
|
|||
//Assert.assertEquals(w1, w2);
|
||||
}
|
||||
|
||||
@Test public void testSelectAfterInsertProperlyCachesEntity() throws
|
||||
Exception { Widget w1, w2, w3, w4; UUID key = UUIDs.timeBased();
|
||||
@Test
|
||||
public void testSelectAfterInsertProperlyCachesEntity() throws Exception {
|
||||
Widget w1, w2, w3, w4;
|
||||
UUID key = UUIDs.timeBased();
|
||||
|
||||
try (UnitOfWork uow = session.begin()) {
|
||||
// This should cache the inserted Widget.
|
||||
w1 = session.<Widget>insert(widget)
|
||||
w1 =
|
||||
session
|
||||
.<Widget>insert(widget)
|
||||
.value(widget::id, key)
|
||||
.value(widget::name, RandomString.make(20))
|
||||
.value(widget::a, RandomString.make(10))
|
||||
|
@ -466,27 +479,27 @@ public class UnitOfWorkTest extends AbstractEmbeddedCassandraTest {
|
|||
.sync(uow);
|
||||
|
||||
// This should read from the cache and get the same instance of a Widget.
|
||||
w2 = session.<Widget>select(widget)
|
||||
.where(widget::id, eq(key))
|
||||
.single()
|
||||
.sync(uow)
|
||||
.orElse(null);
|
||||
w2 =
|
||||
session.<Widget>select(widget).where(widget::id, eq(key)).single().sync(uow).orElse(null);
|
||||
|
||||
uow.commit() .andThen(() -> { Assert.assertEquals(w1, w2); }); }
|
||||
uow.commit()
|
||||
.andThen(
|
||||
() -> {
|
||||
Assert.assertEquals(w1, w2);
|
||||
});
|
||||
}
|
||||
|
||||
// This should read the widget from the session cache and maintain object identity.
|
||||
w3 = session.<Widget>select(widget)
|
||||
.where(widget::id, eq(key))
|
||||
.single()
|
||||
.sync()
|
||||
.orElse(null);
|
||||
w3 = session.<Widget>select(widget).where(widget::id, eq(key)).single().sync().orElse(null);
|
||||
|
||||
Assert.assertEquals(w1, w3);
|
||||
|
||||
// This should read the widget from the database, no object identity but
|
||||
// values should match.
|
||||
w4 = session.<Widget>select(widget)
|
||||
.where(widget::id,eq(key))
|
||||
w4 =
|
||||
session
|
||||
.<Widget>select(widget)
|
||||
.where(widget::id, eq(key))
|
||||
.uncached()
|
||||
.single()
|
||||
.sync()
|
||||
|
@ -496,5 +509,4 @@ public class UnitOfWorkTest extends AbstractEmbeddedCassandraTest {
|
|||
Assert.assertTrue(w1.equals(w4));
|
||||
Assert.assertTrue(w4.equals(w1));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -55,6 +55,5 @@ public interface Account {
|
|||
public Map<String, Object> toMap() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue