diff --git a/bin/format.sh b/bin/format.sh index 10b2bf0..9967eb1 100755 --- a/bin/format.sh +++ b/bin/format.sh @@ -1,7 +1,14 @@ #!/bin/bash -for f in $(find ./src -name \*.java); do - echo Formatting $f - java -jar ./lib/google-java-format-1.3-all-deps.jar --replace $f -done +if [ "X$1" == "Xall" ]; then + for f in $(find ./src -name \*.java); do + echo Formatting $f + java -jar ./lib/google-java-format-1.3-all-deps.jar --replace $f + done +else + for file in $(git status --short | awk '{print $2}'); do + echo $file + java -jar ./lib/google-java-format-1.3-all-deps.jar --replace $file + done +fi diff --git a/src/main/java/net/helenus/core/SessionInitializer.java b/src/main/java/net/helenus/core/SessionInitializer.java index f8a39a7..0cd3c7d 100644 --- a/src/main/java/net/helenus/core/SessionInitializer.java +++ b/src/main/java/net/helenus/core/SessionInitializer.java @@ -45,7 +45,7 @@ public final class SessionInitializer extends AbstractSessionOperations { private boolean showCql = false; private boolean showValues = true; private ConsistencyLevel consistencyLevel; - private boolean idempotent = true; + private boolean idempotent = false; private MetricRegistry metricRegistry = new MetricRegistry(); private Tracer zipkinTracer; private PrintStream printStream = System.out; @@ -147,6 +147,11 @@ public final class SessionInitializer extends AbstractSessionOperations { return consistencyLevel; } + public SessionInitializer setOperationsIdempotentByDefault() { + this.idempotent = true; + return this; + } + public SessionInitializer idempotentQueryExecution(boolean idempotent) { this.idempotent = idempotent; return this; diff --git a/src/main/java/net/helenus/core/operation/AbstractFilterOperation.java b/src/main/java/net/helenus/core/operation/AbstractFilterOperation.java index 93e164e..de570eb 100644 --- a/src/main/java/net/helenus/core/operation/AbstractFilterOperation.java +++ b/src/main/java/net/helenus/core/operation/AbstractFilterOperation.java @@ -108,6 +108,12 @@ public abstract class AbstractFilterOperation !filter.getNode().getProperty().isIdempotent()) + || super.isIdempotentOperation(); + } + protected List bindFacetValues(List facets) { if (facets == null) { return new ArrayList(); diff --git a/src/main/java/net/helenus/core/operation/AbstractStatementOperation.java b/src/main/java/net/helenus/core/operation/AbstractStatementOperation.java index e0b97a6..61ff695 100644 --- a/src/main/java/net/helenus/core/operation/AbstractStatementOperation.java +++ b/src/main/java/net/helenus/core/operation/AbstractStatementOperation.java @@ -47,10 +47,10 @@ public abstract class AbstractStatementOperation extends AbstractOperation v._1.getProperty()).allMatch(prop -> prop.isIdempotent()) + || super.isIdempotentOperation(); + } + @Override public T sync() throws TimeoutException { T result = super.sync(); @@ -346,10 +352,6 @@ public final class InsertOperation extends AbstractOperation { } } + protected boolean isIdempotentOperation() { + return false; + } + public Statement options(Statement statement) { return statement; } diff --git a/src/main/java/net/helenus/core/operation/UpdateOperation.java b/src/main/java/net/helenus/core/operation/UpdateOperation.java index c54880d..6288baa 100644 --- a/src/main/java/net/helenus/core/operation/UpdateOperation.java +++ b/src/main/java/net/helenus/core/operation/UpdateOperation.java @@ -783,6 +783,28 @@ public final class UpdateOperation extends AbstractFilterOperation { + if (facet != null) { + Set props = facet.getProperties(); + if (props != null && props.size() > 0) { + return props.stream().allMatch(prop -> prop.isIdempotent()); + } else { + return true; + } + } else { + // In this case our UPDATE statement made mutations via the List, Set, Map methods only. + return false; + } + }) + || super.isIdempotentOperation(); + } + @Override public E sync() throws TimeoutException { E result = super.sync(); diff --git a/src/main/java/net/helenus/core/reflect/HelenusNamedProperty.java b/src/main/java/net/helenus/core/reflect/HelenusNamedProperty.java index 9c4e448..c295fc3 100644 --- a/src/main/java/net/helenus/core/reflect/HelenusNamedProperty.java +++ b/src/main/java/net/helenus/core/reflect/HelenusNamedProperty.java @@ -63,6 +63,11 @@ public final class HelenusNamedProperty implements HelenusProperty { return false; } + @Override + public boolean isIdempotent() { + return false; + } + @Override public Class getJavaType() { throw new HelenusMappingException("will never called"); diff --git a/src/main/java/net/helenus/mapping/HelenusMappingProperty.java b/src/main/java/net/helenus/mapping/HelenusMappingProperty.java index fbea1dd..c3646a6 100644 --- a/src/main/java/net/helenus/mapping/HelenusMappingProperty.java +++ b/src/main/java/net/helenus/mapping/HelenusMappingProperty.java @@ -35,6 +35,7 @@ public final class HelenusMappingProperty implements HelenusProperty { private final String propertyName; private final Optional indexName; private final boolean caseSensitiveIndex; + private final boolean idempotent; private final ColumnInformation columnInfo; @@ -56,6 +57,15 @@ public final class HelenusMappingProperty implements HelenusProperty { this.columnInfo = new ColumnInformation(getter); + switch (this.columnInfo.getColumnType()) { + case PARTITION_KEY: + case CLUSTERING_COLUMN: + this.idempotent = true; + break; + default: + this.idempotent = MappingUtil.idempotent(getter); + } + this.genericJavaType = getter.getGenericReturnType(); this.javaType = getter.getReturnType(); this.abstractJavaType = MappingJavaTypes.resolveJavaType(this.javaType); @@ -112,6 +122,11 @@ public final class HelenusMappingProperty implements HelenusProperty { return caseSensitiveIndex; } + @Override + public boolean isIdempotent() { + return idempotent; + } + @Override public String getPropertyName() { return propertyName; diff --git a/src/main/java/net/helenus/mapping/HelenusProperty.java b/src/main/java/net/helenus/mapping/HelenusProperty.java index 08b428e..99b0dbf 100644 --- a/src/main/java/net/helenus/mapping/HelenusProperty.java +++ b/src/main/java/net/helenus/mapping/HelenusProperty.java @@ -37,6 +37,8 @@ public interface HelenusProperty { boolean caseSensitiveIndex(); + boolean isIdempotent(); + Class getJavaType(); AbstractDataType getDataType(); diff --git a/src/main/java/net/helenus/mapping/MappingUtil.java b/src/main/java/net/helenus/mapping/MappingUtil.java index 6eff50b..08b4bac 100644 --- a/src/main/java/net/helenus/mapping/MappingUtil.java +++ b/src/main/java/net/helenus/mapping/MappingUtil.java @@ -124,6 +124,15 @@ public final class MappingUtil { return false; } + public static boolean idempotent(Method getterMethod) { + Column column = getterMethod.getDeclaredAnnotation(Column.class); + + if (column != null) { + return column.idempotent(); + } + return false; + } + public static String getPropertyName(Method getter) { return getter.getName(); } diff --git a/src/main/java/net/helenus/mapping/annotation/Column.java b/src/main/java/net/helenus/mapping/annotation/Column.java index ab4b2d4..886493e 100644 --- a/src/main/java/net/helenus/mapping/annotation/Column.java +++ b/src/main/java/net/helenus/mapping/annotation/Column.java @@ -59,4 +59,12 @@ public @interface Column { * @return true if name have to be quoted */ boolean forceQuote() default false; + + /** + * Used to determin if updates can be retried. Also, mutations to this field do not trigger + * objects in the session cache to be evicted. + * + * @return + */ + boolean idempotent() default false; }