From 25eb81219d8ee6168a0cb8fd7bacd0782d3852fa Mon Sep 17 00:00:00 2001 From: Greg Burd Date: Mon, 23 Oct 2017 16:29:23 -0400 Subject: [PATCH 01/18] WIP: caching --- .../net/helenus/core/AbstractUnitOfWork.java | 6 ++++ .../operation/AbstractStatementOperation.java | 30 ++++++++++--------- .../helenus/mapping/HelenusMappingEntity.java | 4 +-- .../net/helenus/mapping/annotation/Index.java | 6 ++++ 4 files changed, 30 insertions(+), 16 deletions(-) diff --git a/src/main/java/net/helenus/core/AbstractUnitOfWork.java b/src/main/java/net/helenus/core/AbstractUnitOfWork.java index fe3ccdf..9a345bc 100644 --- a/src/main/java/net/helenus/core/AbstractUnitOfWork.java +++ b/src/main/java/net/helenus/core/AbstractUnitOfWork.java @@ -86,6 +86,12 @@ public abstract class AbstractUnitOfWork implements UnitOfW } public void logTimers(String what) { + + cache hit, miss; + multiple calls, sometimes to db, sometimes to cache, sometimes both... + uow.setPurpose(getClass().getSimpleName() + "::" + Thread.currentThread().getStackTrace()[1].getMethodName()); + + double e = (double) elapsedTime_.elapsed(TimeUnit.MICROSECONDS) / 1000.0; double d = (double) databaseTime_.elapsed(TimeUnit.MICROSECONDS) / 1000.0; double c = (double) cacheLookupTime_.elapsed(TimeUnit.MICROSECONDS) / 1000.0; diff --git a/src/main/java/net/helenus/core/operation/AbstractStatementOperation.java b/src/main/java/net/helenus/core/operation/AbstractStatementOperation.java index c46a0f0..dbe8b08 100644 --- a/src/main/java/net/helenus/core/operation/AbstractStatementOperation.java +++ b/src/main/java/net/helenus/core/operation/AbstractStatementOperation.java @@ -21,6 +21,7 @@ import java.util.Map; import java.util.Optional; import java.util.concurrent.TimeUnit; +import net.helenus.mapping.HelenusProperty; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -46,9 +47,7 @@ import net.helenus.mapping.value.BeanColumnValueProvider; import net.helenus.support.HelenusException; public abstract class AbstractStatementOperation> extends Operation { - - private static final Logger LOG = LoggerFactory.getLogger(AbstractStatementOperation.class); - + protected boolean enableCache = true; protected boolean showValues = true; protected TraceContext traceContext; @@ -327,14 +326,14 @@ public abstract class AbstractStatementOperation { - if (valueMap == null) { - Object value = BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop, false); - binder.setValueForProperty(prop, value.toString()); - } else { - binder.setValueForProperty(prop, valueMap.get(prop.getPropertyName()).toString()); - } - facets.add(binder.bind()); - }); + List properties = unboundFacet.getProperties(); + if (properties != null) { + properties.forEach(prop -> { + if (valueMap == null) { + Object value = BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop, false); + binder.setValueForProperty(prop, value.toString()); + } else { + binder.setValueForProperty(prop, valueMap.get(prop.getPropertyName()).toString()); + } + facets.add(binder.bind()); + }); + } } else { facets.add(facet); } diff --git a/src/main/java/net/helenus/mapping/HelenusMappingEntity.java b/src/main/java/net/helenus/mapping/HelenusMappingEntity.java index 11f9790..77cd60e 100644 --- a/src/main/java/net/helenus/mapping/HelenusMappingEntity.java +++ b/src/main/java/net/helenus/mapping/HelenusMappingEntity.java @@ -125,8 +125,8 @@ public final class HelenusMappingEntity implements HelenusEntity { facetsBuilder.add(new UnboundFacet(primaryKeyProperties)); primaryKeyProperties = null; } - Optional optionalIndexName = prop.getIndexName(); - if (optionalIndexName.isPresent()) { + Index idx = prop.getGetterMethod().getAnnotation(Index.class); + if (idx.distinct()) { UnboundFacet facet = new UnboundFacet(prop); facetsBuilder.add(facet); } diff --git a/src/main/java/net/helenus/mapping/annotation/Index.java b/src/main/java/net/helenus/mapping/annotation/Index.java index 5222824..6e341c9 100644 --- a/src/main/java/net/helenus/mapping/annotation/Index.java +++ b/src/main/java/net/helenus/mapping/annotation/Index.java @@ -65,4 +65,10 @@ public @interface Index { * @return true if the index should ignore case when comparing */ boolean caseSensitive() default true; + + /** + * + * @return + */ + boolean distinct() default false; } From a1e29c62c82a8908fbf67958a19e104f15850bb8 Mon Sep 17 00:00:00 2001 From: Greg Burd Date: Tue, 24 Oct 2017 11:05:44 -0400 Subject: [PATCH 02/18] Improve UOW logging. --- .../net/helenus/core/AbstractUnitOfWork.java | 62 ++++++++------ .../java/net/helenus/core/HelenusSession.java | 19 ++++- .../java/net/helenus/core/UnitOfWork.java | 2 + .../operation/AbstractStatementOperation.java | 9 +-- .../net/helenus/core/operation/Operation.java | 1 + .../helenus/mapping/HelenusMappingEntity.java | 13 ++- .../mapping/annotation/Constraints.java | 81 ++++++++++++------- .../mapping/validator/DistinctValidator.java | 36 +++++++++ .../core/unitofwork/UnitOfWorkTest.java | 7 +- 9 files changed, 162 insertions(+), 68 deletions(-) create mode 100644 src/main/java/net/helenus/mapping/validator/DistinctValidator.java diff --git a/src/main/java/net/helenus/core/AbstractUnitOfWork.java b/src/main/java/net/helenus/core/AbstractUnitOfWork.java index 9a345bc..641610b 100644 --- a/src/main/java/net/helenus/core/AbstractUnitOfWork.java +++ b/src/main/java/net/helenus/core/AbstractUnitOfWork.java @@ -17,6 +17,7 @@ package net.helenus.core; import java.util.*; import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -43,10 +44,13 @@ public abstract class AbstractUnitOfWork implements UnitOfW private List postCommit = new ArrayList(); private boolean aborted = false; private boolean committed = false; - private String purpose_; - private Stopwatch elapsedTime_; - private Stopwatch databaseTime_ = Stopwatch.createUnstarted(); - private Stopwatch cacheLookupTime_ = Stopwatch.createUnstarted(); + private String purpose; + private int cacheHits = 0; + private int cacheMisses = 0; + private int databaseLookups = 0; + private Stopwatch elapsedTime; + private Stopwatch databaseTime = Stopwatch.createUnstarted(); + private Stopwatch cacheLookupTime = Stopwatch.createUnstarted(); protected AbstractUnitOfWork(HelenusSession session, AbstractUnitOfWork parent) { Objects.requireNonNull(session, "containing session cannot be null"); @@ -57,12 +61,12 @@ public abstract class AbstractUnitOfWork implements UnitOfW @Override public Stopwatch getExecutionTimer() { - return databaseTime_; + return databaseTime; } @Override public Stopwatch getCacheLookupTimer() { - return cacheLookupTime_; + return cacheLookupTime; } @Override @@ -74,31 +78,43 @@ public abstract class AbstractUnitOfWork implements UnitOfW @Override public UnitOfWork begin() { - elapsedTime_ = Stopwatch.createStarted(); + elapsedTime = Stopwatch.createStarted(); // log.record(txn::start) return this; } @Override public UnitOfWork setPurpose(String purpose) { - purpose_ = purpose; + this.purpose = purpose; return this; } + @Override + public void record(int cache, int ops) { + if (cache > 0) { + cacheHits += cache; + } else { + cacheMisses += Math.abs(cache); + } + if (ops > 0) { + databaseLookups += ops; + } + } + public void logTimers(String what) { - - cache hit, miss; - multiple calls, sometimes to db, sometimes to cache, sometimes both... - uow.setPurpose(getClass().getSimpleName() + "::" + Thread.currentThread().getStackTrace()[1].getMethodName()); - - - double e = (double) elapsedTime_.elapsed(TimeUnit.MICROSECONDS) / 1000.0; - double d = (double) databaseTime_.elapsed(TimeUnit.MICROSECONDS) / 1000.0; - double c = (double) cacheLookupTime_.elapsed(TimeUnit.MICROSECONDS) / 1000.0; - double fd = (d / (e - c)) * 100.0; - double fc = (c / (e - d)) * 100.0; - LOG.info(String.format("UOW(%s)%s %s (total: %.3fms cache: %.3fms %2.2f%% db: %.3fms %2.2f%%)", hashCode(), - (purpose_ == null ? "" : " " + purpose_), what, e, c, fc, d, fd)); + double e = (double) elapsedTime.elapsed(TimeUnit.MICROSECONDS) / 1000.0; + double d = (double) databaseTime.elapsed(TimeUnit.MICROSECONDS) / 1000.0; + double c = (double) cacheLookupTime.elapsed(TimeUnit.MICROSECONDS) / 1000.0; + double fd = (d / e) * 100.0; + double fc = (c / e) * 100.0; + double dat = d + c; + double daf = (dat / e) * 100; + String nested = this.nested.stream().map(uow -> String.valueOf(uow.hashCode())).collect(Collectors.joining(", ")); + LOG.info(String.format("UOW(%s%s) %s (total: %.3fms cache: %.3fms %2.2f%% (%d hit, %d miss) %d database operation%s took %.3fms %2.2f%% [%.3fms %2.2f%%])%s", + hashCode(), + (this.nested.size() > 0 ? ", [" + nested + "]" : ""), + what, e, c, fc, cacheHits, cacheMisses, databaseLookups, (databaseLookups > 1) ? "s" : "", + d, fd, dat, daf, (purpose == null ? "" : " in " + purpose))); } private void applyPostCommitFunctions() { @@ -191,7 +207,7 @@ public abstract class AbstractUnitOfWork implements UnitOfW } else { session.mergeCache(cache); } - elapsedTime_.stop(); + elapsedTime.stop(); // Apply all post-commit functions for if (parent == null) { @@ -218,7 +234,7 @@ public abstract class AbstractUnitOfWork implements UnitOfW // log.record(txn::abort) // cache.invalidateSince(txn::start time) if (!hasAborted()) { - elapsedTime_.stop(); + elapsedTime.stop(); logTimers("aborted"); } } diff --git a/src/main/java/net/helenus/core/HelenusSession.java b/src/main/java/net/helenus/core/HelenusSession.java index b0b0fb1..f458080 100644 --- a/src/main/java/net/helenus/core/HelenusSession.java +++ b/src/main/java/net/helenus/core/HelenusSession.java @@ -288,15 +288,30 @@ public final class HelenusSession extends AbstractSessionOperations implements C return metadata; } - public synchronized UnitOfWork begin() { - return begin(null); + public UnitOfWork begin() { + return this.begin(null); } public synchronized UnitOfWork begin(UnitOfWork parent) { + StackTraceElement[] trace = Thread.currentThread().getStackTrace(); + int frame = 2; + if (trace[2].getMethodName().equals("begin")) { + frame = 3; + } + StringBuilder purpose = new StringBuilder() + .append(trace[frame].getClassName()) + .append(".") + .append(trace[frame].getMethodName()) + .append("(") + .append(trace[frame].getFileName()) + .append(":") + .append(trace[frame].getLineNumber()) + .append(")"); try { Class clazz = unitOfWorkClass; Constructor ctor = clazz.getConstructor(HelenusSession.class, UnitOfWork.class); UnitOfWork uow = ctor.newInstance(this, parent); + uow.setPurpose(purpose.toString()); if (parent != null) { parent.addNestedUnitOfWork(uow); } diff --git a/src/main/java/net/helenus/core/UnitOfWork.java b/src/main/java/net/helenus/core/UnitOfWork.java index 6ff3496..96125c3 100644 --- a/src/main/java/net/helenus/core/UnitOfWork.java +++ b/src/main/java/net/helenus/core/UnitOfWork.java @@ -65,4 +65,6 @@ public interface UnitOfWork extends AutoCloseable { Stopwatch getCacheLookupTimer(); + void record(int cache, int ops); + } diff --git a/src/main/java/net/helenus/core/operation/AbstractStatementOperation.java b/src/main/java/net/helenus/core/operation/AbstractStatementOperation.java index dbe8b08..44a60d3 100644 --- a/src/main/java/net/helenus/core/operation/AbstractStatementOperation.java +++ b/src/main/java/net/helenus/core/operation/AbstractStatementOperation.java @@ -21,10 +21,6 @@ import java.util.Map; import java.util.Optional; import java.util.concurrent.TimeUnit; -import net.helenus.mapping.HelenusProperty; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import com.datastax.driver.core.ConsistencyLevel; import com.datastax.driver.core.PreparedStatement; import com.datastax.driver.core.RegularStatement; @@ -43,6 +39,7 @@ import net.helenus.core.UnitOfWork; import net.helenus.core.cache.Facet; import net.helenus.core.cache.UnboundFacet; import net.helenus.core.reflect.MapExportable; +import net.helenus.mapping.HelenusProperty; import net.helenus.mapping.value.BeanColumnValueProvider; import net.helenus.support.HelenusException; @@ -326,14 +323,14 @@ public abstract class AbstractStatementOperation { timer.start(); } ResultSetFuture futureResultSet = session.executeAsync(statement, showValues); + if (uow != null) uow.record(0, 1); ResultSet resultSet = futureResultSet.getUninterruptibly(); // TODO(gburd): (timeout, units); if (uow != null) diff --git a/src/main/java/net/helenus/mapping/HelenusMappingEntity.java b/src/main/java/net/helenus/mapping/HelenusMappingEntity.java index 77cd60e..8869761 100644 --- a/src/main/java/net/helenus/mapping/HelenusMappingEntity.java +++ b/src/main/java/net/helenus/mapping/HelenusMappingEntity.java @@ -15,9 +15,11 @@ */ package net.helenus.mapping; +import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.util.*; +import net.helenus.mapping.validator.DistinctValidator; import org.apache.commons.lang3.ClassUtils; import com.datastax.driver.core.DefaultMetadata; @@ -33,6 +35,8 @@ import net.helenus.core.cache.UnboundFacet; import net.helenus.mapping.annotation.*; import net.helenus.support.HelenusMappingException; +import javax.validation.ConstraintValidator; + public final class HelenusMappingEntity implements HelenusEntity { private final Class iface; @@ -125,10 +129,11 @@ public final class HelenusMappingEntity implements HelenusEntity { facetsBuilder.add(new UnboundFacet(primaryKeyProperties)); primaryKeyProperties = null; } - Index idx = prop.getGetterMethod().getAnnotation(Index.class); - if (idx.distinct()) { - UnboundFacet facet = new UnboundFacet(prop); - facetsBuilder.add(facet); + for (ConstraintValidator constraint : MappingUtil.getValidators(prop.getGetterMethod())) { + if (constraint.getClass().isAssignableFrom(DistinctValidator.class)); + UnboundFacet facet = new UnboundFacet(prop); + facetsBuilder.add(facet); + break; } } } diff --git a/src/main/java/net/helenus/mapping/annotation/Constraints.java b/src/main/java/net/helenus/mapping/annotation/Constraints.java index 5ed755e..1013015 100644 --- a/src/main/java/net/helenus/mapping/annotation/Constraints.java +++ b/src/main/java/net/helenus/mapping/annotation/Constraints.java @@ -222,34 +222,59 @@ public final class Constraints { public @interface UpperCase { } - /** - * Pattern annotation is LowerCase annotation is using to ensure that value is - * upper case before storing it - * - *

- * Can be used only for @java.lang.CharSequence - * - *

- * It does not have effect on selects and data retrieval operations - */ - @Documented - @Retention(RetentionPolicy.RUNTIME) - @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) - @Constraint(validatedBy = PatternValidator.class) - public @interface Pattern { + /** + * Pattern annotation is LowerCase annotation is using to ensure that value is + * upper case before storing it + * + *

+ * Can be used only for @java.lang.CharSequence + * + *

+ * It does not have effect on selects and data retrieval operations + */ + @Documented + @Retention(RetentionPolicy.RUNTIME) + @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) + @Constraint(validatedBy = PatternValidator.class) + public @interface Pattern { - /** - * User defined regex expression to check match of the value - * - * @return Java regex pattern - */ - String value(); + /** + * User defined regex expression to check match of the value + * + * @return Java regex pattern + */ + String value(); - /** - * Regex flags composition - * - * @return Java regex flags - */ - int flags(); - } + /** + * Regex flags composition + * + * @return Java regex flags + */ + int flags(); + } + + /** + * Distinct annotation is used to signal, but not ensure that a value should be + * distinct in the database. + * + *

+ * Can be used only for @java.lang.CharSequence + * + *

+ * It does not have effect on selects and data retrieval operations + */ + @Documented + @Retention(RetentionPolicy.RUNTIME) + @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) + @Constraint(validatedBy = DistinctValidator.class) + public @interface Distinct { + + /** + * User defined Enum to further restrict the items in the set. + * + * @return Java + */ + Class value() default Enum.class; + + } } diff --git a/src/main/java/net/helenus/mapping/validator/DistinctValidator.java b/src/main/java/net/helenus/mapping/validator/DistinctValidator.java new file mode 100644 index 0000000..cedcec9 --- /dev/null +++ b/src/main/java/net/helenus/mapping/validator/DistinctValidator.java @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2015 The Helenus Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.helenus.mapping.validator; + +import java.util.regex.Pattern; + +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorContext; + +import net.helenus.mapping.annotation.Constraints; + +public final class DistinctValidator implements ConstraintValidator { + + @Override + public void initialize(Constraints.Distinct constraintAnnotation) { + } + + @Override + public boolean isValid(CharSequence value, ConstraintValidatorContext context) { + //TODO(gburd): if there is an Enum type supplied, check that value is valid Enum.name() + return true; + } +} diff --git a/src/test/java/net/helenus/test/integration/core/unitofwork/UnitOfWorkTest.java b/src/test/java/net/helenus/test/integration/core/unitofwork/UnitOfWorkTest.java index 27e86bb..ecc048c 100644 --- a/src/test/java/net/helenus/test/integration/core/unitofwork/UnitOfWorkTest.java +++ b/src/test/java/net/helenus/test/integration/core/unitofwork/UnitOfWorkTest.java @@ -24,10 +24,7 @@ import net.helenus.core.Helenus; import net.helenus.core.HelenusSession; import net.helenus.core.UnitOfWork; import net.helenus.core.annotation.Cacheable; -import net.helenus.mapping.annotation.Column; -import net.helenus.mapping.annotation.Index; -import net.helenus.mapping.annotation.PartitionKey; -import net.helenus.mapping.annotation.Table; +import net.helenus.mapping.annotation.*; import net.helenus.test.integration.build.AbstractEmbeddedCassandraTest; import org.junit.Assert; import org.junit.BeforeClass; @@ -39,8 +36,8 @@ interface Widget { @PartitionKey UUID id(); - @Column @Index + @Constraints.Distinct() String name(); } From c6b95f12b4a1c62b46b1354e98b3603676479b2b Mon Sep 17 00:00:00 2001 From: Greg Burd Date: Tue, 24 Oct 2017 13:40:35 -0400 Subject: [PATCH 03/18] Fix up logging a bit. Fix bug where updateCache wasn't properly adding facets that were bound. --- .../core/AbstractSessionOperations.java | 30 +++++++++----- .../net/helenus/core/AbstractUnitOfWork.java | 30 +++++++------- .../java/net/helenus/core/HelenusSession.java | 39 ++++++++++++------- .../operation/AbstractStatementOperation.java | 4 +- .../net/helenus/core/operation/Operation.java | 2 +- 5 files changed, 66 insertions(+), 39 deletions(-) diff --git a/src/main/java/net/helenus/core/AbstractSessionOperations.java b/src/main/java/net/helenus/core/AbstractSessionOperations.java index 15abfae..0a1b3fd 100644 --- a/src/main/java/net/helenus/core/AbstractSessionOperations.java +++ b/src/main/java/net/helenus/core/AbstractSessionOperations.java @@ -60,7 +60,7 @@ public abstract class AbstractSessionOperations { public PreparedStatement prepare(RegularStatement statement) { try { - log(statement, false); + log(statement, null, false); return currentSession().prepare(statement); } catch (RuntimeException e) { throw translateException(e); @@ -69,29 +69,41 @@ public abstract class AbstractSessionOperations { public ListenableFuture prepareAsync(RegularStatement statement) { try { - log(statement, false); + log(statement, null, false); return currentSession().prepareAsync(statement); } catch (RuntimeException e) { throw translateException(e); } } - public ResultSet execute(Statement statement, boolean showValues) { - return executeAsync(statement, showValues).getUninterruptibly(); + public ResultSet execute(Statement statement, boolean showValues) { + return execute(statement, null, showValues); + } + + public ResultSet execute(Statement statement, UnitOfWork uow, boolean showValues) { + return executeAsync(statement, uow, showValues).getUninterruptibly(); } - public ResultSetFuture executeAsync(Statement statement, boolean showValues) { - try { - log(statement, showValues); + public ResultSetFuture executeAsync(Statement statement, boolean showValues) { + return executeAsync(statement, null, showValues); + } + + public ResultSetFuture executeAsync(Statement statement, UnitOfWork uow, boolean showValues) { + try { + log(statement, uow, showValues); return currentSession().executeAsync(statement); } catch (RuntimeException e) { throw translateException(e); } } - void log(Statement statement, boolean showValues) { + void log(Statement statement, UnitOfWork uow, boolean showValues) { if (LOG.isInfoEnabled()) { - LOG.info("Execute statement " + statement); + String uowString = ""; + if (uow != null) { + uowString = "within UOW(" + uow.hashCode() + "): "; + } + LOG.info(String.format("Execute statement %s%s", uowString, statement)); } if (isShowCql()) { if (statement instanceof BuiltStatement) { diff --git a/src/main/java/net/helenus/core/AbstractUnitOfWork.java b/src/main/java/net/helenus/core/AbstractUnitOfWork.java index 641610b..b3434a1 100644 --- a/src/main/java/net/helenus/core/AbstractUnitOfWork.java +++ b/src/main/java/net/helenus/core/AbstractUnitOfWork.java @@ -34,7 +34,7 @@ import net.helenus.core.cache.Facet; /** Encapsulates the concept of a "transaction" as a unit-of-work. */ public abstract class AbstractUnitOfWork implements UnitOfWork, AutoCloseable { - private static final Logger LOG = LoggerFactory.getLogger(AbstractUnitOfWork.class); + private static final Logger LOG = LoggerFactory.getLogger(AbstractUnitOfWork.class); private final List> nested = new ArrayList<>(); private final HelenusSession session; @@ -44,13 +44,13 @@ public abstract class AbstractUnitOfWork implements UnitOfW private List postCommit = new ArrayList(); private boolean aborted = false; private boolean committed = false; - private String purpose; - private int cacheHits = 0; - private int cacheMisses = 0; - private int databaseLookups = 0; - private Stopwatch elapsedTime; - private Stopwatch databaseTime = Stopwatch.createUnstarted(); - private Stopwatch cacheLookupTime = Stopwatch.createUnstarted(); + protected String purpose; + protected int cacheHits = 0; + protected int cacheMisses = 0; + protected int databaseLookups = 0; + protected Stopwatch elapsedTime; + protected Stopwatch databaseTime = Stopwatch.createUnstarted(); + protected Stopwatch cacheLookupTime = Stopwatch.createUnstarted(); protected AbstractUnitOfWork(HelenusSession session, AbstractUnitOfWork parent) { Objects.requireNonNull(session, "containing session cannot be null"); @@ -101,7 +101,7 @@ public abstract class AbstractUnitOfWork implements UnitOfW } } - public void logTimers(String what) { + public String logTimers(String what) { double e = (double) elapsedTime.elapsed(TimeUnit.MICROSECONDS) / 1000.0; double d = (double) databaseTime.elapsed(TimeUnit.MICROSECONDS) / 1000.0; double c = (double) cacheLookupTime.elapsed(TimeUnit.MICROSECONDS) / 1000.0; @@ -110,11 +110,11 @@ public abstract class AbstractUnitOfWork implements UnitOfW double dat = d + c; double daf = (dat / e) * 100; String nested = this.nested.stream().map(uow -> String.valueOf(uow.hashCode())).collect(Collectors.joining(", ")); - LOG.info(String.format("UOW(%s%s) %s (total: %.3fms cache: %.3fms %2.2f%% (%d hit, %d miss) %d database operation%s took %.3fms %2.2f%% [%.3fms %2.2f%%])%s", + return String.format(Locale.US, "UOW(%s%s) %s (total: %,.3fms cache: %,.3fms %,2.2f%% (%,d hit, %,d miss) %,d database operation%s took %,.3fms %,2.2f%% [%,.3fms %,2.2f%%])%s", hashCode(), (this.nested.size() > 0 ? ", [" + nested + "]" : ""), what, e, c, fc, cacheHits, cacheMisses, databaseLookups, (databaseLookups > 1) ? "s" : "", - d, fd, dat, daf, (purpose == null ? "" : " in " + purpose))); + d, fd, dat, daf, (purpose == null ? "" : " in " + purpose)); } private void applyPostCommitFunctions() { @@ -123,7 +123,9 @@ public abstract class AbstractUnitOfWork implements UnitOfW f.apply(); } } - logTimers("committed"); + if (LOG.isInfoEnabled()) { + LOG.info(logTimers("committed")); + } } @Override @@ -235,7 +237,9 @@ public abstract class AbstractUnitOfWork implements UnitOfW // cache.invalidateSince(txn::start time) if (!hasAborted()) { elapsedTime.stop(); - logTimers("aborted"); + if (LOG.isInfoEnabled()) { + LOG.info(logTimers("aborted")); + } } } diff --git a/src/main/java/net/helenus/core/HelenusSession.java b/src/main/java/net/helenus/core/HelenusSession.java index f458080..5df40fb 100644 --- a/src/main/java/net/helenus/core/HelenusSession.java +++ b/src/main/java/net/helenus/core/HelenusSession.java @@ -51,10 +51,14 @@ import net.helenus.support.Fun.Tuple2; import net.helenus.support.Fun.Tuple6; import net.helenus.support.HelenusException; import net.helenus.support.HelenusMappingException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public final class HelenusSession extends AbstractSessionOperations implements Closeable { - private final int MAX_CACHE_SIZE = 10000; + private static final Logger LOG = LoggerFactory.getLogger(HelenusSession.class); + + private final int MAX_CACHE_SIZE = 10000; private final int MAX_CACHE_EXPIRE_SECONDS = 600; private final Session session; @@ -293,25 +297,30 @@ public final class HelenusSession extends AbstractSessionOperations implements C } public synchronized UnitOfWork begin(UnitOfWork parent) { - StackTraceElement[] trace = Thread.currentThread().getStackTrace(); - int frame = 2; - if (trace[2].getMethodName().equals("begin")) { - frame = 3; + StringBuilder purpose = null; + if (LOG.isInfoEnabled()) { + StackTraceElement[] trace = Thread.currentThread().getStackTrace(); + int frame = 2; + if (trace[2].getMethodName().equals("begin")) { + frame = 3; + } + purpose = new StringBuilder() + .append(trace[frame].getClassName()) + .append(".") + .append(trace[frame].getMethodName()) + .append("(") + .append(trace[frame].getFileName()) + .append(":") + .append(trace[frame].getLineNumber()) + .append(")"); } - StringBuilder purpose = new StringBuilder() - .append(trace[frame].getClassName()) - .append(".") - .append(trace[frame].getMethodName()) - .append("(") - .append(trace[frame].getFileName()) - .append(":") - .append(trace[frame].getLineNumber()) - .append(")"); try { Class clazz = unitOfWorkClass; Constructor ctor = clazz.getConstructor(HelenusSession.class, UnitOfWork.class); UnitOfWork uow = ctor.newInstance(this, parent); - uow.setPurpose(purpose.toString()); + if (LOG.isInfoEnabled()) { + uow.setPurpose(purpose.toString()); + } if (parent != null) { parent.addNestedUnitOfWork(uow); } diff --git a/src/main/java/net/helenus/core/operation/AbstractStatementOperation.java b/src/main/java/net/helenus/core/operation/AbstractStatementOperation.java index 44a60d3..e0315de 100644 --- a/src/main/java/net/helenus/core/operation/AbstractStatementOperation.java +++ b/src/main/java/net/helenus/core/operation/AbstractStatementOperation.java @@ -353,8 +353,10 @@ public abstract class AbstractStatementOperation { timer = uow.getExecutionTimer(); timer.start(); } - ResultSetFuture futureResultSet = session.executeAsync(statement, showValues); + ResultSetFuture futureResultSet = session.executeAsync(statement, uow, showValues); if (uow != null) uow.record(0, 1); ResultSet resultSet = futureResultSet.getUninterruptibly(); // TODO(gburd): (timeout, units); From 1642f09ce9745475a1b14dd73607635352945f3e Mon Sep 17 00:00:00 2001 From: Greg Burd Date: Tue, 24 Oct 2017 14:24:23 -0400 Subject: [PATCH 04/18] Fix NPE, replace forEach() with for() /because Java. Formatting. --- .../core/AbstractSessionOperations.java | 30 +++--- .../net/helenus/core/AbstractUnitOfWork.java | 49 ++++----- .../java/net/helenus/core/HelenusSession.java | 50 ++++----- .../java/net/helenus/core/UnitOfWork.java | 2 +- .../operation/AbstractStatementOperation.java | 29 +++-- .../net/helenus/core/operation/Operation.java | 3 +- .../core/operation/SelectOperation.java | 17 +-- .../helenus/mapping/HelenusMappingEntity.java | 18 ++-- .../mapping/annotation/Constraints.java | 100 +++++++++--------- .../net/helenus/mapping/annotation/Index.java | 10 +- .../mapping/validator/DistinctValidator.java | 19 ++-- 11 files changed, 162 insertions(+), 165 deletions(-) diff --git a/src/main/java/net/helenus/core/AbstractSessionOperations.java b/src/main/java/net/helenus/core/AbstractSessionOperations.java index 0a1b3fd..9352367 100644 --- a/src/main/java/net/helenus/core/AbstractSessionOperations.java +++ b/src/main/java/net/helenus/core/AbstractSessionOperations.java @@ -76,20 +76,20 @@ public abstract class AbstractSessionOperations { } } - public ResultSet execute(Statement statement, boolean showValues) { - return execute(statement, null, showValues); - } - - public ResultSet execute(Statement statement, UnitOfWork uow, boolean showValues) { - return executeAsync(statement, uow, showValues).getUninterruptibly(); + public ResultSet execute(Statement statement, boolean showValues) { + return execute(statement, null, showValues); } - public ResultSetFuture executeAsync(Statement statement, boolean showValues) { - return executeAsync(statement, null, showValues); - } + public ResultSet execute(Statement statement, UnitOfWork uow, boolean showValues) { + return executeAsync(statement, uow, showValues).getUninterruptibly(); + } - public ResultSetFuture executeAsync(Statement statement, UnitOfWork uow, boolean showValues) { - try { + public ResultSetFuture executeAsync(Statement statement, boolean showValues) { + return executeAsync(statement, null, showValues); + } + + public ResultSetFuture executeAsync(Statement statement, UnitOfWork uow, boolean showValues) { + try { log(statement, uow, showValues); return currentSession().executeAsync(statement); } catch (RuntimeException e) { @@ -99,10 +99,10 @@ public abstract class AbstractSessionOperations { void log(Statement statement, UnitOfWork uow, boolean showValues) { if (LOG.isInfoEnabled()) { - String uowString = ""; - if (uow != null) { - uowString = "within UOW(" + uow.hashCode() + "): "; - } + String uowString = ""; + if (uow != null) { + uowString = "within UOW(" + uow.hashCode() + "): "; + } LOG.info(String.format("Execute statement %s%s", uowString, statement)); } if (isShowCql()) { diff --git a/src/main/java/net/helenus/core/AbstractUnitOfWork.java b/src/main/java/net/helenus/core/AbstractUnitOfWork.java index b3434a1..eb0d657 100644 --- a/src/main/java/net/helenus/core/AbstractUnitOfWork.java +++ b/src/main/java/net/helenus/core/AbstractUnitOfWork.java @@ -34,16 +34,13 @@ import net.helenus.core.cache.Facet; /** Encapsulates the concept of a "transaction" as a unit-of-work. */ public abstract class AbstractUnitOfWork implements UnitOfWork, AutoCloseable { - private static final Logger LOG = LoggerFactory.getLogger(AbstractUnitOfWork.class); + private static final Logger LOG = LoggerFactory.getLogger(AbstractUnitOfWork.class); private final List> nested = new ArrayList<>(); private final HelenusSession session; private final AbstractUnitOfWork parent; // Cache: private final Table cache = HashBasedTable.create(); - private List postCommit = new ArrayList(); - private boolean aborted = false; - private boolean committed = false; protected String purpose; protected int cacheHits = 0; protected int cacheMisses = 0; @@ -51,6 +48,9 @@ public abstract class AbstractUnitOfWork implements UnitOfW protected Stopwatch elapsedTime; protected Stopwatch databaseTime = Stopwatch.createUnstarted(); protected Stopwatch cacheLookupTime = Stopwatch.createUnstarted(); + private List postCommit = new ArrayList(); + private boolean aborted = false; + private boolean committed = false; protected AbstractUnitOfWork(HelenusSession session, AbstractUnitOfWork parent) { Objects.requireNonNull(session, "containing session cannot be null"); @@ -90,16 +90,16 @@ public abstract class AbstractUnitOfWork implements UnitOfW } @Override - public void record(int cache, int ops) { - if (cache > 0) { - cacheHits += cache; - } else { - cacheMisses += Math.abs(cache); - } - if (ops > 0) { - databaseLookups += ops; - } - } + public void record(int cache, int ops) { + if (cache > 0) { + cacheHits += cache; + } else { + cacheMisses += Math.abs(cache); + } + if (ops > 0) { + databaseLookups += ops; + } + } public String logTimers(String what) { double e = (double) elapsedTime.elapsed(TimeUnit.MICROSECONDS) / 1000.0; @@ -109,12 +109,13 @@ public abstract class AbstractUnitOfWork implements UnitOfW double fc = (c / e) * 100.0; double dat = d + c; double daf = (dat / e) * 100; - String nested = this.nested.stream().map(uow -> String.valueOf(uow.hashCode())).collect(Collectors.joining(", ")); - return String.format(Locale.US, "UOW(%s%s) %s (total: %,.3fms cache: %,.3fms %,2.2f%% (%,d hit, %,d miss) %,d database operation%s took %,.3fms %,2.2f%% [%,.3fms %,2.2f%%])%s", - hashCode(), - (this.nested.size() > 0 ? ", [" + nested + "]" : ""), - what, e, c, fc, cacheHits, cacheMisses, databaseLookups, (databaseLookups > 1) ? "s" : "", - d, fd, dat, daf, (purpose == null ? "" : " in " + purpose)); + String nested = this.nested.stream().map(uow -> String.valueOf(uow.hashCode())) + .collect(Collectors.joining(", ")); + return String.format(Locale.US, + "UOW(%s%s) %s (total: %,.3fms cache: %,.3fms %,2.2f%% (%,d hit, %,d miss) %,d database operation%s took %,.3fms %,2.2f%% [%,.3fms %,2.2f%%])%s", + hashCode(), (this.nested.size() > 0 ? ", [" + nested + "]" : ""), what, e, c, fc, cacheHits, + cacheMisses, databaseLookups, (databaseLookups > 1) ? "s" : "", d, fd, dat, daf, + (purpose == null ? "" : " in " + purpose)); } private void applyPostCommitFunctions() { @@ -124,8 +125,8 @@ public abstract class AbstractUnitOfWork implements UnitOfW } } if (LOG.isInfoEnabled()) { - LOG.info(logTimers("committed")); - } + LOG.info(logTimers("committed")); + } } @Override @@ -238,8 +239,8 @@ public abstract class AbstractUnitOfWork implements UnitOfW if (!hasAborted()) { elapsedTime.stop(); if (LOG.isInfoEnabled()) { - LOG.info(logTimers("aborted")); - } + LOG.info(logTimers("aborted")); + } } } diff --git a/src/main/java/net/helenus/core/HelenusSession.java b/src/main/java/net/helenus/core/HelenusSession.java index 5df40fb..19bf7d2 100644 --- a/src/main/java/net/helenus/core/HelenusSession.java +++ b/src/main/java/net/helenus/core/HelenusSession.java @@ -27,6 +27,9 @@ import java.util.concurrent.TimeUnit; import java.util.function.Function; import java.util.stream.Collectors; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.codahale.metrics.MetricRegistry; import com.datastax.driver.core.*; import com.google.common.cache.Cache; @@ -42,6 +45,7 @@ import net.helenus.core.reflect.Drafted; import net.helenus.core.reflect.HelenusPropertyNode; import net.helenus.core.reflect.MapExportable; import net.helenus.mapping.HelenusEntity; +import net.helenus.mapping.HelenusProperty; import net.helenus.mapping.MappingUtil; import net.helenus.mapping.value.*; import net.helenus.support.DslPropertyException; @@ -51,14 +55,12 @@ import net.helenus.support.Fun.Tuple2; import net.helenus.support.Fun.Tuple6; import net.helenus.support.HelenusException; import net.helenus.support.HelenusMappingException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; public final class HelenusSession extends AbstractSessionOperations implements Closeable { - private static final Logger LOG = LoggerFactory.getLogger(HelenusSession.class); + private static final Logger LOG = LoggerFactory.getLogger(HelenusSession.class); - private final int MAX_CACHE_SIZE = 10000; + private final int MAX_CACHE_SIZE = 10000; private final int MAX_CACHE_EXPIRE_SECONDS = 600; private final Session session; @@ -204,14 +206,14 @@ public final class HelenusSession extends AbstractSessionOperations implements C if (facet instanceof UnboundFacet) { UnboundFacet unboundFacet = (UnboundFacet) facet; UnboundFacet.Binder binder = unboundFacet.binder(); - unboundFacet.getProperties().forEach(prop -> { + for (HelenusProperty prop : unboundFacet.getProperties()) { if (valueMap == null) { Object value = BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop, false); binder.setValueForProperty(prop, value.toString()); } else { binder.setValueForProperty(prop, valueMap.get(prop.getPropertyName()).toString()); } - }); + } if (binder.isBound()) { boundFacets.add(binder.bind()); } @@ -293,34 +295,28 @@ public final class HelenusSession extends AbstractSessionOperations implements C } public UnitOfWork begin() { - return this.begin(null); + return this.begin(null); } public synchronized UnitOfWork begin(UnitOfWork parent) { - StringBuilder purpose = null; - if (LOG.isInfoEnabled()) { - StackTraceElement[] trace = Thread.currentThread().getStackTrace(); - int frame = 2; - if (trace[2].getMethodName().equals("begin")) { - frame = 3; - } - purpose = new StringBuilder() - .append(trace[frame].getClassName()) - .append(".") - .append(trace[frame].getMethodName()) - .append("(") - .append(trace[frame].getFileName()) - .append(":") - .append(trace[frame].getLineNumber()) - .append(")"); - } + StringBuilder purpose = null; + if (LOG.isInfoEnabled()) { + StackTraceElement[] trace = Thread.currentThread().getStackTrace(); + int frame = 2; + if (trace[2].getMethodName().equals("begin")) { + frame = 3; + } + purpose = new StringBuilder().append(trace[frame].getClassName()).append(".") + .append(trace[frame].getMethodName()).append("(").append(trace[frame].getFileName()).append(":") + .append(trace[frame].getLineNumber()).append(")"); + } try { Class clazz = unitOfWorkClass; Constructor ctor = clazz.getConstructor(HelenusSession.class, UnitOfWork.class); UnitOfWork uow = ctor.newInstance(this, parent); - if (LOG.isInfoEnabled()) { - uow.setPurpose(purpose.toString()); - } + if (LOG.isInfoEnabled()) { + uow.setPurpose(purpose.toString()); + } if (parent != null) { parent.addNestedUnitOfWork(uow); } diff --git a/src/main/java/net/helenus/core/UnitOfWork.java b/src/main/java/net/helenus/core/UnitOfWork.java index 96125c3..29c66ea 100644 --- a/src/main/java/net/helenus/core/UnitOfWork.java +++ b/src/main/java/net/helenus/core/UnitOfWork.java @@ -65,6 +65,6 @@ public interface UnitOfWork extends AutoCloseable { Stopwatch getCacheLookupTimer(); - void record(int cache, int ops); + void record(int cache, int ops); } diff --git a/src/main/java/net/helenus/core/operation/AbstractStatementOperation.java b/src/main/java/net/helenus/core/operation/AbstractStatementOperation.java index e0315de..cd433dd 100644 --- a/src/main/java/net/helenus/core/operation/AbstractStatementOperation.java +++ b/src/main/java/net/helenus/core/operation/AbstractStatementOperation.java @@ -44,7 +44,7 @@ import net.helenus.mapping.value.BeanColumnValueProvider; import net.helenus.support.HelenusException; public abstract class AbstractStatementOperation> extends Operation { - + protected boolean enableCache = true; protected boolean showValues = true; protected TraceContext traceContext; @@ -323,14 +323,14 @@ public abstract class AbstractStatementOperation properties = unboundFacet.getProperties(); - if (properties != null) { - properties.forEach(prop -> { - if (valueMap == null) { - Object value = BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop, false); - binder.setValueForProperty(prop, value.toString()); - } else { - binder.setValueForProperty(prop, valueMap.get(prop.getPropertyName()).toString()); - } - }); - if (binder.isBound()) { - facets.add(binder.bind()); - } + for (HelenusProperty prop : unboundFacet.getProperties()) { + if (valueMap == null) { + Object value = BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop, false); + binder.setValueForProperty(prop, value.toString()); + } else { + binder.setValueForProperty(prop, valueMap.get(prop.getPropertyName()).toString()); + } + } + if (binder.isBound()) { + facets.add(binder.bind()); } } else { facets.add(facet); diff --git a/src/main/java/net/helenus/core/operation/Operation.java b/src/main/java/net/helenus/core/operation/Operation.java index 8115bc7..2a2fef7 100644 --- a/src/main/java/net/helenus/core/operation/Operation.java +++ b/src/main/java/net/helenus/core/operation/Operation.java @@ -73,7 +73,8 @@ public abstract class Operation { timer.start(); } ResultSetFuture futureResultSet = session.executeAsync(statement, uow, showValues); - if (uow != null) uow.record(0, 1); + if (uow != null) + uow.record(0, 1); ResultSet resultSet = futureResultSet.getUninterruptibly(); // TODO(gburd): (timeout, units); if (uow != null) diff --git a/src/main/java/net/helenus/core/operation/SelectOperation.java b/src/main/java/net/helenus/core/operation/SelectOperation.java index bc658f2..58b790b 100644 --- a/src/main/java/net/helenus/core/operation/SelectOperation.java +++ b/src/main/java/net/helenus/core/operation/SelectOperation.java @@ -38,6 +38,7 @@ import net.helenus.core.cache.Facet; import net.helenus.core.cache.UnboundFacet; import net.helenus.core.reflect.HelenusPropertyNode; import net.helenus.mapping.HelenusEntity; +import net.helenus.mapping.HelenusProperty; import net.helenus.mapping.MappingUtil; import net.helenus.mapping.OrderingDirection; import net.helenus.mapping.value.ColumnValueProvider; @@ -206,16 +207,18 @@ public final class SelectOperation extends AbstractFilterStreamOperation { - Filter filter = filters.get(prop); - if (filter != null) { - Object[] postulates = filter.postulateValues(); - for (Object p : postulates) { - binder.setValueForProperty(prop, p.toString()); + for (HelenusProperty prop : unboundFacet.getProperties()) { + if (filters != null) { + Filter filter = filters.get(prop); + if (filter != null) { + Object[] postulates = filter.postulateValues(); + for (Object p : postulates) { + binder.setValueForProperty(prop, p.toString()); + } } } - }); + } if (binder.isBound()) { boundFacets.add(binder.bind()); } diff --git a/src/main/java/net/helenus/mapping/HelenusMappingEntity.java b/src/main/java/net/helenus/mapping/HelenusMappingEntity.java index 8869761..7785da2 100644 --- a/src/main/java/net/helenus/mapping/HelenusMappingEntity.java +++ b/src/main/java/net/helenus/mapping/HelenusMappingEntity.java @@ -15,11 +15,11 @@ */ package net.helenus.mapping; -import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.util.*; -import net.helenus.mapping.validator.DistinctValidator; +import javax.validation.ConstraintValidator; + import org.apache.commons.lang3.ClassUtils; import com.datastax.driver.core.DefaultMetadata; @@ -33,10 +33,9 @@ import net.helenus.core.annotation.Cacheable; import net.helenus.core.cache.Facet; import net.helenus.core.cache.UnboundFacet; import net.helenus.mapping.annotation.*; +import net.helenus.mapping.validator.DistinctValidator; import net.helenus.support.HelenusMappingException; -import javax.validation.ConstraintValidator; - public final class HelenusMappingEntity implements HelenusEntity { private final Class iface; @@ -129,11 +128,12 @@ public final class HelenusMappingEntity implements HelenusEntity { facetsBuilder.add(new UnboundFacet(primaryKeyProperties)); primaryKeyProperties = null; } - for (ConstraintValidator constraint : MappingUtil.getValidators(prop.getGetterMethod())) { - if (constraint.getClass().isAssignableFrom(DistinctValidator.class)); - UnboundFacet facet = new UnboundFacet(prop); - facetsBuilder.add(facet); - break; + for (ConstraintValidator constraint : MappingUtil.getValidators(prop.getGetterMethod())) { + if (constraint.getClass().isAssignableFrom(DistinctValidator.class)) + ; + UnboundFacet facet = new UnboundFacet(prop); + facetsBuilder.add(facet); + break; } } } diff --git a/src/main/java/net/helenus/mapping/annotation/Constraints.java b/src/main/java/net/helenus/mapping/annotation/Constraints.java index 1013015..14961b7 100644 --- a/src/main/java/net/helenus/mapping/annotation/Constraints.java +++ b/src/main/java/net/helenus/mapping/annotation/Constraints.java @@ -222,59 +222,59 @@ public final class Constraints { public @interface UpperCase { } - /** - * Pattern annotation is LowerCase annotation is using to ensure that value is - * upper case before storing it - * - *

- * Can be used only for @java.lang.CharSequence - * - *

- * It does not have effect on selects and data retrieval operations - */ - @Documented - @Retention(RetentionPolicy.RUNTIME) - @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) - @Constraint(validatedBy = PatternValidator.class) - public @interface Pattern { + /** + * Pattern annotation is LowerCase annotation is using to ensure that value is + * upper case before storing it + * + *

+ * Can be used only for @java.lang.CharSequence + * + *

+ * It does not have effect on selects and data retrieval operations + */ + @Documented + @Retention(RetentionPolicy.RUNTIME) + @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) + @Constraint(validatedBy = PatternValidator.class) + public @interface Pattern { - /** - * User defined regex expression to check match of the value - * - * @return Java regex pattern - */ - String value(); + /** + * User defined regex expression to check match of the value + * + * @return Java regex pattern + */ + String value(); - /** - * Regex flags composition - * - * @return Java regex flags - */ - int flags(); - } + /** + * Regex flags composition + * + * @return Java regex flags + */ + int flags(); + } - /** - * Distinct annotation is used to signal, but not ensure that a value should be - * distinct in the database. - * - *

- * Can be used only for @java.lang.CharSequence - * - *

- * It does not have effect on selects and data retrieval operations - */ - @Documented - @Retention(RetentionPolicy.RUNTIME) - @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) - @Constraint(validatedBy = DistinctValidator.class) - public @interface Distinct { + /** + * Distinct annotation is used to signal, but not ensure that a value should be + * distinct in the database. + * + *

+ * Can be used only for @java.lang.CharSequence + * + *

+ * It does not have effect on selects and data retrieval operations + */ + @Documented + @Retention(RetentionPolicy.RUNTIME) + @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) + @Constraint(validatedBy = DistinctValidator.class) + public @interface Distinct { - /** - * User defined Enum to further restrict the items in the set. - * - * @return Java - */ - Class value() default Enum.class; + /** + * User defined Enum to further restrict the items in the set. + * + * @return Java + */ + Class value() default Enum.class; - } + } } diff --git a/src/main/java/net/helenus/mapping/annotation/Index.java b/src/main/java/net/helenus/mapping/annotation/Index.java index 6e341c9..f0e59d4 100644 --- a/src/main/java/net/helenus/mapping/annotation/Index.java +++ b/src/main/java/net/helenus/mapping/annotation/Index.java @@ -66,9 +66,9 @@ public @interface Index { */ boolean caseSensitive() default true; - /** - * - * @return - */ - boolean distinct() default false; + /** + * + * @return + */ + boolean distinct() default false; } diff --git a/src/main/java/net/helenus/mapping/validator/DistinctValidator.java b/src/main/java/net/helenus/mapping/validator/DistinctValidator.java index cedcec9..1dc1778 100644 --- a/src/main/java/net/helenus/mapping/validator/DistinctValidator.java +++ b/src/main/java/net/helenus/mapping/validator/DistinctValidator.java @@ -15,8 +15,6 @@ */ package net.helenus.mapping.validator; -import java.util.regex.Pattern; - import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; @@ -24,13 +22,14 @@ import net.helenus.mapping.annotation.Constraints; public final class DistinctValidator implements ConstraintValidator { - @Override - public void initialize(Constraints.Distinct constraintAnnotation) { - } + @Override + public void initialize(Constraints.Distinct constraintAnnotation) { + } - @Override - public boolean isValid(CharSequence value, ConstraintValidatorContext context) { - //TODO(gburd): if there is an Enum type supplied, check that value is valid Enum.name() - return true; - } + @Override + public boolean isValid(CharSequence value, ConstraintValidatorContext context) { + // TODO(gburd): if there is an Enum type supplied, check that value is valid + // Enum.name() + return true; + } } From 18f2a057dea6784395251e72a27f0e2e94da7307 Mon Sep 17 00:00:00 2001 From: Greg Burd Date: Tue, 24 Oct 2017 16:01:48 -0400 Subject: [PATCH 05/18] Refining logging. --- .../core/AbstractSessionOperations.java | 52 ++++++++++++----- .../net/helenus/core/AbstractUnitOfWork.java | 37 ++++++------ .../java/net/helenus/core/UnitOfWork.java | 10 ++-- .../operation/AbstractOptionalOperation.java | 57 ++++++++++++------- .../operation/AbstractStatementOperation.java | 7 --- .../operation/AbstractStreamOperation.java | 47 +++++++++++---- .../net/helenus/core/operation/Operation.java | 41 +++++++------ 7 files changed, 162 insertions(+), 89 deletions(-) diff --git a/src/main/java/net/helenus/core/AbstractSessionOperations.java b/src/main/java/net/helenus/core/AbstractSessionOperations.java index 9352367..0ab6fc3 100644 --- a/src/main/java/net/helenus/core/AbstractSessionOperations.java +++ b/src/main/java/net/helenus/core/AbstractSessionOperations.java @@ -18,7 +18,9 @@ package net.helenus.core; import java.io.PrintStream; import java.util.List; import java.util.concurrent.Executor; +import java.util.concurrent.TimeUnit; +import com.google.common.base.Stopwatch; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -60,7 +62,7 @@ public abstract class AbstractSessionOperations { public PreparedStatement prepare(RegularStatement statement) { try { - log(statement, null, false); + log(statement, null, null, false); return currentSession().prepare(statement); } catch (RuntimeException e) { throw translateException(e); @@ -69,41 +71,61 @@ public abstract class AbstractSessionOperations { public ListenableFuture prepareAsync(RegularStatement statement) { try { - log(statement, null, false); + log(statement, null, null, false); return currentSession().prepareAsync(statement); } catch (RuntimeException e) { throw translateException(e); } } - public ResultSet execute(Statement statement, boolean showValues) { - return execute(statement, null, showValues); + public ResultSet execute(Statement statement, boolean showValues) { + return execute(statement, null, null, showValues); + } + + public ResultSet execute(Statement statement, Stopwatch timer, boolean showValues) { + return execute(statement, null, timer, showValues); + } + + public ResultSet execute(Statement statement, UnitOfWork uow, boolean showValues) { + return execute(statement, uow, null, showValues); + } + + public ResultSet execute(Statement statement, UnitOfWork uow, Stopwatch timer, boolean showValues) { + return executeAsync(statement, uow, timer, showValues).getUninterruptibly(); } - public ResultSet execute(Statement statement, UnitOfWork uow, boolean showValues) { - return executeAsync(statement, uow, showValues).getUninterruptibly(); - } + public ResultSetFuture executeAsync(Statement statement, boolean showValues) { + return executeAsync(statement, null, null, showValues); + } - public ResultSetFuture executeAsync(Statement statement, boolean showValues) { - return executeAsync(statement, null, showValues); - } + public ResultSetFuture executeAsync(Statement statement, Stopwatch timer, boolean showValues) { + return executeAsync(statement, null, timer, showValues); + } - public ResultSetFuture executeAsync(Statement statement, UnitOfWork uow, boolean showValues) { + public ResultSetFuture executeAsync(Statement statement, UnitOfWork uow, boolean showValues) { + return executeAsync(statement, uow, null, showValues); + } + + public ResultSetFuture executeAsync(Statement statement, UnitOfWork uow, Stopwatch timer, boolean showValues) { try { - log(statement, uow, showValues); + log(statement, uow, timer, showValues); return currentSession().executeAsync(statement); } catch (RuntimeException e) { throw translateException(e); } } - void log(Statement statement, UnitOfWork uow, boolean showValues) { + void log(Statement statement, UnitOfWork uow, Stopwatch timer, boolean showValues) { if (LOG.isInfoEnabled()) { + String timerString = ""; String uowString = ""; if (uow != null) { - uowString = "within UOW(" + uow.hashCode() + "): "; + uowString = (timer != null) ? " " : "" + "UOW(" + uow.hashCode() + ")"; } - LOG.info(String.format("Execute statement %s%s", uowString, statement)); + if (timer != null) { + timerString = String.format(" %s", timer.toString()); + } + LOG.info(String.format("CQL%s%s - %s", uowString, timerString, statement)); } if (isShowCql()) { if (statement instanceof BuiltStatement) { diff --git a/src/main/java/net/helenus/core/AbstractUnitOfWork.java b/src/main/java/net/helenus/core/AbstractUnitOfWork.java index eb0d657..a291390 100644 --- a/src/main/java/net/helenus/core/AbstractUnitOfWork.java +++ b/src/main/java/net/helenus/core/AbstractUnitOfWork.java @@ -46,8 +46,8 @@ public abstract class AbstractUnitOfWork implements UnitOfW protected int cacheMisses = 0; protected int databaseLookups = 0; protected Stopwatch elapsedTime; - protected Stopwatch databaseTime = Stopwatch.createUnstarted(); - protected Stopwatch cacheLookupTime = Stopwatch.createUnstarted(); + protected Map databaseTime = new HashMap<>(); + protected double cacheLookupTime = 0.0; private List postCommit = new ArrayList(); private boolean aborted = false; private boolean committed = false; @@ -60,14 +60,19 @@ public abstract class AbstractUnitOfWork implements UnitOfW } @Override - public Stopwatch getExecutionTimer() { - return databaseTime; - } + public void addDatabaseTime(String name, Stopwatch amount) { + Double time = databaseTime.get(name); + if (time == null) { + databaseTime.put(name, (double)amount.elapsed(TimeUnit.MICROSECONDS)); + } else { + databaseTime.put(name, time + amount.elapsed(TimeUnit.MICROSECONDS)); + } + } - @Override - public Stopwatch getCacheLookupTimer() { - return cacheLookupTime; - } + @Override + public void addCacheLookupTime(Stopwatch amount) { + cacheLookupTime += amount.elapsed(TimeUnit.MICROSECONDS); + } @Override public void addNestedUnitOfWork(UnitOfWork uow) { @@ -79,7 +84,7 @@ public abstract class AbstractUnitOfWork implements UnitOfW @Override public UnitOfWork begin() { elapsedTime = Stopwatch.createStarted(); - // log.record(txn::start) + // log.recordCacheAndDatabaseOperationCount(txn::start) return this; } @@ -90,7 +95,7 @@ public abstract class AbstractUnitOfWork implements UnitOfW } @Override - public void record(int cache, int ops) { + public void recordCacheAndDatabaseOperationCount(int cache, int ops) { if (cache > 0) { cacheHits += cache; } else { @@ -103,8 +108,8 @@ public abstract class AbstractUnitOfWork implements UnitOfW public String logTimers(String what) { double e = (double) elapsedTime.elapsed(TimeUnit.MICROSECONDS) / 1000.0; - double d = (double) databaseTime.elapsed(TimeUnit.MICROSECONDS) / 1000.0; - double c = (double) cacheLookupTime.elapsed(TimeUnit.MICROSECONDS) / 1000.0; + double d = databaseTime.containsKey("Cassandra") ? databaseTime.get("Cassandra") / 1000.0 : 0.0; + double c = cacheLookupTime / 1000.0; double fd = (d / e) * 100.0; double fc = (c / e) * 100.0; double dat = d + c; @@ -112,7 +117,7 @@ public abstract class AbstractUnitOfWork implements UnitOfW String nested = this.nested.stream().map(uow -> String.valueOf(uow.hashCode())) .collect(Collectors.joining(", ")); return String.format(Locale.US, - "UOW(%s%s) %s (total: %,.3fms cache: %,.3fms %,2.2f%% (%,d hit, %,d miss) %,d database operation%s took %,.3fms %,2.2f%% [%,.3fms %,2.2f%%])%s", + "UOW(%s%s) %s (total: %,.3fms cache: %,.3fms %,2.2f%% (%,d hit, %,d miss) %,d Cassandra operation%s took %,.3fms %,2.2f%% [%,.3fms %,2.2f%%])%s", hashCode(), (this.nested.size() > 0 ? ", [" + nested + "]" : ""), what, e, c, fc, cacheHits, cacheMisses, databaseLookups, (databaseLookups > 1) ? "s" : "", d, fd, dat, daf, (purpose == null ? "" : " in " + purpose)); @@ -191,7 +196,7 @@ public abstract class AbstractUnitOfWork implements UnitOfW } } - // log.record(txn::provisionalCommit) + // log.recordCacheAndDatabaseOperationCount(txn::provisionalCommit) // examine log for conflicts in read-set and write-set between begin and // provisional commit // if (conflict) { throw new ConflictingUnitOfWorkException(this) } @@ -234,7 +239,7 @@ public abstract class AbstractUnitOfWork implements UnitOfW uow.committed = false; uow.aborted = true; }); - // log.record(txn::abort) + // log.recordCacheAndDatabaseOperationCount(txn::abort) // cache.invalidateSince(txn::start time) if (!hasAborted()) { elapsedTime.stop(); diff --git a/src/main/java/net/helenus/core/UnitOfWork.java b/src/main/java/net/helenus/core/UnitOfWork.java index 29c66ea..6b4161e 100644 --- a/src/main/java/net/helenus/core/UnitOfWork.java +++ b/src/main/java/net/helenus/core/UnitOfWork.java @@ -25,7 +25,7 @@ import net.helenus.core.cache.Facet; public interface UnitOfWork extends AutoCloseable { /** - * Marks the beginning of a transactional section of work. Will write a record + * Marks the beginning of a transactional section of work. Will write a recordCacheAndDatabaseOperationCount * to the shared write-ahead log. * * @return the handle used to commit or abort the work. @@ -61,10 +61,10 @@ public interface UnitOfWork extends AutoCloseable { UnitOfWork setPurpose(String purpose); - Stopwatch getExecutionTimer(); + void addDatabaseTime(String name, Stopwatch amount); + void addCacheLookupTime(Stopwatch amount); - Stopwatch getCacheLookupTimer(); - - void record(int cache, int ops); + // Cache > 0 means "cache hit", < 0 means cache miss. + void recordCacheAndDatabaseOperationCount(int cache, int database); } diff --git a/src/main/java/net/helenus/core/operation/AbstractOptionalOperation.java b/src/main/java/net/helenus/core/operation/AbstractOptionalOperation.java index fb37c63..6c23eb5 100644 --- a/src/main/java/net/helenus/core/operation/AbstractOptionalOperation.java +++ b/src/main/java/net/helenus/core/operation/AbstractOptionalOperation.java @@ -71,7 +71,12 @@ public abstract class AbstractOptionalOperation result = Optional.empty(); - E cacheResult = null; + E cachedResult = null; boolean updateCache = true; if (enableCache) { - Stopwatch timer = uow.getCacheLookupTimer(); - timer.start(); - List facets = bindFacetValues(); - cacheResult = checkCache(uow, facets); - if (cacheResult != null) { - result = Optional.of(cacheResult); - updateCache = false; - } else { - if (isSessionCacheable()) { - String tableName = CacheUtil.schemaName(facets); - cacheResult = (E) sessionOps.checkCache(tableName, facets); - if (cacheResult != null) { - result = Optional.of(cacheResult); - } - } - } - timer.stop(); + Stopwatch timer = Stopwatch.createStarted(); + try { + List facets = bindFacetValues(); + cachedResult = checkCache(uow, facets); + if (cachedResult != null) { + result = Optional.of(cachedResult); + updateCache = false; + uowCacheHits.mark(); + cacheHits.mark(); + uow.recordCacheAndDatabaseOperationCount(1, 0); + } else { + uowCacheMiss.mark(); + if (isSessionCacheable()) { + String tableName = CacheUtil.schemaName(facets); + cachedResult = (E) sessionOps.checkCache(tableName, facets); + if (cachedResult != null) { + result = Optional.of(cachedResult); + sessionCacheHits.mark(); + cacheHits.mark(); + uow.recordCacheAndDatabaseOperationCount(1, 0); + } else { + sessionCacheMiss.mark(); + cacheMiss.mark(); + uow.recordCacheAndDatabaseOperationCount(-1, 0); + } + } + } + } finally { + timer.stop(); + uow.addCacheLookupTime(timer); + } } if (!result.isPresent()) { diff --git a/src/main/java/net/helenus/core/operation/AbstractStatementOperation.java b/src/main/java/net/helenus/core/operation/AbstractStatementOperation.java index cd433dd..1b08a4c 100644 --- a/src/main/java/net/helenus/core/operation/AbstractStatementOperation.java +++ b/src/main/java/net/helenus/core/operation/AbstractStatementOperation.java @@ -322,17 +322,10 @@ public abstract class AbstractStatementOperation facets = bindFacetValues(); - cachedResult = checkCache(uow, facets); - if (cachedResult != null) { - resultStream = Stream.of(cachedResult); - updateCache = false; - } - timer.stop(); + Stopwatch timer = Stopwatch.createStarted(); + try { + List facets = bindFacetValues(); + cachedResult = checkCache(uow, facets); + if (cachedResult != null) { + resultStream = Stream.of(cachedResult); + updateCache = false; + uowCacheHits.mark(); + cacheHits.mark(); + uow.recordCacheAndDatabaseOperationCount(1, 0); + } else { + uowCacheMiss.mark(); + if (isSessionCacheable()) { + String tableName = CacheUtil.schemaName(facets); + cachedResult = (E) sessionOps.checkCache(tableName, facets); + if (cachedResult != null) { + resultStream = Stream.of(cachedResult); + sessionCacheHits.mark(); + cacheHits.mark(); + uow.recordCacheAndDatabaseOperationCount(1, 0); + } else { + sessionCacheMiss.mark(); + cacheMiss.mark(); + uow.recordCacheAndDatabaseOperationCount(-1, 0); + } + } + } + } finally { + timer.stop(); + uow.addCacheLookupTime(timer); + } } if (resultStream == null) { diff --git a/src/main/java/net/helenus/core/operation/Operation.java b/src/main/java/net/helenus/core/operation/Operation.java index 2a2fef7..89f673f 100644 --- a/src/main/java/net/helenus/core/operation/Operation.java +++ b/src/main/java/net/helenus/core/operation/Operation.java @@ -36,15 +36,23 @@ import net.helenus.core.cache.Facet; public abstract class Operation { protected final AbstractSessionOperations sessionOps; - protected final Meter uowCacheHits; - protected final Meter uowCacheMiss; + protected final Meter uowCacheHits; + protected final Meter uowCacheMiss; + protected final Meter sessionCacheHits; + protected final Meter sessionCacheMiss; + protected final Meter cacheHits; + protected final Meter cacheMiss; protected final Timer requestLatency; Operation(AbstractSessionOperations sessionOperations) { this.sessionOps = sessionOperations; MetricRegistry metrics = sessionOperations.getMetricRegistry(); - this.uowCacheHits = metrics.meter("net.helenus.UOW-cache-hits"); - this.uowCacheMiss = metrics.meter("net.helenus.UOW-cache-miss"); + this.uowCacheHits = metrics.meter("net.helenus.UOW-cache-hits"); + this.uowCacheMiss = metrics.meter("net.helenus.UOW-cache-miss"); + this.sessionCacheHits = metrics.meter("net.helenus.session-cache-hits"); + this.sessionCacheMiss = metrics.meter("net.helenus.session-cache-miss"); + this.cacheHits = metrics.meter("net.helenus.cache-hits"); + this.cacheMiss = metrics.meter("net.helenus.cache-miss"); this.requestLatency = metrics.timer("net.helenus.request-latency"); } @@ -67,20 +75,19 @@ public abstract class Operation { } Statement statement = options(buildStatement(cached)); - Stopwatch timer = null; - if (uow != null) { - timer = uow.getExecutionTimer(); - timer.start(); - } - ResultSetFuture futureResultSet = session.executeAsync(statement, uow, showValues); - if (uow != null) - uow.record(0, 1); - ResultSet resultSet = futureResultSet.getUninterruptibly(); // TODO(gburd): (timeout, units); + Stopwatch timer = Stopwatch.createStarted(); + try { + ResultSetFuture futureResultSet = session.executeAsync(statement, uow, timer, showValues); + if (uow != null) + uow.recordCacheAndDatabaseOperationCount(0, 1); + ResultSet resultSet = futureResultSet.getUninterruptibly(); // TODO(gburd): (timeout, units); + return resultSet; - if (uow != null) - timer.stop(); - - return resultSet; + } finally { + timer.stop(); + if (uow != null) + uow.addDatabaseTime("Cassandra", timer); + } } finally { From 8a7dbfdec16dcc65f386775c8ffd0a8ad02976e4 Mon Sep 17 00:00:00 2001 From: Greg Burd Date: Tue, 24 Oct 2017 21:07:47 -0400 Subject: [PATCH 06/18] Implement missing getFacets() methods. Clean up some logic. --- .../core/AbstractSessionOperations.java | 49 +++++++------ .../net/helenus/core/AbstractUnitOfWork.java | 24 +++---- .../java/net/helenus/core/HelenusSession.java | 10 ++- .../java/net/helenus/core/UnitOfWork.java | 8 +-- .../core/operation/AbstractOperation.java | 4 -- .../operation/AbstractOptionalOperation.java | 68 +++++++++---------- .../operation/AbstractStatementOperation.java | 12 +++- .../operation/AbstractStreamOperation.java | 64 ++++++++--------- .../core/operation/InsertOperation.java | 11 +++ .../net/helenus/core/operation/Operation.java | 47 ++++++------- .../core/operation/UpdateOperation.java | 11 +++ .../helenus/mapping/HelenusMappingEntity.java | 10 +-- 12 files changed, 173 insertions(+), 145 deletions(-) diff --git a/src/main/java/net/helenus/core/AbstractSessionOperations.java b/src/main/java/net/helenus/core/AbstractSessionOperations.java index 0ab6fc3..c163f7f 100644 --- a/src/main/java/net/helenus/core/AbstractSessionOperations.java +++ b/src/main/java/net/helenus/core/AbstractSessionOperations.java @@ -18,15 +18,14 @@ package net.helenus.core; import java.io.PrintStream; import java.util.List; import java.util.concurrent.Executor; -import java.util.concurrent.TimeUnit; -import com.google.common.base.Stopwatch; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.codahale.metrics.MetricRegistry; import com.datastax.driver.core.*; import com.datastax.driver.core.querybuilder.BuiltStatement; +import com.google.common.base.Stopwatch; import com.google.common.collect.Table; import com.google.common.util.concurrent.ListenableFuture; @@ -78,35 +77,35 @@ public abstract class AbstractSessionOperations { } } - public ResultSet execute(Statement statement, boolean showValues) { - return execute(statement, null, null, showValues); - } + public ResultSet execute(Statement statement, boolean showValues) { + return execute(statement, null, null, showValues); + } - public ResultSet execute(Statement statement, Stopwatch timer, boolean showValues) { - return execute(statement, null, timer, showValues); - } + public ResultSet execute(Statement statement, Stopwatch timer, boolean showValues) { + return execute(statement, null, timer, showValues); + } - public ResultSet execute(Statement statement, UnitOfWork uow, boolean showValues) { - return execute(statement, uow, null, showValues); - } + public ResultSet execute(Statement statement, UnitOfWork uow, boolean showValues) { + return execute(statement, uow, null, showValues); + } - public ResultSet execute(Statement statement, UnitOfWork uow, Stopwatch timer, boolean showValues) { + public ResultSet execute(Statement statement, UnitOfWork uow, Stopwatch timer, boolean showValues) { return executeAsync(statement, uow, timer, showValues).getUninterruptibly(); } - public ResultSetFuture executeAsync(Statement statement, boolean showValues) { - return executeAsync(statement, null, null, showValues); - } + public ResultSetFuture executeAsync(Statement statement, boolean showValues) { + return executeAsync(statement, null, null, showValues); + } - public ResultSetFuture executeAsync(Statement statement, Stopwatch timer, boolean showValues) { - return executeAsync(statement, null, timer, showValues); - } + public ResultSetFuture executeAsync(Statement statement, Stopwatch timer, boolean showValues) { + return executeAsync(statement, null, timer, showValues); + } - public ResultSetFuture executeAsync(Statement statement, UnitOfWork uow, boolean showValues) { - return executeAsync(statement, uow, null, showValues); - } + public ResultSetFuture executeAsync(Statement statement, UnitOfWork uow, boolean showValues) { + return executeAsync(statement, uow, null, showValues); + } - public ResultSetFuture executeAsync(Statement statement, UnitOfWork uow, Stopwatch timer, boolean showValues) { + public ResultSetFuture executeAsync(Statement statement, UnitOfWork uow, Stopwatch timer, boolean showValues) { try { log(statement, uow, timer, showValues); return currentSession().executeAsync(statement); @@ -117,14 +116,14 @@ public abstract class AbstractSessionOperations { void log(Statement statement, UnitOfWork uow, Stopwatch timer, boolean showValues) { if (LOG.isInfoEnabled()) { - String timerString = ""; + String timerString = ""; String uowString = ""; if (uow != null) { uowString = (timer != null) ? " " : "" + "UOW(" + uow.hashCode() + ")"; } if (timer != null) { - timerString = String.format(" %s", timer.toString()); - } + timerString = String.format(" %s", timer.toString()); + } LOG.info(String.format("CQL%s%s - %s", uowString, timerString, statement)); } if (isShowCql()) { diff --git a/src/main/java/net/helenus/core/AbstractUnitOfWork.java b/src/main/java/net/helenus/core/AbstractUnitOfWork.java index a291390..73db315 100644 --- a/src/main/java/net/helenus/core/AbstractUnitOfWork.java +++ b/src/main/java/net/helenus/core/AbstractUnitOfWork.java @@ -60,19 +60,19 @@ public abstract class AbstractUnitOfWork implements UnitOfW } @Override - public void addDatabaseTime(String name, Stopwatch amount) { - Double time = databaseTime.get(name); - if (time == null) { - databaseTime.put(name, (double)amount.elapsed(TimeUnit.MICROSECONDS)); - } else { - databaseTime.put(name, time + amount.elapsed(TimeUnit.MICROSECONDS)); - } - } + public void addDatabaseTime(String name, Stopwatch amount) { + Double time = databaseTime.get(name); + if (time == null) { + databaseTime.put(name, (double) amount.elapsed(TimeUnit.MICROSECONDS)); + } else { + databaseTime.put(name, time + amount.elapsed(TimeUnit.MICROSECONDS)); + } + } - @Override - public void addCacheLookupTime(Stopwatch amount) { - cacheLookupTime += amount.elapsed(TimeUnit.MICROSECONDS); - } + @Override + public void addCacheLookupTime(Stopwatch amount) { + cacheLookupTime += amount.elapsed(TimeUnit.MICROSECONDS); + } @Override public void addNestedUnitOfWork(UnitOfWork uow) { diff --git a/src/main/java/net/helenus/core/HelenusSession.java b/src/main/java/net/helenus/core/HelenusSession.java index 19bf7d2..a80989f 100644 --- a/src/main/java/net/helenus/core/HelenusSession.java +++ b/src/main/java/net/helenus/core/HelenusSession.java @@ -207,11 +207,15 @@ public final class HelenusSession extends AbstractSessionOperations implements C UnboundFacet unboundFacet = (UnboundFacet) facet; UnboundFacet.Binder binder = unboundFacet.binder(); for (HelenusProperty prop : unboundFacet.getProperties()) { + Object value; if (valueMap == null) { - Object value = BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop, false); - binder.setValueForProperty(prop, value.toString()); + value = BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop, false); + if (value != null) { + binder.setValueForProperty(prop, value.toString()); + } } else { - binder.setValueForProperty(prop, valueMap.get(prop.getPropertyName()).toString()); + value = valueMap.get(prop.getPropertyName()); + binder.setValueForProperty(prop, value.toString()); } } if (binder.isBound()) { diff --git a/src/main/java/net/helenus/core/UnitOfWork.java b/src/main/java/net/helenus/core/UnitOfWork.java index 6b4161e..e236509 100644 --- a/src/main/java/net/helenus/core/UnitOfWork.java +++ b/src/main/java/net/helenus/core/UnitOfWork.java @@ -25,8 +25,8 @@ import net.helenus.core.cache.Facet; public interface UnitOfWork extends AutoCloseable { /** - * Marks the beginning of a transactional section of work. Will write a recordCacheAndDatabaseOperationCount - * to the shared write-ahead log. + * Marks the beginning of a transactional section of work. Will write a + * recordCacheAndDatabaseOperationCount to the shared write-ahead log. * * @return the handle used to commit or abort the work. */ @@ -61,8 +61,8 @@ public interface UnitOfWork extends AutoCloseable { UnitOfWork setPurpose(String purpose); - void addDatabaseTime(String name, Stopwatch amount); - void addCacheLookupTime(Stopwatch amount); + void addDatabaseTime(String name, Stopwatch amount); + void addCacheLookupTime(Stopwatch amount); // Cache > 0 means "cache hit", < 0 means cache miss. void recordCacheAndDatabaseOperationCount(int cache, int database); diff --git a/src/main/java/net/helenus/core/operation/AbstractOperation.java b/src/main/java/net/helenus/core/operation/AbstractOperation.java index 4afbdc0..82e8fb2 100644 --- a/src/main/java/net/helenus/core/operation/AbstractOperation.java +++ b/src/main/java/net/helenus/core/operation/AbstractOperation.java @@ -31,10 +31,6 @@ public abstract class AbstractOperation> ex public abstract E transform(ResultSet resultSet); - public boolean cacheable() { - return false; - } - public PreparedOperation prepare() { return new PreparedOperation(prepareStatement(), this); } diff --git a/src/main/java/net/helenus/core/operation/AbstractOptionalOperation.java b/src/main/java/net/helenus/core/operation/AbstractOptionalOperation.java index 6c23eb5..ca21e43 100644 --- a/src/main/java/net/helenus/core/operation/AbstractOptionalOperation.java +++ b/src/main/java/net/helenus/core/operation/AbstractOptionalOperation.java @@ -74,9 +74,9 @@ public abstract class AbstractOptionalOperation facets = bindFacetValues(); - cachedResult = checkCache(uow, facets); - if (cachedResult != null) { - result = Optional.of(cachedResult); - updateCache = false; - uowCacheHits.mark(); - cacheHits.mark(); - uow.recordCacheAndDatabaseOperationCount(1, 0); - } else { - uowCacheMiss.mark(); - if (isSessionCacheable()) { - String tableName = CacheUtil.schemaName(facets); - cachedResult = (E) sessionOps.checkCache(tableName, facets); - if (cachedResult != null) { - result = Optional.of(cachedResult); - sessionCacheHits.mark(); - cacheHits.mark(); - uow.recordCacheAndDatabaseOperationCount(1, 0); - } else { - sessionCacheMiss.mark(); - cacheMiss.mark(); - uow.recordCacheAndDatabaseOperationCount(-1, 0); - } - } - } - } finally { - timer.stop(); - uow.addCacheLookupTime(timer); - } + Stopwatch timer = Stopwatch.createStarted(); + try { + List facets = bindFacetValues(); + cachedResult = checkCache(uow, facets); + if (cachedResult != null) { + result = Optional.of(cachedResult); + updateCache = false; + uowCacheHits.mark(); + cacheHits.mark(); + uow.recordCacheAndDatabaseOperationCount(1, 0); + } else { + uowCacheMiss.mark(); + if (isSessionCacheable()) { + String tableName = CacheUtil.schemaName(facets); + cachedResult = (E) sessionOps.checkCache(tableName, facets); + if (cachedResult != null) { + result = Optional.of(cachedResult); + sessionCacheHits.mark(); + cacheHits.mark(); + uow.recordCacheAndDatabaseOperationCount(1, 0); + } else { + sessionCacheMiss.mark(); + cacheMiss.mark(); + uow.recordCacheAndDatabaseOperationCount(-1, 0); + } + } + } + } finally { + timer.stop(); + uow.addCacheLookupTime(timer); + } } if (!result.isPresent()) { diff --git a/src/main/java/net/helenus/core/operation/AbstractStatementOperation.java b/src/main/java/net/helenus/core/operation/AbstractStatementOperation.java index 1b08a4c..ff84180 100644 --- a/src/main/java/net/helenus/core/operation/AbstractStatementOperation.java +++ b/src/main/java/net/helenus/core/operation/AbstractStatementOperation.java @@ -338,11 +338,17 @@ public abstract class AbstractStatementOperation facets = bindFacetValues(); - cachedResult = checkCache(uow, facets); - if (cachedResult != null) { - resultStream = Stream.of(cachedResult); - updateCache = false; - uowCacheHits.mark(); - cacheHits.mark(); - uow.recordCacheAndDatabaseOperationCount(1, 0); - } else { - uowCacheMiss.mark(); - if (isSessionCacheable()) { - String tableName = CacheUtil.schemaName(facets); - cachedResult = (E) sessionOps.checkCache(tableName, facets); - if (cachedResult != null) { - resultStream = Stream.of(cachedResult); - sessionCacheHits.mark(); - cacheHits.mark(); - uow.recordCacheAndDatabaseOperationCount(1, 0); - } else { - sessionCacheMiss.mark(); - cacheMiss.mark(); - uow.recordCacheAndDatabaseOperationCount(-1, 0); - } - } - } - } finally { - timer.stop(); - uow.addCacheLookupTime(timer); - } + List facets = bindFacetValues(); + cachedResult = checkCache(uow, facets); + if (cachedResult != null) { + resultStream = Stream.of(cachedResult); + updateCache = false; + uowCacheHits.mark(); + cacheHits.mark(); + uow.recordCacheAndDatabaseOperationCount(1, 0); + } else { + uowCacheMiss.mark(); + if (isSessionCacheable()) { + String tableName = CacheUtil.schemaName(facets); + cachedResult = (E) sessionOps.checkCache(tableName, facets); + if (cachedResult != null) { + resultStream = Stream.of(cachedResult); + sessionCacheHits.mark(); + cacheHits.mark(); + uow.recordCacheAndDatabaseOperationCount(1, 0); + } else { + sessionCacheMiss.mark(); + cacheMiss.mark(); + uow.recordCacheAndDatabaseOperationCount(-1, 0); + } + } + } + } finally { + timer.stop(); + uow.addCacheLookupTime(timer); + } } if (resultStream == null) { diff --git a/src/main/java/net/helenus/core/operation/InsertOperation.java b/src/main/java/net/helenus/core/operation/InsertOperation.java index fe05cde..24243e5 100644 --- a/src/main/java/net/helenus/core/operation/InsertOperation.java +++ b/src/main/java/net/helenus/core/operation/InsertOperation.java @@ -27,6 +27,7 @@ import net.helenus.core.AbstractSessionOperations; import net.helenus.core.Getter; import net.helenus.core.Helenus; import net.helenus.core.UnitOfWork; +import net.helenus.core.cache.Facet; import net.helenus.core.reflect.DefaultPrimitiveTypes; import net.helenus.core.reflect.Drafted; import net.helenus.core.reflect.HelenusPropertyNode; @@ -246,4 +247,14 @@ public final class InsertOperation extends AbstractOperation getFacets() { + if (entity != null) { + return entity.getFacets(); + } else { + return new ArrayList(); + } + } + } diff --git a/src/main/java/net/helenus/core/operation/Operation.java b/src/main/java/net/helenus/core/operation/Operation.java index 89f673f..193dd82 100644 --- a/src/main/java/net/helenus/core/operation/Operation.java +++ b/src/main/java/net/helenus/core/operation/Operation.java @@ -15,6 +15,7 @@ */ package net.helenus.core.operation; +import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; @@ -36,23 +37,23 @@ import net.helenus.core.cache.Facet; public abstract class Operation { protected final AbstractSessionOperations sessionOps; - protected final Meter uowCacheHits; - protected final Meter uowCacheMiss; - protected final Meter sessionCacheHits; - protected final Meter sessionCacheMiss; - protected final Meter cacheHits; - protected final Meter cacheMiss; + protected final Meter uowCacheHits; + protected final Meter uowCacheMiss; + protected final Meter sessionCacheHits; + protected final Meter sessionCacheMiss; + protected final Meter cacheHits; + protected final Meter cacheMiss; protected final Timer requestLatency; Operation(AbstractSessionOperations sessionOperations) { this.sessionOps = sessionOperations; MetricRegistry metrics = sessionOperations.getMetricRegistry(); - this.uowCacheHits = metrics.meter("net.helenus.UOW-cache-hits"); - this.uowCacheMiss = metrics.meter("net.helenus.UOW-cache-miss"); - this.sessionCacheHits = metrics.meter("net.helenus.session-cache-hits"); - this.sessionCacheMiss = metrics.meter("net.helenus.session-cache-miss"); - this.cacheHits = metrics.meter("net.helenus.cache-hits"); - this.cacheMiss = metrics.meter("net.helenus.cache-miss"); + this.uowCacheHits = metrics.meter("net.helenus.UOW-cache-hits"); + this.uowCacheMiss = metrics.meter("net.helenus.UOW-cache-miss"); + this.sessionCacheHits = metrics.meter("net.helenus.session-cache-hits"); + this.sessionCacheMiss = metrics.meter("net.helenus.session-cache-miss"); + this.cacheHits = metrics.meter("net.helenus.cache-hits"); + this.cacheMiss = metrics.meter("net.helenus.cache-miss"); this.requestLatency = metrics.timer("net.helenus.request-latency"); } @@ -77,17 +78,17 @@ public abstract class Operation { Statement statement = options(buildStatement(cached)); Stopwatch timer = Stopwatch.createStarted(); try { - ResultSetFuture futureResultSet = session.executeAsync(statement, uow, timer, showValues); - if (uow != null) - uow.recordCacheAndDatabaseOperationCount(0, 1); - ResultSet resultSet = futureResultSet.getUninterruptibly(); // TODO(gburd): (timeout, units); - return resultSet; + ResultSetFuture futureResultSet = session.executeAsync(statement, uow, timer, showValues); + if (uow != null) + uow.recordCacheAndDatabaseOperationCount(0, 1); + ResultSet resultSet = futureResultSet.getUninterruptibly(); // TODO(gburd): (timeout, units); + return resultSet; - } finally { - timer.stop(); - if (uow != null) - uow.addDatabaseTime("Cassandra", timer); - } + } finally { + timer.stop(); + if (uow != null) + uow.addDatabaseTime("Cassandra", timer); + } } finally { @@ -106,7 +107,7 @@ public abstract class Operation { } public List getFacets() { - return null; + return new ArrayList(); } public List bindFacetValues() { diff --git a/src/main/java/net/helenus/core/operation/UpdateOperation.java b/src/main/java/net/helenus/core/operation/UpdateOperation.java index 04ed538..4a7f2a3 100644 --- a/src/main/java/net/helenus/core/operation/UpdateOperation.java +++ b/src/main/java/net/helenus/core/operation/UpdateOperation.java @@ -25,6 +25,7 @@ import com.datastax.driver.core.querybuilder.QueryBuilder; import com.datastax.driver.core.querybuilder.Update; import net.helenus.core.*; +import net.helenus.core.cache.Facet; import net.helenus.core.reflect.HelenusPropertyNode; import net.helenus.mapping.HelenusEntity; import net.helenus.mapping.HelenusProperty; @@ -579,4 +580,14 @@ public final class UpdateOperation extends AbstractFilterOperation getFacets() { + if (entity != null) { + return entity.getFacets(); + } else { + return new ArrayList(); + } + } + } diff --git a/src/main/java/net/helenus/mapping/HelenusMappingEntity.java b/src/main/java/net/helenus/mapping/HelenusMappingEntity.java index 7785da2..5872598 100644 --- a/src/main/java/net/helenus/mapping/HelenusMappingEntity.java +++ b/src/main/java/net/helenus/mapping/HelenusMappingEntity.java @@ -129,11 +129,11 @@ public final class HelenusMappingEntity implements HelenusEntity { primaryKeyProperties = null; } for (ConstraintValidator constraint : MappingUtil.getValidators(prop.getGetterMethod())) { - if (constraint.getClass().isAssignableFrom(DistinctValidator.class)) - ; - UnboundFacet facet = new UnboundFacet(prop); - facetsBuilder.add(facet); - break; + if (constraint.getClass().isAssignableFrom(DistinctValidator.class)) { + UnboundFacet facet = new UnboundFacet(prop); + facetsBuilder.add(facet); + break; + } } } } From 7535e9ade70f8fb7e2f4a4709670dbba92f91643 Mon Sep 17 00:00:00 2001 From: Greg Burd Date: Wed, 25 Oct 2017 20:53:12 -0400 Subject: [PATCH 07/18] Improved logging output. Fixed caching for insert, update, delete cases. --- .../core/AbstractSessionOperations.java | 52 +- .../net/helenus/core/AbstractUnitOfWork.java | 166 ++++-- .../java/net/helenus/core/HelenusSession.java | 146 ++--- .../java/net/helenus/core/UnitOfWork.java | 2 + .../operation/AbstractFilterOperation.java | 1 + .../operation/AbstractOptionalOperation.java | 79 +-- .../operation/AbstractStatementOperation.java | 2 +- .../operation/AbstractStreamOperation.java | 84 +-- .../core/operation/DeleteOperation.java | 70 +++ .../core/operation/InsertOperation.java | 11 +- .../net/helenus/core/operation/Operation.java | 68 ++- .../core/operation/SelectOperation.java | 3 +- .../core/operation/UpdateOperation.java | 13 +- .../core/reflect/DslInvocationHandler.java | 42 +- .../build/AbstractEmbeddedCassandraTest.java | 112 ++-- .../integration/core/ContextInitTest.java | 13 +- .../core/HelenusValidatorTest.java | 56 +- .../core/collection/CollectionTest.java | 499 ++++++++---------- .../integration/core/collection/Customer.java | 20 +- .../core/compound/CompondKeyTest.java | 117 ++-- .../integration/core/compound/Timeline.java | 21 +- .../integration/core/counter/CounterTest.java | 54 +- .../test/integration/core/counter/Page.java | 8 +- .../core/draft/EntityDraftBuilderTest.java | 100 ++-- .../integration/core/draft/Inventory.java | 125 ++--- .../test/integration/core/draft/Supply.java | 200 +++---- .../integration/core/hierarchy/Animal.java | 20 +- .../test/integration/core/hierarchy/Cat.java | 6 +- .../core/hierarchy/HierarchyTest.java | 92 ++-- .../integration/core/hierarchy/Mammal.java | 6 +- .../test/integration/core/hierarchy/Pig.java | 4 +- .../test/integration/core/index/Book.java | 14 +- .../core/index/SecondaryIndexTest.java | 42 +- .../test/integration/core/prepared/Car.java | 13 +- .../core/prepared/PreparedStatementTest.java | 137 ++--- .../core/simple/InsertPartialTest.java | 71 +-- .../test/integration/core/simple/Message.java | 30 +- .../core/simple/SimpleUserTest.java | 291 ++++------ .../core/simple/StaticColumnTest.java | 199 +++---- .../test/integration/core/simple/User.java | 15 +- .../integration/core/simple/UserType.java | 3 +- .../integration/core/simple/Username.java | 10 +- .../test/integration/core/tuple/Album.java | 13 +- .../core/tuple/AlbumInformation.java | 8 +- .../test/integration/core/tuple/DslTest.java | 21 +- .../core/tuple/InnerTupleTest.java | 163 +++--- .../test/integration/core/tuple/Photo.java | 2 +- .../integration/core/tuple/PhotoAlbum.java | 6 +- .../integration/core/tuple/PhotoFolder.java | 8 +- .../integration/core/tuple/TupleTest.java | 202 ++++--- .../core/tuplecollection/Author.java | 8 +- .../core/tuplecollection/Book.java | 15 +- .../core/tuplecollection/Section.java | 8 +- .../tuplecollection/TupleCollectionTest.java | 206 ++++---- .../core/tuplecollection/TupleKeyMapTest.java | 159 +++--- .../core/tuplecollection/TupleListTest.java | 194 ++++--- .../core/tuplecollection/TupleMapTest.java | 170 +++--- .../core/tuplecollection/TupleSetTest.java | 129 +++-- .../tuplecollection/TupleValueMapTest.java | 155 +++--- .../core/udtcollection/Author.java | 4 +- .../integration/core/udtcollection/Book.java | 15 +- .../core/udtcollection/Section.java | 4 +- .../core/udtcollection/UDTCollectionTest.java | 208 ++++---- .../core/udtcollection/UDTKeyMapTest.java | 147 +++--- .../core/udtcollection/UDTListTest.java | 194 ++++--- .../core/udtcollection/UDTMapTest.java | 167 +++--- .../core/udtcollection/UDTSetTest.java | 129 +++-- .../core/udtcollection/UDTValueMapTest.java | 147 +++--- .../core/unitofwork/AndThenOrderTest.java | 207 ++++---- .../core/unitofwork/Directory.java | 11 +- .../integration/core/unitofwork/File.java | 7 +- .../core/unitofwork/FileAttributes.java | 2 +- .../core/unitofwork/FilesystemNode.java | 18 +- .../core/unitofwork/UnitOfWorkTest.java | 307 +++++------ .../integration/core/usertype/Account.java | 15 +- .../integration/core/usertype/Address.java | 26 +- .../core/usertype/AddressInformation.java | 4 +- .../integration/core/usertype/Customer.java | 9 +- .../usertype/InnerUserDefinedTypeTest.java | 155 +++--- .../core/usertype/UserDefinedTypeTest.java | 318 +++++------ .../test/integration/core/views/Cyclist.java | 23 +- .../integration/core/views/CyclistsByAge.java | 20 +- .../core/views/MaterializedViewTest.java | 73 ++- .../core/dsl/CachedElevatorImpl.java | 99 ++-- .../test/performance/core/dsl/Elevator.java | 6 +- .../performance/core/dsl/ElevatorImpl.java | 73 +-- .../performance/core/dsl/MappingTest.java | 126 ++--- .../helenus/test/unit/core/dsl/Account.java | 51 +- .../unit/core/dsl/AccountWithCollections.java | 20 +- .../unit/core/dsl/CollectionsDlsTest.java | 73 +-- .../helenus/test/unit/core/dsl/DslTest.java | 31 +- .../helenus/test/unit/core/dsl/Rocket.java | 4 +- .../unit/core/dsl/UDTCollectionsDlsTest.java | 46 +- .../test/unit/core/dsl/WrapperTest.java | 66 +-- .../test/unit/core/dsl/WrongAccount.java | 2 +- .../test/unit/support/ImmutablesTest.java | 114 ++-- .../test/unit/support/TransformersTest.java | 98 ++-- .../log4j-embedded-cassandra.properties | 6 +- src/test/resources/logging.properties | 2 +- 99 files changed, 3696 insertions(+), 3815 deletions(-) diff --git a/src/main/java/net/helenus/core/AbstractSessionOperations.java b/src/main/java/net/helenus/core/AbstractSessionOperations.java index c163f7f..80c3fbf 100644 --- a/src/main/java/net/helenus/core/AbstractSessionOperations.java +++ b/src/main/java/net/helenus/core/AbstractSessionOperations.java @@ -17,20 +17,22 @@ package net.helenus.core; import java.io.PrintStream; import java.util.List; +import java.util.Set; import java.util.concurrent.Executor; +import net.helenus.support.Either; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.codahale.metrics.MetricRegistry; import com.datastax.driver.core.*; -import com.datastax.driver.core.querybuilder.BuiltStatement; import com.google.common.base.Stopwatch; import com.google.common.collect.Table; import com.google.common.util.concurrent.ListenableFuture; import brave.Tracer; 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.HelenusException; @@ -61,7 +63,7 @@ public abstract class AbstractSessionOperations { public PreparedStatement prepare(RegularStatement statement) { try { - log(statement, null, null, false); + logStatement(statement, false); return currentSession().prepare(statement); } catch (RuntimeException e) { throw translateException(e); @@ -70,7 +72,7 @@ public abstract class AbstractSessionOperations { public ListenableFuture prepareAsync(RegularStatement statement) { try { - log(statement, null, null, false); + logStatement(statement, false); return currentSession().prepareAsync(statement); } catch (RuntimeException e) { throw translateException(e); @@ -107,42 +109,20 @@ public abstract class AbstractSessionOperations { public ResultSetFuture executeAsync(Statement statement, UnitOfWork uow, Stopwatch timer, boolean showValues) { try { - log(statement, uow, timer, showValues); + logStatement(statement, showValues); return currentSession().executeAsync(statement); } catch (RuntimeException e) { throw translateException(e); } } - void log(Statement statement, UnitOfWork uow, Stopwatch timer, boolean showValues) { - if (LOG.isInfoEnabled()) { - String timerString = ""; - String uowString = ""; - if (uow != null) { - uowString = (timer != null) ? " " : "" + "UOW(" + uow.hashCode() + ")"; - } - if (timer != null) { - timerString = String.format(" %s", timer.toString()); - } - LOG.info(String.format("CQL%s%s - %s", uowString, timerString, statement)); - } - if (isShowCql()) { - if (statement instanceof BuiltStatement) { - BuiltStatement builtStatement = (BuiltStatement) statement; - if (showValues) { - RegularStatement regularStatement = builtStatement.setForceNoValues(true); - printCql(regularStatement.getQueryString()); - } else { - printCql(builtStatement.getQueryString()); - } - } else if (statement instanceof RegularStatement) { - RegularStatement regularStatement = (RegularStatement) statement; - printCql(regularStatement.getQueryString()); - } else { - printCql(statement.toString()); - } - } - } + private void logStatement(Statement statement, boolean showValues) { + if (isShowCql()) { + printCql(Operation.queryString(statement, showValues)); + } else if (LOG.isInfoEnabled()) { + LOG.info("CQL> " + Operation.queryString(statement, showValues)); + } + } public Tracer getZipkinTracer() { return null; @@ -152,8 +132,7 @@ public abstract class AbstractSessionOperations { return null; } - public void mergeCache(Table cache) { - } + public void mergeCache(Table>> uowCache) { } RuntimeException translateException(RuntimeException e) { if (e instanceof HelenusException) { @@ -172,4 +151,7 @@ public abstract class AbstractSessionOperations { void printCql(String cql) { getPrintStream().println(cql); } + + public void cacheEvict(List facets) { + } } diff --git a/src/main/java/net/helenus/core/AbstractUnitOfWork.java b/src/main/java/net/helenus/core/AbstractUnitOfWork.java index 73db315..3690bf5 100644 --- a/src/main/java/net/helenus/core/AbstractUnitOfWork.java +++ b/src/main/java/net/helenus/core/AbstractUnitOfWork.java @@ -19,6 +19,10 @@ import java.util.*; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; +import net.helenus.core.cache.UnboundFacet; +import net.helenus.core.reflect.HelenusNamedProperty; +import net.helenus.mapping.HelenusProperty; +import net.helenus.support.Either; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -31,6 +35,8 @@ import com.google.common.collect.TreeTraverser; import net.helenus.core.cache.CacheUtil; import net.helenus.core.cache.Facet; +import static net.helenus.core.HelenusSession.deleted; + /** Encapsulates the concept of a "transaction" as a unit-of-work. */ public abstract class AbstractUnitOfWork implements UnitOfWork, AutoCloseable { @@ -39,8 +45,11 @@ public abstract class AbstractUnitOfWork implements UnitOfW private final List> nested = new ArrayList<>(); private final HelenusSession session; private final AbstractUnitOfWork parent; - // Cache: - private final Table cache = HashBasedTable.create(); + private List postCommit = new ArrayList(); + private boolean aborted = false; + private boolean committed = false; + + private final Table>> cache = HashBasedTable.create(); protected String purpose; protected int cacheHits = 0; protected int cacheMisses = 0; @@ -48,9 +57,6 @@ public abstract class AbstractUnitOfWork implements UnitOfW protected Stopwatch elapsedTime; protected Map databaseTime = new HashMap<>(); protected double cacheLookupTime = 0.0; - private List postCommit = new ArrayList(); - private boolean aborted = false; - private boolean committed = false; protected AbstractUnitOfWork(HelenusSession session, AbstractUnitOfWork parent) { Objects.requireNonNull(session, "containing session cannot be null"); @@ -82,7 +88,7 @@ public abstract class AbstractUnitOfWork implements UnitOfW } @Override - public UnitOfWork begin() { + public synchronized UnitOfWork begin() { elapsedTime = Stopwatch.createStarted(); // log.recordCacheAndDatabaseOperationCount(txn::start) return this; @@ -108,19 +114,38 @@ public abstract class AbstractUnitOfWork implements UnitOfW public String logTimers(String what) { double e = (double) elapsedTime.elapsed(TimeUnit.MICROSECONDS) / 1000.0; - double d = databaseTime.containsKey("Cassandra") ? databaseTime.get("Cassandra") / 1000.0 : 0.0; + double d = 0.0; double c = cacheLookupTime / 1000.0; - double fd = (d / e) * 100.0; double fc = (c / e) * 100.0; - double dat = d + c; - double daf = (dat / e) * 100; - String nested = this.nested.stream().map(uow -> String.valueOf(uow.hashCode())) - .collect(Collectors.joining(", ")); - return String.format(Locale.US, - "UOW(%s%s) %s (total: %,.3fms cache: %,.3fms %,2.2f%% (%,d hit, %,d miss) %,d Cassandra operation%s took %,.3fms %,2.2f%% [%,.3fms %,2.2f%%])%s", - hashCode(), (this.nested.size() > 0 ? ", [" + nested + "]" : ""), what, e, c, fc, cacheHits, - cacheMisses, databaseLookups, (databaseLookups > 1) ? "s" : "", d, fd, dat, daf, - (purpose == null ? "" : " in " + purpose)); + String database = ""; + if (databaseTime.size() > 0) { + List dbt = new ArrayList<>(databaseTime.size()); + for (String name : databaseTime.keySet()) { + double t = databaseTime.get(name) / 1000.0; + d += t; + dbt.add(String.format("%s took %,.3fms %,2.2f%%", name, t, (t / e) * 100.0)); + } + double fd = (d / e) * 100.0; + database = String.format(", %d quer%s (%,.3fms %,2.2f%% - %s)", databaseLookups, + (databaseLookups > 1) ? "ies" : "y", d, fd, String.join(", ", dbt)); + } + String cache = ""; + if (cacheLookupTime > 0) { + int cacheLookups = cacheHits + cacheMisses; + cache = String.format(" with %d cache lookup%s (%,.3fms %,2.2f%% - %,d hit, %,d miss)", cacheLookups, + cacheLookups > 1 ? "s" : "", c, fc, cacheHits, cacheMisses); + } + String da = ""; + if (databaseTime.size() > 0 || cacheLookupTime > 0) { + double dat = d + c; + double daf = (dat / e) * 100; + da = String.format(" consuming %,.3fms for data access, or %,2.2f%% of total UOW time.", dat, daf); + } + String n = nested.stream().map(uow -> String.valueOf(uow.hashCode())).collect(Collectors.joining(", ")); + String s = String.format(Locale.US, "UOW(%s%s) %s in %,.3fms%s%s%s%s", hashCode(), + (nested.size() > 0 ? ", [" + n + "]" : ""), what, e, cache, database, da, + (purpose == null ? "" : " " + purpose)); + return s; } private void applyPostCommitFunctions() { @@ -141,15 +166,14 @@ public abstract class AbstractUnitOfWork implements UnitOfW for (Facet facet : facets) { if (!facet.fixed()) { String columnName = facet.name() + "==" + facet.value(); - Object value = cache.get(tableName, columnName); - if (value != null) { - if (result.isPresent() && result.get() != value) { - // One facet matched, but another did not. - result = Optional.empty(); - break; - } else { - result = Optional.of(value); - } + Either> eitherValue = cache.get(tableName, columnName); + if (eitherValue != null) { + Object value = deleted; + if (eitherValue.isLeft()) { + value = eitherValue.getLeft(); + } + result = Optional.of(value); + break; } } } @@ -162,13 +186,46 @@ public abstract class AbstractUnitOfWork implements UnitOfW return result; } + @Override + public List cacheEvict(List facets) { + Either> deletedObjectFacets = Either.right(facets); + String tableName = CacheUtil.schemaName(facets); + Optional optionalValue = cacheLookup(facets); + if (optionalValue.isPresent()) { + Object value = optionalValue.get(); + + for (Facet facet : facets) { + if (!facet.fixed()) { + String columnKey = facet.name() + "==" + facet.value(); + // mark the value identified by the facet to `deleted` + cache.put(tableName, columnKey, deletedObjectFacets); + } + } + // look for other row/col pairs that referenced the same object, mark them + // `deleted` + cache.columnKeySet().forEach(columnKey -> { + Either> eitherCachedValue = cache.get(tableName, columnKey); + if (eitherCachedValue.isLeft()) { + Object cachedValue = eitherCachedValue.getLeft(); + if (cachedValue == value) { + cache.put(tableName, columnKey, deletedObjectFacets); + String[] parts = columnKey.split("=="); + facets.add(new Facet(parts[0], parts[1])); + } + } + }); + } + return facets; + } + @Override public void cacheUpdate(Object value, List facets) { - Facet table = facets.remove(0); - String tableName = table.value().toString(); + String tableName = CacheUtil.schemaName(facets); for (Facet facet : facets) { - String columnName = facet.name() + "==" + facet.value(); - cache.put(tableName, columnName, value); + if (!facet.fixed()) { + String columnName = facet.name() + "==" + facet.value(); + cache.put(tableName, columnName, Either.left(value)); + } } } @@ -208,32 +265,46 @@ public abstract class AbstractUnitOfWork implements UnitOfW aborted = false; nested.forEach((uow) -> Errors.rethrow().wrap(uow::commit)); + elapsedTime.stop(); - // Merge UOW cache into parent's cache. - if (parent != null) { - parent.mergeCache(cache); - } else { - session.mergeCache(cache); - } - elapsedTime.stop(); - - // Apply all post-commit functions for if (parent == null) { + // Apply all post-commit functions, this is the outter-most UnitOfWork. traverser.postOrderTraversal(this).forEach(uow -> { uow.applyPostCommitFunctions(); }); - return new PostCommitFunction(this, null); - } - } + + // Merge our cache into the session cache. + session.mergeCache(cache); + + return new PostCommitFunction(this, null); + } else { + + // Merge cache and statistics into parent if there is one. + parent.mergeCache(cache); + + parent.cacheHits += cacheHits; + parent.cacheMisses += cacheMisses; + parent.databaseLookups += databaseLookups; + parent.cacheLookupTime += cacheLookupTime; + for (String name : databaseTime.keySet()) { + if (parent.databaseTime.containsKey(name)) { + double t = parent.databaseTime.get(name); + parent.databaseTime.put(name, t + databaseTime.get(name)); + } else { + parent.databaseTime.put(name, databaseTime.get(name)); + } + } + } + } // else { // Constructor ctor = clazz.getConstructor(conflictExceptionClass); // T object = ctor.newInstance(new Object[] { String message }); // } - return new PostCommitFunction(this, postCommit); + return new PostCommitFunction(this, postCommit); } /* Explicitly discard the work and mark it as as such in the log. */ - public void abort() { + public synchronized void abort() { TreeTraverser> traverser = TreeTraverser.using(node -> node::getChildNodes); traverser.postOrderTraversal(this).forEach(uow -> { uow.committed = false; @@ -249,12 +320,13 @@ public abstract class AbstractUnitOfWork implements UnitOfW } } - private void mergeCache(Table from) { - Table to = this.cache; + private void mergeCache(Table>> from) { + Table>> to = this.cache; from.rowMap().forEach((rowKey, columnMap) -> { columnMap.forEach((columnKey, value) -> { if (to.contains(rowKey, columnKey)) { - to.put(rowKey, columnKey, CacheUtil.merge(to.get(rowKey, columnKey), from.get(rowKey, columnKey))); + //TODO(gburd):... + to.put(rowKey, columnKey, Either.left(CacheUtil.merge(to.get(rowKey, columnKey).getLeft(), from.get(rowKey, columnKey).getLeft()))); } else { to.put(rowKey, columnKey, from.get(rowKey, columnKey)); } diff --git a/src/main/java/net/helenus/core/HelenusSession.java b/src/main/java/net/helenus/core/HelenusSession.java index a80989f..e169a86 100644 --- a/src/main/java/net/helenus/core/HelenusSession.java +++ b/src/main/java/net/helenus/core/HelenusSession.java @@ -27,6 +27,7 @@ import java.util.concurrent.TimeUnit; import java.util.function.Function; import java.util.stream.Collectors; +import net.helenus.support.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -48,17 +49,14 @@ import net.helenus.mapping.HelenusEntity; import net.helenus.mapping.HelenusProperty; import net.helenus.mapping.MappingUtil; import net.helenus.mapping.value.*; -import net.helenus.support.DslPropertyException; -import net.helenus.support.Fun; import net.helenus.support.Fun.Tuple1; import net.helenus.support.Fun.Tuple2; import net.helenus.support.Fun.Tuple6; -import net.helenus.support.HelenusException; -import net.helenus.support.HelenusMappingException; public final class HelenusSession extends AbstractSessionOperations implements Closeable { private static final Logger LOG = LoggerFactory.getLogger(HelenusSession.class); + public static final Object deleted = new Object(); private final int MAX_CACHE_SIZE = 10000; private final int MAX_CACHE_EXPIRE_SECONDS = 600; @@ -74,7 +72,7 @@ public final class HelenusSession extends AbstractSessionOperations implements C private final SessionRepository sessionRepository; private final Executor executor; private final boolean dropSchemaOnClose; - private final Cache sessionCache; + private final Cache sessionCache; private final RowColumnValueProvider valueProvider; private final StatementColumnValuePreparer valuePreparer; private final Metadata metadata; @@ -101,7 +99,8 @@ public final class HelenusSession extends AbstractSessionOperations implements C this.zipkinTracer = tracer; this.sessionCache = CacheBuilder.newBuilder().maximumSize(MAX_CACHE_SIZE) - .expireAfterAccess(MAX_CACHE_EXPIRE_SECONDS, TimeUnit.SECONDS).recordStats().build(); + .expireAfterAccess(MAX_CACHE_EXPIRE_SECONDS, TimeUnit.SECONDS) + .expireAfterWrite(MAX_CACHE_EXPIRE_SECONDS, TimeUnit.SECONDS).recordStats().build(); this.valueProvider = new RowColumnValueProvider(this.sessionRepository); this.valuePreparer = new StatementColumnValuePreparer(this.sessionRepository); @@ -198,6 +197,16 @@ public final class HelenusSession extends AbstractSessionOperations implements C return null; } + @Override + public void cacheEvict(List facets) { + String tableName = CacheUtil.schemaName(facets); + List facetCombinations = CacheUtil.flattenFacets(facets); + for (String[] combination : facetCombinations) { + String cacheKey = tableName + "." + Arrays.toString(combination); + sessionCache.invalidate(cacheKey); + } + } + @Override public void updateCache(Object pojo, List facets) { Map valueMap = pojo instanceof MapExportable ? ((MapExportable) pojo).toMap() : null; @@ -225,71 +234,72 @@ public final class HelenusSession extends AbstractSessionOperations implements C boundFacets.add(facet); } } - String tableName = CacheUtil.schemaName(facets); - List facetCombinations = CacheUtil.flattenFacets(boundFacets); - Object value = sessionCache.getIfPresent(pojo); - Object mergedValue = null; - for (String[] combination : facetCombinations) { - String cacheKey = tableName + "." + Arrays.toString(combination); - if (value == null) { - sessionCache.put(cacheKey, pojo); - } else { - if (mergedValue == null) { - mergedValue = pojo; - } else { - mergedValue = CacheUtil.merge(value, pojo); - } - sessionCache.put(mergedValue, pojo); - } - } - + String tableName = CacheUtil.schemaName(facets); + List facetCombinations = CacheUtil.flattenFacets(boundFacets); + mergeAndUpdateCacheValues(pojo, tableName, facetCombinations); } @Override - public void mergeCache(Table uowCache) { - List pojos = uowCache.values().stream().distinct().collect(Collectors.toList()); - for (Object pojo : pojos) { - HelenusEntity entity = Helenus.resolve(MappingUtil.getMappingInterface(pojo)); - Map valueMap = pojo instanceof MapExportable ? ((MapExportable) pojo).toMap() : null; - if (entity.isCacheable()) { - List boundFacets = new ArrayList<>(); - for (Facet facet : entity.getFacets()) { - if (facet instanceof UnboundFacet) { - UnboundFacet unboundFacet = (UnboundFacet) facet; - UnboundFacet.Binder binder = unboundFacet.binder(); - unboundFacet.getProperties().forEach(prop -> { - if (valueMap == null) { - Object value = BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop, false); - binder.setValueForProperty(prop, value.toString()); - } else { - binder.setValueForProperty(prop, valueMap.get(prop.getPropertyName()).toString()); - } - }); - if (binder.isBound()) { - boundFacets.add(binder.bind()); - } - } else { - boundFacets.add(facet); - } - } - String tableName = entity.getName().toCql(); - // NOTE: should equal `String tableName = CacheUtil.schemaName(facets);` - List facetCombinations = CacheUtil.flattenFacets(boundFacets); - Object value = sessionCache.getIfPresent(pojo); - Object mergedValue = null; - for (String[] combination : facetCombinations) { - String cacheKey = tableName + "." + Arrays.toString(combination); - if (value == null) { - sessionCache.put(cacheKey, pojo); - } else { - if (mergedValue == null) { - mergedValue = pojo; - } else { - mergedValue = CacheUtil.merge(value, pojo); - } - sessionCache.put(mergedValue, pojo); - } + public void mergeCache(Table>> uowCache) { + List>> items = uowCache.values().stream().distinct().collect(Collectors.toList()); + for (Either> item : items) { + if (item.isRight()) { + List facets = item.getRight(); + String tableName = CacheUtil.schemaName(facets); + List combinations = CacheUtil.flattenFacets(facets); + for (String[] combination : combinations) { + String cacheKey = tableName + "." + Arrays.toString(combination); + sessionCache.invalidate(cacheKey); + } + } else { + Object pojo = item.getLeft(); + HelenusEntity entity = Helenus.resolve(MappingUtil.getMappingInterface(pojo)); + Map valueMap = pojo instanceof MapExportable ? ((MapExportable) pojo).toMap() : null; + if (entity.isCacheable()) { + List boundFacets = new ArrayList<>(); + for (Facet facet : entity.getFacets()) { + if (facet instanceof UnboundFacet) { + UnboundFacet unboundFacet = (UnboundFacet) facet; + UnboundFacet.Binder binder = unboundFacet.binder(); + unboundFacet.getProperties().forEach(prop -> { + if (valueMap == null) { + Object value = BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop, + false); + binder.setValueForProperty(prop, value.toString()); + } else { + binder.setValueForProperty(prop, valueMap.get(prop.getPropertyName()).toString()); + } + }); + if (binder.isBound()) { + boundFacets.add(binder.bind()); + } + } else { + boundFacets.add(facet); + } + } + // NOTE: should equal `String tableName = CacheUtil.schemaName(facets);` + List facetCombinations = CacheUtil.flattenFacets(boundFacets); + String tableName = CacheUtil.schemaName(boundFacets); + mergeAndUpdateCacheValues(pojo, tableName, facetCombinations); + } + } + } + } + + private void mergeAndUpdateCacheValues(Object pojo, String tableName, List facetCombinations) { + Object merged = null; + for (String[] combination : facetCombinations) { + String cacheKey = tableName + "." + Arrays.toString(combination); + Object value = sessionCache.getIfPresent(cacheKey); + if (value == null) { + sessionCache.put(cacheKey, pojo); + } else { + if (merged == null) { + merged = pojo; + } else { + merged = CacheUtil.merge(value, pojo); } + sessionCache.put(cacheKey, merged); } } } @@ -318,7 +328,7 @@ public final class HelenusSession extends AbstractSessionOperations implements C Class clazz = unitOfWorkClass; Constructor ctor = clazz.getConstructor(HelenusSession.class, UnitOfWork.class); UnitOfWork uow = ctor.newInstance(this, parent); - if (LOG.isInfoEnabled()) { + if (LOG.isInfoEnabled() && purpose != null) { uow.setPurpose(purpose.toString()); } if (parent != null) { diff --git a/src/main/java/net/helenus/core/UnitOfWork.java b/src/main/java/net/helenus/core/UnitOfWork.java index e236509..5a1c7bc 100644 --- a/src/main/java/net/helenus/core/UnitOfWork.java +++ b/src/main/java/net/helenus/core/UnitOfWork.java @@ -59,6 +59,8 @@ public interface UnitOfWork extends AutoCloseable { void cacheUpdate(Object pojo, List facets); + List cacheEvict(List facets); + UnitOfWork setPurpose(String purpose); void addDatabaseTime(String name, Stopwatch amount); diff --git a/src/main/java/net/helenus/core/operation/AbstractFilterOperation.java b/src/main/java/net/helenus/core/operation/AbstractFilterOperation.java index c7a4787..13de23e 100644 --- a/src/main/java/net/helenus/core/operation/AbstractFilterOperation.java +++ b/src/main/java/net/helenus/core/operation/AbstractFilterOperation.java @@ -107,4 +107,5 @@ public abstract class AbstractFilterOperation> extends AbstractStatementOperation { @@ -109,41 +111,48 @@ public abstract class AbstractOptionalOperation result = Optional.empty(); E cachedResult = null; - boolean updateCache = true; + final boolean updateCache; if (enableCache) { Stopwatch timer = Stopwatch.createStarted(); try { List facets = bindFacetValues(); - cachedResult = checkCache(uow, facets); - if (cachedResult != null) { - result = Optional.of(cachedResult); - updateCache = false; - uowCacheHits.mark(); - cacheHits.mark(); - uow.recordCacheAndDatabaseOperationCount(1, 0); - } else { - uowCacheMiss.mark(); - if (isSessionCacheable()) { - String tableName = CacheUtil.schemaName(facets); - cachedResult = (E) sessionOps.checkCache(tableName, facets); - if (cachedResult != null) { - result = Optional.of(cachedResult); - sessionCacheHits.mark(); - cacheHits.mark(); - uow.recordCacheAndDatabaseOperationCount(1, 0); - } else { - sessionCacheMiss.mark(); - cacheMiss.mark(); - uow.recordCacheAndDatabaseOperationCount(-1, 0); - } - } - } + if (facets != null) { + cachedResult = checkCache(uow, facets); + if (cachedResult != null) { + updateCache = false; + result = Optional.of(cachedResult); + uowCacheHits.mark(); + cacheHits.mark(); + uow.recordCacheAndDatabaseOperationCount(1, 0); + } else { + updateCache = true; + uowCacheMiss.mark(); + if (isSessionCacheable()) { + String tableName = CacheUtil.schemaName(facets); + cachedResult = (E) sessionOps.checkCache(tableName, facets); + if (cachedResult != null) { + result = Optional.of(cachedResult); + sessionCacheHits.mark(); + cacheHits.mark(); + uow.recordCacheAndDatabaseOperationCount(1, 0); + } else { + sessionCacheMiss.mark(); + cacheMiss.mark(); + uow.recordCacheAndDatabaseOperationCount(-1, 0); + } + } + } + } else { + updateCache = false; + } } finally { timer.stop(); uow.addCacheLookupTime(timer); } - } + } else { + updateCache = false; + } if (!result.isPresent()) { // Formulate the query and execute it against the Cassandra cluster. @@ -154,14 +163,16 @@ public abstract class AbstractOptionalOperation uow, E pojo, List identifyingFacets) { + protected void cacheUpdate(UnitOfWork uow, E pojo, List identifyingFacets) { List facets = new ArrayList<>(); Map valueMap = pojo instanceof MapExportable ? ((MapExportable) pojo).toMap() : null; diff --git a/src/main/java/net/helenus/core/operation/AbstractStreamOperation.java b/src/main/java/net/helenus/core/operation/AbstractStreamOperation.java index 15d0372..afa8a73 100644 --- a/src/main/java/net/helenus/core/operation/AbstractStreamOperation.java +++ b/src/main/java/net/helenus/core/operation/AbstractStreamOperation.java @@ -33,6 +33,8 @@ import net.helenus.core.UnitOfWork; import net.helenus.core.cache.CacheUtil; import net.helenus.core.cache.Facet; +import static net.helenus.core.HelenusSession.deleted; + public abstract class AbstractStreamOperation> extends AbstractStatementOperation { @@ -115,41 +117,48 @@ public abstract class AbstractStreamOperation resultStream = null; E cachedResult = null; - boolean updateCache = true; + final boolean updateCache; if (enableCache) { Stopwatch timer = Stopwatch.createStarted(); try { List facets = bindFacetValues(); - cachedResult = checkCache(uow, facets); - if (cachedResult != null) { - resultStream = Stream.of(cachedResult); - updateCache = false; - uowCacheHits.mark(); - cacheHits.mark(); - uow.recordCacheAndDatabaseOperationCount(1, 0); - } else { - uowCacheMiss.mark(); - if (isSessionCacheable()) { - String tableName = CacheUtil.schemaName(facets); - cachedResult = (E) sessionOps.checkCache(tableName, facets); - if (cachedResult != null) { - resultStream = Stream.of(cachedResult); - sessionCacheHits.mark(); - cacheHits.mark(); - uow.recordCacheAndDatabaseOperationCount(1, 0); - } else { - sessionCacheMiss.mark(); - cacheMiss.mark(); - uow.recordCacheAndDatabaseOperationCount(-1, 0); - } - } - } + if (facets != null) { + cachedResult = checkCache(uow, facets); + if (cachedResult != null) { + updateCache = false; + resultStream = Stream.of(cachedResult); + uowCacheHits.mark(); + cacheHits.mark(); + uow.recordCacheAndDatabaseOperationCount(1, 0); + } else { + updateCache = true; + uowCacheMiss.mark(); + if (isSessionCacheable()) { + String tableName = CacheUtil.schemaName(facets); + cachedResult = (E) sessionOps.checkCache(tableName, facets); + if (cachedResult != null) { + resultStream = Stream.of(cachedResult); + sessionCacheHits.mark(); + cacheHits.mark(); + uow.recordCacheAndDatabaseOperationCount(1, 0); + } else { + sessionCacheMiss.mark(); + cacheMiss.mark(); + uow.recordCacheAndDatabaseOperationCount(-1, 0); + } + } + } + } else { + updateCache = false; + } } finally { timer.stop(); uow.addCacheLookupTime(timer); } - } + } else { + updateCache = false; + } if (resultStream == null) { ResultSet resultSet = execute(sessionOps, uow, traceContext, queryExecutionTimeout, queryTimeoutUnits, @@ -159,17 +168,20 @@ public abstract class AbstractStreamOperation again = new ArrayList<>(); - List facets = getFacets(); - resultStream.forEach(result -> { - updateCache(uow, result, facets); - again.add(result); - }); - resultStream = again.stream(); + if (resultStream != null) { + List again = new ArrayList<>(); + List facets = getFacets(); + resultStream.forEach(result -> { + if (result != deleted) { + if (updateCache) { + cacheUpdate(uow, result, facets); + } + again.add(result); + } + }); + resultStream = again.stream(); } - - return resultStream; + return resultStream; } finally { context.stop(); } diff --git a/src/main/java/net/helenus/core/operation/DeleteOperation.java b/src/main/java/net/helenus/core/operation/DeleteOperation.java index d95c567..d3abf19 100644 --- a/src/main/java/net/helenus/core/operation/DeleteOperation.java +++ b/src/main/java/net/helenus/core/operation/DeleteOperation.java @@ -15,6 +15,11 @@ */ package net.helenus.core.operation; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + import com.datastax.driver.core.ResultSet; import com.datastax.driver.core.querybuilder.BuiltStatement; import com.datastax.driver.core.querybuilder.Delete; @@ -23,8 +28,12 @@ import com.datastax.driver.core.querybuilder.QueryBuilder; import net.helenus.core.AbstractSessionOperations; import net.helenus.core.Filter; +import net.helenus.core.UnitOfWork; +import net.helenus.core.cache.Facet; +import net.helenus.core.cache.UnboundFacet; import net.helenus.core.reflect.HelenusPropertyNode; import net.helenus.mapping.HelenusEntity; +import net.helenus.mapping.HelenusProperty; import net.helenus.support.HelenusMappingException; public final class DeleteOperation extends AbstractFilterOperation { @@ -122,4 +131,65 @@ public final class DeleteOperation extends AbstractFilterOperation bindFacetValues(List facets) { + if (facets == null) { + return new ArrayList(); + } + List boundFacets = new ArrayList<>(); + Map filterMap = new HashMap<>(filters.size()); + filters.forEach(f -> filterMap.put(f.getNode().getProperty(), f)); + + for (Facet facet : facets) { + if (facet instanceof UnboundFacet) { + UnboundFacet unboundFacet = (UnboundFacet) facet; + UnboundFacet.Binder binder = unboundFacet.binder(); + if (filters != null) { + for (HelenusProperty prop : unboundFacet.getProperties()) { + + Filter filter = filterMap.get(prop); + if (filter != null) { + Object[] postulates = filter.postulateValues(); + for (Object p : postulates) { + binder.setValueForProperty(prop, p.toString()); + } + } + } + + } + if (binder.isBound()) { + boundFacets.add(binder.bind()); + } + } else { + boundFacets.add(facet); + } + } + return boundFacets; + } + + @Override + public ResultSet sync() {// throws TimeoutException { + ResultSet result = super.sync(); + if (entity.isCacheable()) { + sessionOps.cacheEvict(bindFacetValues()); + } + return result; + } + + @Override + public List getFacets() { + return entity.getFacets(); + } + + @Override + public ResultSet sync(UnitOfWork uow) {// throws TimeoutException { + if (uow == null) { + return sync(); + } + ResultSet result = super.sync(uow); + List facets = getFacets(); + uow.cacheEvict(bindFacetValues(facets)); + return result; + } + } diff --git a/src/main/java/net/helenus/core/operation/InsertOperation.java b/src/main/java/net/helenus/core/operation/InsertOperation.java index 24243e5..510121c 100644 --- a/src/main/java/net/helenus/core/operation/InsertOperation.java +++ b/src/main/java/net/helenus/core/operation/InsertOperation.java @@ -235,6 +235,15 @@ public final class InsertOperation extends AbstractOperation extends AbstractOperation iface = entity.getMappingInterface(); if (resultType == iface) { - updateCache(uow, result, entity.getFacets()); + cacheUpdate(uow, result, entity.getFacets()); } return result; } diff --git a/src/main/java/net/helenus/core/operation/Operation.java b/src/main/java/net/helenus/core/operation/Operation.java index 193dd82..e451926 100644 --- a/src/main/java/net/helenus/core/operation/Operation.java +++ b/src/main/java/net/helenus/core/operation/Operation.java @@ -19,6 +19,11 @@ import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; +import com.datastax.driver.core.RegularStatement; +import com.datastax.driver.core.querybuilder.BuiltStatement; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.codahale.metrics.Meter; import com.codahale.metrics.MetricRegistry; import com.codahale.metrics.Timer; @@ -36,6 +41,8 @@ import net.helenus.core.cache.Facet; public abstract class Operation { + private static final Logger LOG = LoggerFactory.getLogger(Operation.class); + protected final AbstractSessionOperations sessionOps; protected final Meter uowCacheHits; protected final Meter uowCacheMiss; @@ -46,16 +53,19 @@ public abstract class Operation { protected final Timer requestLatency; Operation(AbstractSessionOperations sessionOperations) { - this.sessionOps = sessionOperations; - MetricRegistry metrics = sessionOperations.getMetricRegistry(); - this.uowCacheHits = metrics.meter("net.helenus.UOW-cache-hits"); - this.uowCacheMiss = metrics.meter("net.helenus.UOW-cache-miss"); - this.sessionCacheHits = metrics.meter("net.helenus.session-cache-hits"); - this.sessionCacheMiss = metrics.meter("net.helenus.session-cache-miss"); - this.cacheHits = metrics.meter("net.helenus.cache-hits"); - this.cacheMiss = metrics.meter("net.helenus.cache-miss"); - this.requestLatency = metrics.timer("net.helenus.request-latency"); - } + this.sessionOps = sessionOperations; + MetricRegistry metrics = sessionOperations.getMetricRegistry(); + if (metrics == null) { + metrics = new MetricRegistry(); + } + this.uowCacheHits = metrics.meter("net.helenus.UOW-cache-hits"); + this.uowCacheMiss = metrics.meter("net.helenus.UOW-cache-miss"); + this.sessionCacheHits = metrics.meter("net.helenus.session-cache-hits"); + this.sessionCacheMiss = metrics.meter("net.helenus.session-cache-miss"); + this.cacheHits = metrics.meter("net.helenus.cache-hits"); + this.cacheMiss = metrics.meter("net.helenus.cache-miss"); + this.requestLatency = metrics.timer("net.helenus.request-latency"); + } public ResultSet execute(AbstractSessionOperations session, UnitOfWork uow, TraceContext traceContext, long timeout, TimeUnit units, boolean showValues, boolean cached) { // throws TimeoutException { @@ -88,6 +98,7 @@ public abstract class Operation { timer.stop(); if (uow != null) uow.addDatabaseTime("Cassandra", timer); + log(statement, uow, timer, showValues); } } finally { @@ -98,6 +109,43 @@ public abstract class Operation { } } + public static String queryString(Statement statement, boolean includeValues) { + String query = null; + if (statement instanceof BuiltStatement) { + BuiltStatement builtStatement = (BuiltStatement) statement; + if (includeValues) { + RegularStatement regularStatement = builtStatement.setForceNoValues(true); + query = regularStatement.getQueryString(); + } else { + query = builtStatement.getQueryString(); + } + } else if (statement instanceof RegularStatement) { + RegularStatement regularStatement = (RegularStatement) statement; + query = regularStatement.getQueryString(); + } else { + query = statement.toString(); + + } + return query; + } + + void log(Statement statement, UnitOfWork uow, Stopwatch timer, boolean showValues) { + if (LOG.isInfoEnabled()) { + String uowString = ""; + if (uow != null) { + uowString = "UOW(" + uow.hashCode() + ")"; + } + String timerString = ""; + if (timer != null) { + timerString = String.format(" %s ", timer.toString()); + } + LOG.info(String.format("%s%s%s", + uowString, + timerString, + Operation.queryString(statement, false))); + } + } + public Statement options(Statement statement) { return statement; } diff --git a/src/main/java/net/helenus/core/operation/SelectOperation.java b/src/main/java/net/helenus/core/operation/SelectOperation.java index 58b790b..b4470dd 100644 --- a/src/main/java/net/helenus/core/operation/SelectOperation.java +++ b/src/main/java/net/helenus/core/operation/SelectOperation.java @@ -250,7 +250,8 @@ public final class SelectOperation extends AbstractFilterStreamOperation extends AbstractFilterOperation implements InvocationHandler { private HelenusEntity init(Metadata metadata) { HelenusEntity entity = new HelenusMappingEntity(iface, metadata); + Collection properties = entity.getOrderedProperties(); + if (properties != null) { + for (HelenusProperty prop : properties) { - for (HelenusProperty prop : entity.getOrderedProperties()) { + map.put(prop.getGetterMethod(), prop); - map.put(prop.getGetterMethod(), prop); + AbstractDataType type = prop.getDataType(); + Class javaType = prop.getJavaType(); - AbstractDataType type = prop.getDataType(); - Class javaType = prop.getJavaType(); + if (type instanceof UDTDataType && !UDTValue.class.isAssignableFrom(javaType)) { - if (type instanceof UDTDataType && !UDTValue.class.isAssignableFrom(javaType)) { + Object childDsl = Helenus.dsl(javaType, classLoader, + Optional.of(new HelenusPropertyNode(prop, parent)), + metadata); - Object childDsl = Helenus.dsl(javaType, classLoader, Optional.of(new HelenusPropertyNode(prop, parent)), - metadata); + udtMap.put(prop.getGetterMethod(), childDsl); + } - udtMap.put(prop.getGetterMethod(), childDsl); - } + if (type instanceof DTDataType) { + DTDataType dataType = (DTDataType) type; - if (type instanceof DTDataType) { - DTDataType dataType = (DTDataType) type; + if (dataType.getDataType() instanceof TupleType && !TupleValue.class.isAssignableFrom(javaType)) { - if (dataType.getDataType() instanceof TupleType && !TupleValue.class.isAssignableFrom(javaType)) { + Object childDsl = Helenus.dsl(javaType, classLoader, + Optional.of(new HelenusPropertyNode(prop, parent)), metadata); - Object childDsl = Helenus.dsl(javaType, classLoader, - Optional.of(new HelenusPropertyNode(prop, parent)), metadata); - - tupleMap.put(prop.getGetterMethod(), childDsl); - } - } - } + tupleMap.put(prop.getGetterMethod(), childDsl); + } + } + } + } return entity; } diff --git a/src/test/java/net/helenus/test/integration/build/AbstractEmbeddedCassandraTest.java b/src/test/java/net/helenus/test/integration/build/AbstractEmbeddedCassandraTest.java index f52bb89..b951287 100644 --- a/src/test/java/net/helenus/test/integration/build/AbstractEmbeddedCassandraTest.java +++ b/src/test/java/net/helenus/test/integration/build/AbstractEmbeddedCassandraTest.java @@ -15,87 +15,83 @@ */ package net.helenus.test.integration.build; -import com.datastax.driver.core.Cluster; -import com.datastax.driver.core.KeyspaceMetadata; -import com.datastax.driver.core.Session; import java.io.IOException; import java.util.UUID; + import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.thrift.transport.TTransportException; import org.cassandraunit.utils.EmbeddedCassandraServerHelper; import org.junit.AfterClass; import org.junit.BeforeClass; +import com.datastax.driver.core.Cluster; +import com.datastax.driver.core.KeyspaceMetadata; +import com.datastax.driver.core.Session; + /** AbstractEmbeddedCassandraTest */ public abstract class AbstractEmbeddedCassandraTest { - private static Cluster cluster; + private static Cluster cluster; - private static String keyspace; + private static String keyspace; - private static Session session; + private static Session session; - private static boolean keep; + private static boolean keep; - public static boolean isConnected() { - return session != null; - } + public static boolean isConnected() { + return session != null; + } - public static Cluster getCluster() { - return cluster; - } + public static Cluster getCluster() { + return cluster; + } - public static Session getSession() { - return session; - } + public static Session getSession() { + return session; + } - public static String getKeyspace() { - return keyspace; - } + public static String getKeyspace() { + return keyspace; + } - public static void setKeep(boolean enable) { - keep = enable; - } + public static void setKeep(boolean enable) { + keep = enable; + } - @BeforeClass - public static void startCassandraEmbeddedServer() - throws TTransportException, IOException, InterruptedException, ConfigurationException { - keyspace = "test" + UUID.randomUUID().toString().replace("-", ""); - EmbeddedCassandraServerHelper.startEmbeddedCassandra( - EmbeddedCassandraServerHelper.CASSANDRA_RNDPORT_YML_FILE); + @BeforeClass + public static void startCassandraEmbeddedServer() + throws TTransportException, IOException, InterruptedException, ConfigurationException { + keyspace = "test" + UUID.randomUUID().toString().replace("-", ""); + EmbeddedCassandraServerHelper.startEmbeddedCassandra(EmbeddedCassandraServerHelper.CASSANDRA_RNDPORT_YML_FILE); - cluster = - Cluster.builder() - .addContactPoint(EmbeddedCassandraServerHelper.getHost()) - .withPort(EmbeddedCassandraServerHelper.getNativeTransportPort()) - .build(); + cluster = Cluster.builder().addContactPoint(EmbeddedCassandraServerHelper.getHost()) + .withPort(EmbeddedCassandraServerHelper.getNativeTransportPort()).build(); - KeyspaceMetadata kmd = cluster.getMetadata().getKeyspace(keyspace); - if (kmd == null) { - session = cluster.connect(); + KeyspaceMetadata kmd = cluster.getMetadata().getKeyspace(keyspace); + if (kmd == null) { + session = cluster.connect(); - String cql = - "CREATE KEYSPACE " - + keyspace - + " WITH replication = {'class': 'SimpleStrategy', 'replication_factor' : 1}" - + " AND DURABLE_WRITES = false;"; - System.out.println(cql + "\n"); - session.execute(cql); + String cql = "CREATE KEYSPACE " + keyspace + + " WITH replication = {'class': 'SimpleStrategy', 'replication_factor' : 1}" + + " AND DURABLE_WRITES = false;"; + System.out.println(cql + "\n"); + session.execute(cql); - cql = "USE " + keyspace + ";"; - System.out.println(cql + "\n"); - session.execute(cql); - } else { - session = cluster.connect(keyspace); - } - } + cql = "USE " + keyspace + ";"; + System.out.println(cql + "\n"); + session.execute(cql); + } else { + session = cluster.connect(keyspace); + } + } - @AfterClass - public static void after() { - if (!keep && isConnected()) { - session.close(); - session = null; - EmbeddedCassandraServerHelper.cleanEmbeddedCassandra(); - } - } + @AfterClass + public static void after() { + if (!keep && isConnected()) { + session.close(); + session = null; + EmbeddedCassandraServerHelper.cleanEmbeddedCassandra(); + } + } } diff --git a/src/test/java/net/helenus/test/integration/core/ContextInitTest.java b/src/test/java/net/helenus/test/integration/core/ContextInitTest.java index 0c8f6fd..ee76dc3 100644 --- a/src/test/java/net/helenus/test/integration/core/ContextInitTest.java +++ b/src/test/java/net/helenus/test/integration/core/ContextInitTest.java @@ -15,18 +15,19 @@ */ package net.helenus.test.integration.core; +import org.junit.Test; + import net.helenus.core.Helenus; import net.helenus.core.HelenusSession; import net.helenus.test.integration.build.AbstractEmbeddedCassandraTest; -import org.junit.Test; public class ContextInitTest extends AbstractEmbeddedCassandraTest { - @Test - public void test() { + @Test + public void test() { - HelenusSession session = Helenus.init(getSession()).get(); + HelenusSession session = Helenus.init(getSession()).get(); - System.out.println("Works! " + session); - } + System.out.println("Works! " + session); + } } diff --git a/src/test/java/net/helenus/test/integration/core/HelenusValidatorTest.java b/src/test/java/net/helenus/test/integration/core/HelenusValidatorTest.java index 22ff338..dcfe9ba 100644 --- a/src/test/java/net/helenus/test/integration/core/HelenusValidatorTest.java +++ b/src/test/java/net/helenus/test/integration/core/HelenusValidatorTest.java @@ -1,5 +1,8 @@ package net.helenus.test.integration.core; +import org.junit.Before; +import org.junit.Test; + import net.helenus.core.Helenus; import net.helenus.core.HelenusValidator; import net.helenus.mapping.HelenusEntity; @@ -10,43 +13,40 @@ import net.helenus.mapping.annotation.Table; import net.helenus.support.HelenusException; import net.helenus.support.HelenusMappingException; import net.helenus.test.integration.build.AbstractEmbeddedCassandraTest; -import org.junit.Before; -import org.junit.Test; public class HelenusValidatorTest extends AbstractEmbeddedCassandraTest { - @Table - interface ModelForValidation { + HelenusEntity entity; + HelenusProperty prop; - @Constraints.Email - @PartitionKey - String id(); - } + @Before + public void begin() { + Helenus.init(getSession()).singleton(); - HelenusEntity entity; + entity = Helenus.entity(ModelForValidation.class); - HelenusProperty prop; + prop = entity.getProperty("id"); + } - @Before - public void begin() { - Helenus.init(getSession()).singleton(); + @Test(expected = HelenusMappingException.class) + public void testWrongType() { + HelenusValidator.INSTANCE.validate(prop, Integer.valueOf(123)); + } - entity = Helenus.entity(ModelForValidation.class); + @Test(expected = HelenusException.class) + public void testWrongValue() { + HelenusValidator.INSTANCE.validate(prop, "123"); + } - prop = entity.getProperty("id"); - } + public void testOk() { + HelenusValidator.INSTANCE.validate(prop, "a@b.c"); + } - @Test(expected = HelenusMappingException.class) - public void testWrongType() { - HelenusValidator.INSTANCE.validate(prop, Integer.valueOf(123)); - } + @Table + interface ModelForValidation { - @Test(expected = HelenusException.class) - public void testWrongValue() { - HelenusValidator.INSTANCE.validate(prop, "123"); - } - - public void testOk() { - HelenusValidator.INSTANCE.validate(prop, "a@b.c"); - } + @Constraints.Email + @PartitionKey + String id(); + } } diff --git a/src/test/java/net/helenus/test/integration/core/collection/CollectionTest.java b/src/test/java/net/helenus/test/integration/core/collection/CollectionTest.java index bd1ac60..50a0cd3 100644 --- a/src/test/java/net/helenus/test/integration/core/collection/CollectionTest.java +++ b/src/test/java/net/helenus/test/integration/core/collection/CollectionTest.java @@ -15,407 +15,340 @@ */ package net.helenus.test.integration.core.collection; -import static net.helenus.core.Query.eq; -import static net.helenus.core.Query.get; -import static net.helenus.core.Query.getIdx; +import static net.helenus.core.Query.*; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.UUID; +import java.util.*; import java.util.concurrent.TimeoutException; -import net.helenus.core.Helenus; -import net.helenus.core.HelenusSession; -import net.helenus.test.integration.build.AbstractEmbeddedCassandraTest; + import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; +import net.helenus.core.Helenus; +import net.helenus.core.HelenusSession; +import net.helenus.test.integration.build.AbstractEmbeddedCassandraTest; + public class CollectionTest extends AbstractEmbeddedCassandraTest { - static Customer customer; + static Customer customer; - static HelenusSession session; + static HelenusSession session; - @BeforeClass - public static void beforeTest() { - session = Helenus.init(getSession()).showCql().add(Customer.class).autoCreateDrop().get(); - customer = Helenus.dsl(Customer.class, session.getMetadata()); - } + @BeforeClass + public static void beforeTest() { + session = Helenus.init(getSession()).showCql().add(Customer.class).autoCreateDrop().get(); + customer = Helenus.dsl(Customer.class, session.getMetadata()); + } - @Test - public void testPrint() { - System.out.println(customer); - } + @Test + public void testPrint() { + System.out.println(customer); + } - @Test - public void testSetCRUID() throws TimeoutException { + @Test + public void testSetCRUID() throws TimeoutException { - UUID id = UUID.randomUUID(); + UUID id = UUID.randomUUID(); - Set aliases = new HashSet(); - aliases.add("Alex"); - aliases.add("Albert"); + Set aliases = new HashSet(); + aliases.add("Alex"); + aliases.add("Albert"); - // CREATE + // CREATE - session.insert().value(customer::id, id).value(customer::aliases, aliases).sync(); + session.insert().value(customer::id, id).value(customer::aliases, aliases).sync(); - // READ + // READ - // read full object + // read full object - Customer actual = - session.select(customer).where(customer::id, eq(id)).single().sync().orElse(null); - Assert.assertEquals(id, actual.id()); - Assert.assertEquals(aliases, actual.aliases()); - Assert.assertNull(actual.names()); - Assert.assertNull(actual.properties()); + Customer actual = session.select(customer).where(customer::id, eq(id)).single().sync().orElse(null); + Assert.assertEquals(id, actual.id()); + Assert.assertEquals(aliases, actual.aliases()); + Assert.assertNull(actual.names()); + Assert.assertNull(actual.properties()); - // read full set + // read full set - Set actualSet = - session.select(customer::aliases).where(customer::id, eq(id)).sync().findFirst().get()._1; - Assert.assertEquals(aliases, actualSet); + Set actualSet = session.select(customer::aliases).where(customer::id, eq(id)).sync().findFirst() + .get()._1; + Assert.assertEquals(aliases, actualSet); - // UPDATE + // UPDATE - Set expected = new HashSet(); - expected.add("unknown"); + Set expected = new HashSet(); + expected.add("unknown"); - session.update().set(customer::aliases, expected).where(customer::id, eq(id)).sync(); + session.update().set(customer::aliases, expected).where(customer::id, eq(id)).sync(); - actual = - session.select(customer).where(customer::id, eq(id)).single().sync().orElse(null); + actual = session.select(customer).where(customer::id, eq(id)).single().sync().orElse(null); - Assert.assertEquals(id, actual.id()); - Assert.assertEquals(expected, actual.aliases()); + Assert.assertEquals(id, actual.id()); + Assert.assertEquals(expected, actual.aliases()); - // INSERT + // INSERT - // add operation + // add operation - expected.add("add"); - session.update().add(customer::aliases, "add").where(customer::id, eq(id)).sync(); + expected.add("add"); + session.update().add(customer::aliases, "add").where(customer::id, eq(id)).sync(); - actualSet = - session.select(customer::aliases).where(customer::id, eq(id)).sync().findFirst().get()._1; - Assert.assertEquals(expected, actualSet); + actualSet = session.select(customer::aliases).where(customer::id, eq(id)).sync().findFirst().get()._1; + Assert.assertEquals(expected, actualSet); - // addAll operation - expected.addAll(aliases); - session.update().addAll(customer::aliases, aliases).where(customer::id, eq(id)).sync(); + // addAll operation + expected.addAll(aliases); + session.update().addAll(customer::aliases, aliases).where(customer::id, eq(id)).sync(); - actualSet = - session.select(customer::aliases).where(customer::id, eq(id)).sync().findFirst().get()._1; - Assert.assertEquals(expected, actualSet); + actualSet = session.select(customer::aliases).where(customer::id, eq(id)).sync().findFirst().get()._1; + Assert.assertEquals(expected, actualSet); - // DELETE + // DELETE - // remove single value + // remove single value - expected.remove("add"); - session.update().remove(customer::aliases, "add").where(customer::id, eq(id)).sync(); + expected.remove("add"); + session.update().remove(customer::aliases, "add").where(customer::id, eq(id)).sync(); - actualSet = - session.select(customer::aliases).where(customer::id, eq(id)).sync().findFirst().get()._1; - Assert.assertEquals(expected, actualSet); + actualSet = session.select(customer::aliases).where(customer::id, eq(id)).sync().findFirst().get()._1; + Assert.assertEquals(expected, actualSet); - // remove values + // remove values - expected.removeAll(aliases); - session.update().removeAll(customer::aliases, aliases).where(customer::id, eq(id)).sync(); + expected.removeAll(aliases); + session.update().removeAll(customer::aliases, aliases).where(customer::id, eq(id)).sync(); - actualSet = - session.select(customer::aliases).where(customer::id, eq(id)).sync().findFirst().get()._1; - Assert.assertEquals(expected, actualSet); + actualSet = session.select(customer::aliases).where(customer::id, eq(id)).sync().findFirst().get()._1; + Assert.assertEquals(expected, actualSet); - // remove full list + // remove full list - session.update().set(customer::aliases, null).where(customer::id, eq(id)).sync(); + session.update().set(customer::aliases, null).where(customer::id, eq(id)).sync(); - actualSet = - session.select(customer::aliases).where(customer::id, eq(id)).sync().findFirst().get()._1; - Assert.assertNull(actualSet); + actualSet = session.select(customer::aliases).where(customer::id, eq(id)).sync().findFirst().get()._1; + Assert.assertNull(actualSet); - // remove object + // remove object - session.delete().where(customer::id, eq(id)).sync(); - Long cnt = session.count().where(customer::id, eq(id)).sync(); - Assert.assertEquals(Long.valueOf(0), cnt); - } + session.delete().where(customer::id, eq(id)).sync(); + Long cnt = session.count().where(customer::id, eq(id)).sync(); + Assert.assertEquals(Long.valueOf(0), cnt); + } - @Test - public void testListCRUID() throws TimeoutException { + @Test + public void testListCRUID() throws TimeoutException { - UUID id = UUID.randomUUID(); + UUID id = UUID.randomUUID(); - List names = new ArrayList(); - names.add("Alex"); - names.add("Albert"); + List names = new ArrayList(); + names.add("Alex"); + names.add("Albert"); - // CREATE + // CREATE - session.insert().value(customer::id, id).value(customer::names, names).sync(); + session.insert().value(customer::id, id).value(customer::names, names).sync(); - // READ + // READ - // read full object + // read full object - Customer actual = - session.select(customer).where(customer::id, eq(id)).single().sync().orElse(null); + Customer actual = session.select(customer).where(customer::id, eq(id)).single().sync().orElse(null); - Assert.assertEquals(id, actual.id()); - Assert.assertEquals(names, actual.names()); - Assert.assertNull(actual.aliases()); - Assert.assertNull(actual.properties()); + Assert.assertEquals(id, actual.id()); + Assert.assertEquals(names, actual.names()); + Assert.assertNull(actual.aliases()); + Assert.assertNull(actual.properties()); - // read full list + // read full list - List actualList = - session.select(customer::names).where(customer::id, eq(id)).sync().findFirst().get()._1; - Assert.assertEquals(names, actualList); + List actualList = session.select(customer::names).where(customer::id, eq(id)).sync().findFirst() + .get()._1; + Assert.assertEquals(names, actualList); - // read single value by index + // read single value by index - String cql = session.select(getIdx(customer::names, 1)).where(customer::id, eq(id)).cql(); + String cql = session.select(getIdx(customer::names, 1)).where(customer::id, eq(id)).cql(); - System.out.println("Still not supporting cql = " + cql); + System.out.println("Still not supporting cql = " + cql); - // UPDATE + // UPDATE - List expected = new ArrayList(); - expected.add("unknown"); + List expected = new ArrayList(); + expected.add("unknown"); - session.update().set(customer::names, expected).where(customer::id, eq(id)).sync(); + session.update().set(customer::names, expected).where(customer::id, eq(id)).sync(); - actual = - session.select(customer).where(customer::id, eq(id)).single().sync().orElse(null); + actual = session.select(customer).where(customer::id, eq(id)).single().sync().orElse(null); - Assert.assertEquals(id, actual.id()); - Assert.assertEquals(expected, actual.names()); + Assert.assertEquals(id, actual.id()); + Assert.assertEquals(expected, actual.names()); - // INSERT + // INSERT - // prepend operation + // prepend operation - expected.add(0, "prepend"); - session.update().prepend(customer::names, "prepend").where(customer::id, eq(id)).sync(); + expected.add(0, "prepend"); + session.update().prepend(customer::names, "prepend").where(customer::id, eq(id)).sync(); - actualList = - session.select(customer::names).where(customer::id, eq(id)).sync().findFirst().get()._1; - Assert.assertEquals(expected, actualList); + actualList = session.select(customer::names).where(customer::id, eq(id)).sync().findFirst().get()._1; + Assert.assertEquals(expected, actualList); - // append operation + // append operation - expected.add("append"); - session.update().append(customer::names, "append").where(customer::id, eq(id)).sync(); + expected.add("append"); + session.update().append(customer::names, "append").where(customer::id, eq(id)).sync(); - actualList = - session.select(customer::names).where(customer::id, eq(id)).sync().findFirst().get()._1; - Assert.assertEquals(expected, actualList); + actualList = session.select(customer::names).where(customer::id, eq(id)).sync().findFirst().get()._1; + Assert.assertEquals(expected, actualList); - // prependAll operation - expected.addAll(0, names); - session.update().prependAll(customer::names, names).where(customer::id, eq(id)).sync(); + // prependAll operation + expected.addAll(0, names); + session.update().prependAll(customer::names, names).where(customer::id, eq(id)).sync(); - actualList = - session.select(customer::names).where(customer::id, eq(id)).sync().findFirst().get()._1; - Assert.assertEquals(expected, actualList); + actualList = session.select(customer::names).where(customer::id, eq(id)).sync().findFirst().get()._1; + Assert.assertEquals(expected, actualList); - // appendAll operation - expected.addAll(names); - session.update().appendAll(customer::names, names).where(customer::id, eq(id)).sync(); + // appendAll operation + expected.addAll(names); + session.update().appendAll(customer::names, names).where(customer::id, eq(id)).sync(); - actualList = - session.select(customer::names).where(customer::id, eq(id)).sync().findFirst().get()._1; - Assert.assertEquals(expected, actualList); + actualList = session.select(customer::names).where(customer::id, eq(id)).sync().findFirst().get()._1; + Assert.assertEquals(expected, actualList); - // set by Index + // set by Index - expected.set(5, "inserted"); - session.update().setIdx(customer::names, 5, "inserted").where(customer::id, eq(id)).sync(); + expected.set(5, "inserted"); + session.update().setIdx(customer::names, 5, "inserted").where(customer::id, eq(id)).sync(); - actualList = - session.select(customer::names).where(customer::id, eq(id)).sync().findFirst().get()._1; - Assert.assertEquals(expected, actualList); + actualList = session.select(customer::names).where(customer::id, eq(id)).sync().findFirst().get()._1; + Assert.assertEquals(expected, actualList); - // DELETE + // DELETE - // remove single value + // remove single value - expected.remove("inserted"); - session.update().discard(customer::names, "inserted").where(customer::id, eq(id)).sync(); + expected.remove("inserted"); + session.update().discard(customer::names, "inserted").where(customer::id, eq(id)).sync(); - actualList = - session.select(customer::names).where(customer::id, eq(id)).sync().findFirst().get()._1; - Assert.assertEquals(expected, actualList); + actualList = session.select(customer::names).where(customer::id, eq(id)).sync().findFirst().get()._1; + Assert.assertEquals(expected, actualList); - // remove values + // remove values - expected.removeAll(names); - session.update().discardAll(customer::names, names).where(customer::id, eq(id)).sync(); + expected.removeAll(names); + session.update().discardAll(customer::names, names).where(customer::id, eq(id)).sync(); - actualList = - session.select(customer::names).where(customer::id, eq(id)).sync().findFirst().get()._1; - Assert.assertEquals(expected, actualList); + actualList = session.select(customer::names).where(customer::id, eq(id)).sync().findFirst().get()._1; + Assert.assertEquals(expected, actualList); - // remove full list + // remove full list - session.update().set(customer::names, null).where(customer::id, eq(id)).sync(); + session.update().set(customer::names, null).where(customer::id, eq(id)).sync(); - actualList = - session.select(customer::names).where(customer::id, eq(id)).sync().findFirst().get()._1; - Assert.assertNull(actualList); + actualList = session.select(customer::names).where(customer::id, eq(id)).sync().findFirst().get()._1; + Assert.assertNull(actualList); - // remove object + // remove object - session.delete().where(customer::id, eq(id)).sync(); - Long cnt = session.count().where(customer::id, eq(id)).sync(); - Assert.assertEquals(Long.valueOf(0), cnt); - } + session.delete().where(customer::id, eq(id)).sync(); + Long cnt = session.count().where(customer::id, eq(id)).sync(); + Assert.assertEquals(Long.valueOf(0), cnt); + } - @Test - public void testMapCRUID() throws TimeoutException { + @Test + public void testMapCRUID() throws TimeoutException { - UUID id = UUID.randomUUID(); + UUID id = UUID.randomUUID(); - Map props = new HashMap(); - props.put("key1", "value1"); - props.put("key2", "value2"); + Map props = new HashMap(); + props.put("key1", "value1"); + props.put("key2", "value2"); - // CREATE + // CREATE - session.insert().value(customer::id, id).value(customer::properties, props).sync(); + session.insert().value(customer::id, id).value(customer::properties, props).sync(); - // READ + // READ - // read full object + // read full object - Customer actual = - session.select(customer).where(customer::id, eq(id)).single().sync().orElse(null); + Customer actual = session.select(customer).where(customer::id, eq(id)).single().sync().orElse(null); - Assert.assertEquals(id, actual.id()); - Assert.assertEquals(props, actual.properties()); - Assert.assertNull(actual.aliases()); - Assert.assertNull(actual.names()); + Assert.assertEquals(id, actual.id()); + Assert.assertEquals(props, actual.properties()); + Assert.assertNull(actual.aliases()); + Assert.assertNull(actual.names()); - // read full map + // read full map - Map actualMap = - session - .select(customer::properties) - .where(customer::id, eq(id)) - .sync() - .findFirst() - .get() - ._1; - Assert.assertEquals(props, actualMap); + Map actualMap = session.select(customer::properties).where(customer::id, eq(id)).sync() + .findFirst().get()._1; + Assert.assertEquals(props, actualMap); - // read single key-value in map + // read single key-value in map - String cql = - session.select(get(customer::properties, "key1")).where(customer::id, eq(id)).cql(); + String cql = session.select(get(customer::properties, "key1")).where(customer::id, eq(id)).cql(); - System.out.println("Still not supporting cql = " + cql); + System.out.println("Still not supporting cql = " + cql); - // UPDATE + // UPDATE - Map expected = new HashMap(); - expected.put("k1", "v1"); - expected.put("k2", "v2"); + Map expected = new HashMap(); + expected.put("k1", "v1"); + expected.put("k2", "v2"); - session.update().set(customer::properties, expected).where(customer::id, eq(id)).sync(); + session.update().set(customer::properties, expected).where(customer::id, eq(id)).sync(); - actual = - session.select(customer).where(customer::id, eq(id)).single().sync().orElse(null); - Assert.assertEquals(id, actual.id()); - Assert.assertEquals(expected, actual.properties()); + actual = session.select(customer).where(customer::id, eq(id)).single().sync().orElse(null); + Assert.assertEquals(id, actual.id()); + Assert.assertEquals(expected, actual.properties()); - // INSERT + // INSERT - // put operation + // put operation - expected.put("k3", "v3"); - session.update().put(customer::properties, "k3", "v3").where(customer::id, eq(id)).sync(); + expected.put("k3", "v3"); + session.update().put(customer::properties, "k3", "v3").where(customer::id, eq(id)).sync(); - actualMap = - session - .select(customer::properties) - .where(customer::id, eq(id)) - .sync() - .findFirst() - .get() - ._1; - Assert.assertEquals(expected, actualMap); + actualMap = session.select(customer::properties).where(customer::id, eq(id)).sync().findFirst().get()._1; + Assert.assertEquals(expected, actualMap); - // putAll operation - expected.putAll(props); - session.update().putAll(customer::properties, props).where(customer::id, eq(id)).sync(); + // putAll operation + expected.putAll(props); + session.update().putAll(customer::properties, props).where(customer::id, eq(id)).sync(); - actualMap = - session - .select(customer::properties) - .where(customer::id, eq(id)) - .sync() - .findFirst() - .get() - ._1; - Assert.assertEquals(expected, actualMap); + actualMap = session.select(customer::properties).where(customer::id, eq(id)).sync().findFirst().get()._1; + Assert.assertEquals(expected, actualMap); - // put existing + // put existing - expected.put("k3", "v33"); - session.update().put(customer::properties, "k3", "v33").where(customer::id, eq(id)).sync(); + expected.put("k3", "v33"); + session.update().put(customer::properties, "k3", "v33").where(customer::id, eq(id)).sync(); - actualMap = - session - .select(customer::properties) - .where(customer::id, eq(id)) - .sync() - .findFirst() - .get() - ._1; - Assert.assertEquals(expected, actualMap); + actualMap = session.select(customer::properties).where(customer::id, eq(id)).sync().findFirst().get()._1; + Assert.assertEquals(expected, actualMap); - // DELETE + // DELETE - // remove single key + // remove single key - expected.remove("k3"); - session.update().put(customer::properties, "k3", null).where(customer::id, eq(id)).sync(); + expected.remove("k3"); + session.update().put(customer::properties, "k3", null).where(customer::id, eq(id)).sync(); - actualMap = - session - .select(customer::properties) - .where(customer::id, eq(id)) - .sync() - .findFirst() - .get() - ._1; - Assert.assertEquals(expected, actualMap); - - // remove full map - - session.update().set(customer::properties, null).where(customer::id, eq(id)).sync(); - - actualMap = - session - .select(customer::properties) - .where(customer::id, eq(id)) - .sync() - .findFirst() - .get() - ._1; - Assert.assertNull(actualMap); - - // remove object - - session.delete().where(customer::id, eq(id)).sync(); - Long cnt = session.count().where(customer::id, eq(id)).sync(); - Assert.assertEquals(Long.valueOf(0), cnt); - } + actualMap = session.select(customer::properties).where(customer::id, eq(id)).sync().findFirst().get()._1; + Assert.assertEquals(expected, actualMap); + + // remove full map + + session.update().set(customer::properties, null).where(customer::id, eq(id)).sync(); + + actualMap = session.select(customer::properties).where(customer::id, eq(id)).sync().findFirst().get()._1; + Assert.assertNull(actualMap); + + // remove object + + session.delete().where(customer::id, eq(id)).sync(); + Long cnt = session.count().where(customer::id, eq(id)).sync(); + Assert.assertEquals(Long.valueOf(0), cnt); + } } diff --git a/src/test/java/net/helenus/test/integration/core/collection/Customer.java b/src/test/java/net/helenus/test/integration/core/collection/Customer.java index c9b18fa..165538f 100644 --- a/src/test/java/net/helenus/test/integration/core/collection/Customer.java +++ b/src/test/java/net/helenus/test/integration/core/collection/Customer.java @@ -15,11 +15,13 @@ */ package net.helenus.test.integration.core.collection; -import com.datastax.driver.core.DataType.Name; import java.util.List; import java.util.Map; import java.util.Set; import java.util.UUID; + +import com.datastax.driver.core.DataType.Name; + import net.helenus.mapping.annotation.PartitionKey; import net.helenus.mapping.annotation.Table; import net.helenus.mapping.annotation.Types; @@ -27,15 +29,15 @@ import net.helenus.mapping.annotation.Types; @Table public interface Customer { - @PartitionKey - UUID id(); + @PartitionKey + UUID id(); - @Types.Set(Name.TEXT) - Set aliases(); + @Types.Set(Name.TEXT) + Set aliases(); - @Types.List(Name.TEXT) - List names(); + @Types.List(Name.TEXT) + List names(); - @Types.Map(key = Name.TEXT, value = Name.TEXT) - Map properties(); + @Types.Map(key = Name.TEXT, value = Name.TEXT) + Map properties(); } diff --git a/src/test/java/net/helenus/test/integration/core/compound/CompondKeyTest.java b/src/test/java/net/helenus/test/integration/core/compound/CompondKeyTest.java index 7d9b8aa..fc4169a 100644 --- a/src/test/java/net/helenus/test/integration/core/compound/CompondKeyTest.java +++ b/src/test/java/net/helenus/test/integration/core/compound/CompondKeyTest.java @@ -17,92 +17,89 @@ package net.helenus.test.integration.core.compound; import java.util.Date; import java.util.UUID; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + import net.helenus.core.Helenus; import net.helenus.core.HelenusSession; import net.helenus.core.Operator; import net.helenus.core.Query; import net.helenus.support.Mutable; import net.helenus.test.integration.build.AbstractEmbeddedCassandraTest; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; public class CompondKeyTest extends AbstractEmbeddedCassandraTest { - Timeline timeline; + Timeline timeline; - HelenusSession session; + HelenusSession session; - public static class TimelineImpl implements Timeline { + @Before + public void beforeTest() { + session = Helenus.init(getSession()).showCql().add(Timeline.class).autoCreateDrop().get(); + timeline = Helenus.dsl(Timeline.class, session.getMetadata()); + } - UUID userId; - Date timestamp; - String text; + @Test + public void test() throws Exception { - @Override - public UUID userId() { - return userId; - } + UUID userId = UUID.randomUUID(); + long postTime = System.currentTimeMillis() - 100000L; - @Override - public Date timestamp() { - return timestamp; - } + session.showCql(false); - @Override - public String text() { - return text; - } - } + for (int i = 0; i != 100; ++i) { - @Before - public void beforeTest() { - session = Helenus.init(getSession()).showCql().add(Timeline.class).autoCreateDrop().get(); - timeline = Helenus.dsl(Timeline.class, session.getMetadata()); - } + TimelineImpl post = new TimelineImpl(); + post.userId = userId; + post.timestamp = new Date(postTime + 1000L * i); + post.text = "hello"; - @Test - public void test() throws Exception { + session.upsert(post).sync(); + } - UUID userId = UUID.randomUUID(); - long postTime = System.currentTimeMillis() - 100000L; + session.showCql(true); - session.showCql(false); + final Mutable d = new Mutable(null); + final Mutable c = new Mutable(0); - for (int i = 0; i != 100; ++i) { + session.select(timeline::userId, timeline::timestamp, timeline::text) + .where(timeline::userId, Operator.EQ, userId).orderBy(Query.desc(timeline::timestamp)).limit(5).sync() + .forEach(t -> { - TimelineImpl post = new TimelineImpl(); - post.userId = userId; - post.timestamp = new Date(postTime + 1000L * i); - post.text = "hello"; + // System.out.println(t); + c.set(c.get() + 1); - session.upsert(post).sync(); - } + Date cd = d.get(); + if (cd != null) { + Assert.assertTrue(cd.after(t._2)); + } + d.set(t._2); + }); - session.showCql(true); + Assert.assertEquals(Integer.valueOf(5), c.get()); + } - final Mutable d = new Mutable(null); - final Mutable c = new Mutable(0); + public static class TimelineImpl implements Timeline { - session - .select(timeline::userId, timeline::timestamp, timeline::text) - .where(timeline::userId, Operator.EQ, userId) - .orderBy(Query.desc(timeline::timestamp)) - .limit(5) - .sync() - .forEach( - t -> { + UUID userId; + Date timestamp; + String text; - //System.out.println(t); - c.set(c.get() + 1); + @Override + public UUID userId() { + return userId; + } - Date cd = d.get(); - if (cd != null) { - Assert.assertTrue(cd.after(t._2)); - } - d.set(t._2); - }); + @Override + public Date timestamp() { + return timestamp; + } - Assert.assertEquals(Integer.valueOf(5), c.get()); - } + @Override + public String text() { + return text; + } + } } diff --git a/src/test/java/net/helenus/test/integration/core/compound/Timeline.java b/src/test/java/net/helenus/test/integration/core/compound/Timeline.java index 3871025..f5e1948 100644 --- a/src/test/java/net/helenus/test/integration/core/compound/Timeline.java +++ b/src/test/java/net/helenus/test/integration/core/compound/Timeline.java @@ -17,22 +17,19 @@ package net.helenus.test.integration.core.compound; import java.util.Date; import java.util.UUID; -import net.helenus.mapping.annotation.ClusteringColumn; -import net.helenus.mapping.annotation.Column; -import net.helenus.mapping.annotation.PartitionKey; -import net.helenus.mapping.annotation.Table; -import net.helenus.mapping.annotation.Types; + +import net.helenus.mapping.annotation.*; @Table public interface Timeline { - @PartitionKey(ordinal = 0) - UUID userId(); + @PartitionKey(ordinal = 0) + UUID userId(); - @ClusteringColumn(ordinal = 1) - @Types.Timeuuid - Date timestamp(); + @ClusteringColumn(ordinal = 1) + @Types.Timeuuid + Date timestamp(); - @Column(ordinal = 2) - String text(); + @Column(ordinal = 2) + String text(); } diff --git a/src/test/java/net/helenus/test/integration/core/counter/CounterTest.java b/src/test/java/net/helenus/test/integration/core/counter/CounterTest.java index b1c8c0f..2fbd0b7 100644 --- a/src/test/java/net/helenus/test/integration/core/counter/CounterTest.java +++ b/src/test/java/net/helenus/test/integration/core/counter/CounterTest.java @@ -18,46 +18,46 @@ package net.helenus.test.integration.core.counter; import static net.helenus.core.Query.eq; import java.util.concurrent.TimeoutException; -import net.helenus.core.Helenus; -import net.helenus.core.HelenusSession; -import net.helenus.test.integration.build.AbstractEmbeddedCassandraTest; + import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; +import net.helenus.core.Helenus; +import net.helenus.core.HelenusSession; +import net.helenus.test.integration.build.AbstractEmbeddedCassandraTest; + public class CounterTest extends AbstractEmbeddedCassandraTest { - static Page page; + static Page page; - static HelenusSession session; + static HelenusSession session; - @BeforeClass - public static void beforeTest() { - session = Helenus.init(getSession()).showCql().add(Page.class).autoCreateDrop().get(); - page = Helenus.dsl(Page.class, session.getMetadata()); - } + @BeforeClass + public static void beforeTest() { + session = Helenus.init(getSession()).showCql().add(Page.class).autoCreateDrop().get(); + page = Helenus.dsl(Page.class, session.getMetadata()); + } - @Test - public void testPrint() { - System.out.println(page); - } + @Test + public void testPrint() { + System.out.println(page); + } - @Test - public void testCounter() throws TimeoutException { + @Test + public void testCounter() throws TimeoutException { - boolean exists = - session.select(page::hits).where(page::alias, eq("index")).sync().findFirst().isPresent(); - Assert.assertFalse(exists); + boolean exists = session.select(page::hits).where(page::alias, eq("index")).sync().findFirst().isPresent(); + Assert.assertFalse(exists); - session.update().increment(page::hits, 10L).where(page::alias, eq("index")).sync(); + session.update().increment(page::hits, 10L).where(page::alias, eq("index")).sync(); - long hits = - session.select(page::hits).where(page::alias, eq("index")).sync().findFirst().get()._1; - Assert.assertEquals(10, hits); + long hits = session.select(page::hits).where(page::alias, eq("index")).sync().findFirst().get()._1; + Assert.assertEquals(10, hits); - session.update().decrement(page::hits).where(page::alias, eq("index")).sync(); + session.update().decrement(page::hits).where(page::alias, eq("index")).sync(); - hits = session.select(page::hits).where(page::alias, eq("index")).sync().findFirst().get()._1; - Assert.assertEquals(9, hits); - } + hits = session.select(page::hits).where(page::alias, eq("index")).sync().findFirst().get()._1; + Assert.assertEquals(9, hits); + } } diff --git a/src/test/java/net/helenus/test/integration/core/counter/Page.java b/src/test/java/net/helenus/test/integration/core/counter/Page.java index bfbb27e..577a53a 100644 --- a/src/test/java/net/helenus/test/integration/core/counter/Page.java +++ b/src/test/java/net/helenus/test/integration/core/counter/Page.java @@ -22,9 +22,9 @@ import net.helenus.mapping.annotation.Types; @Table public interface Page { - @PartitionKey - String alias(); + @PartitionKey + String alias(); - @Types.Counter - long hits(); + @Types.Counter + long hits(); } diff --git a/src/test/java/net/helenus/test/integration/core/draft/EntityDraftBuilderTest.java b/src/test/java/net/helenus/test/integration/core/draft/EntityDraftBuilderTest.java index 64f9c7b..f21c50b 100644 --- a/src/test/java/net/helenus/test/integration/core/draft/EntityDraftBuilderTest.java +++ b/src/test/java/net/helenus/test/integration/core/draft/EntityDraftBuilderTest.java @@ -18,72 +18,62 @@ package net.helenus.test.integration.core.draft; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; -import net.helenus.core.Helenus; -import net.helenus.core.HelenusSession; -import net.helenus.test.integration.build.AbstractEmbeddedCassandraTest; + import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; +import net.helenus.core.Helenus; +import net.helenus.core.HelenusSession; +import net.helenus.test.integration.build.AbstractEmbeddedCassandraTest; + public class EntityDraftBuilderTest extends AbstractEmbeddedCassandraTest { - static Supply supply; - static HelenusSession session; + static Supply supply; + static HelenusSession session; - @BeforeClass - public static void beforeTest() { - session = Helenus.init(getSession()).showCql().add(Supply.class).autoCreateDrop().get(); - supply = session.dsl(Supply.class); - } + @BeforeClass + public static void beforeTest() { + session = Helenus.init(getSession()).showCql().add(Supply.class).autoCreateDrop().get(); + supply = session.dsl(Supply.class); + } - @Test - public void testFoo() throws Exception { - Supply.Draft draft = null; + @Test + public void testFoo() throws Exception { + Supply.Draft draft = null; - draft = - Supply.draft("APAC") - .code("WIDGET-002") - .description("Our second Widget!") - .demand( - new HashMap() { - { - put("APAC", 100L); - put("EMEA", 10000L); - put("NORAM", 2000000L); - } - }) - .shipments( - new HashSet() { - { - add("HMS Puddle in transit to APAC, 100 units."); - add("Frigate Jimmy in transit to EMEA, 10000 units."); - } - }) - .suppliers( - new ArrayList() { - { - add("Puddle, Inc."); - add("Jimmy Town, LTD."); - } - }); + draft = Supply.draft("APAC").code("WIDGET-002").description("Our second Widget!") + .demand(new HashMap() { + { + put("APAC", 100L); + put("EMEA", 10000L); + put("NORAM", 2000000L); + } + }).shipments(new HashSet() { + { + add("HMS Puddle in transit to APAC, 100 units."); + add("Frigate Jimmy in transit to EMEA, 10000 units."); + } + }).suppliers(new ArrayList() { + { + add("Puddle, Inc."); + add("Jimmy Town, LTD."); + } + }); - Supply s1 = session.insert(draft).sync(); + Supply s1 = session.insert(draft).sync(); - // List - Supply s2 = - session - .update(s1.update()) - .prepend(supply::suppliers, "Pignose Supply, LLC.") - .sync(); - Assert.assertEquals(s2.suppliers().get(0), "Pignose Supply, LLC."); + // List + Supply s2 = session.update(s1.update()).prepend(supply::suppliers, "Pignose Supply, LLC.").sync(); + Assert.assertEquals(s2.suppliers().get(0), "Pignose Supply, LLC."); - // Set - String shipment = "Pignose, on the way! (1M units)"; - Supply s3 = session.update(s2.update()).add(supply::shipments, shipment).sync(); - Assert.assertTrue(s3.shipments().contains(shipment)); + // Set + String shipment = "Pignose, on the way! (1M units)"; + Supply s3 = session.update(s2.update()).add(supply::shipments, shipment).sync(); + Assert.assertTrue(s3.shipments().contains(shipment)); - // Map - Supply s4 = session.update(s3.update()).put(supply::demand, "NORAM", 10L).sync(); - Assert.assertEquals((long) s4.demand().get("NORAM"), 10L); - } + // Map + Supply s4 = session.update(s3.update()).put(supply::demand, "NORAM", 10L).sync(); + Assert.assertEquals((long) s4.demand().get("NORAM"), 10L); + } } diff --git a/src/test/java/net/helenus/test/integration/core/draft/Inventory.java b/src/test/java/net/helenus/test/integration/core/draft/Inventory.java index a8b5945..57fa020 100644 --- a/src/test/java/net/helenus/test/integration/core/draft/Inventory.java +++ b/src/test/java/net/helenus/test/integration/core/draft/Inventory.java @@ -1,6 +1,7 @@ package net.helenus.test.integration.core.draft; import java.util.UUID; + import net.helenus.core.AbstractAuditedEntityDraft; import net.helenus.core.Helenus; import net.helenus.core.reflect.MapExportable; @@ -9,85 +10,85 @@ import net.helenus.mapping.annotation.*; @Table public interface Inventory { - static Inventory inventory = Helenus.dsl(Inventory.class); + static Inventory inventory = Helenus.dsl(Inventory.class); - @PartitionKey - UUID id(); + @Transient + static Draft draft(UUID id) { + return new Draft(id); + } - @Column("emea") - @Types.Counter - long EMEA(); + @PartitionKey + UUID id(); - @Column("noram") - @Types.Counter - long NORAM(); + @Column("emea") + @Types.Counter + long EMEA(); - @Column("apac") - @Types.Counter - long APAC(); + @Column("noram") + @Types.Counter + long NORAM(); - @Transient - static Draft draft(UUID id) { - return new Draft(id); - } + @Column("apac") + @Types.Counter + long APAC(); - @Transient - default Draft update() { - return new Draft(this); - } + @Transient + default Draft update() { + return new Draft(this); + } - class Draft extends AbstractAuditedEntityDraft { + class Draft extends AbstractAuditedEntityDraft { - // Entity/Draft pattern-enabling methods: - Draft(UUID id) { - super(null); + // Entity/Draft pattern-enabling methods: + Draft(UUID id) { + super(null); - // Primary Key: - set(inventory::id, id); - } + // Primary Key: + set(inventory::id, id); + } - Draft(Inventory inventory) { - super((MapExportable) inventory); - } + Draft(Inventory inventory) { + super((MapExportable) inventory); + } - public Class getEntityClass() { - return Inventory.class; - } + public Class getEntityClass() { + return Inventory.class; + } - protected String getCurrentAuditor() { - return "unknown"; - } + protected String getCurrentAuditor() { + return "unknown"; + } - // Immutable properties: - public UUID id() { - return this.get(inventory::id, UUID.class); - } + // Immutable properties: + public UUID id() { + return this.get(inventory::id, UUID.class); + } - public long EMEA() { - return this.get(inventory::EMEA, long.class); - } + public long EMEA() { + return this.get(inventory::EMEA, long.class); + } - public Draft EMEA(long count) { - mutate(inventory::EMEA, count); - return this; - } + public Draft EMEA(long count) { + mutate(inventory::EMEA, count); + return this; + } - public long APAC() { - return this.get(inventory::APAC, long.class); - } + public long APAC() { + return this.get(inventory::APAC, long.class); + } - public Draft APAC(long count) { - mutate(inventory::APAC, count); - return this; - } + public Draft APAC(long count) { + mutate(inventory::APAC, count); + return this; + } - public long NORAM() { - return this.get(inventory::NORAM, long.class); - } + public long NORAM() { + return this.get(inventory::NORAM, long.class); + } - public Draft NORAM(long count) { - mutate(inventory::NORAM, count); - return this; - } - } + public Draft NORAM(long count) { + mutate(inventory::NORAM, count); + return this; + } + } } diff --git a/src/test/java/net/helenus/test/integration/core/draft/Supply.java b/src/test/java/net/helenus/test/integration/core/draft/Supply.java index 72c0ba7..2576532 100644 --- a/src/test/java/net/helenus/test/integration/core/draft/Supply.java +++ b/src/test/java/net/helenus/test/integration/core/draft/Supply.java @@ -1,10 +1,12 @@ package net.helenus.test.integration.core.draft; -import com.datastax.driver.core.utils.UUIDs; import java.util.List; import java.util.Map; import java.util.Set; import java.util.UUID; + +import com.datastax.driver.core.utils.UUIDs; + import net.helenus.core.AbstractEntityDraft; import net.helenus.core.Helenus; import net.helenus.core.reflect.MapExportable; @@ -13,133 +15,133 @@ import net.helenus.mapping.annotation.*; @Table public interface Supply { - static Supply supply = Helenus.dsl(Supply.class); + static Supply supply = Helenus.dsl(Supply.class); - @PartitionKey - UUID id(); + @Transient + static Draft draft(String region) { + return new Draft(region); + } - @ClusteringColumn(ordinal = 0) - default String region() { - return "NORAM"; - } + @PartitionKey + UUID id(); - @Index(caseSensitive = false) - String code(); + @ClusteringColumn(ordinal = 0) + default String region() { + return "NORAM"; + } - @Index - String description(); // @IndexText == lucene index + @Index(caseSensitive = false) + String code(); - @Index - Map demand(); + @Index + String description(); // @IndexText == lucene index - @Index - List suppliers(); + @Index + Map demand(); - @Index - Set shipments(); + @Index + List suppliers(); - @Transient - static Draft draft(String region) { - return new Draft(region); - } + @Index + Set shipments(); - @Transient - default Draft update() { - return new Draft(this); - } + @Transient + default Draft update() { + return new Draft(this); + } - class Draft extends AbstractEntityDraft { + class Draft extends AbstractEntityDraft { - // Entity/Draft pattern-enabling methods: - Draft(String region) { - super(null); + // Entity/Draft pattern-enabling methods: + Draft(String region) { + super(null); - // Primary Key: - set(supply::id, UUIDs.timeBased()); - set(supply::region, region); - } + // Primary Key: + set(supply::id, UUIDs.timeBased()); + set(supply::region, region); + } - Draft(Supply supply) { - super((MapExportable) supply); - } + Draft(Supply supply) { + super((MapExportable) supply); + } - public Class getEntityClass() { - return Supply.class; - } + public Class getEntityClass() { + return Supply.class; + } - // Immutable properties: - public UUID id() { - return this.get(supply::id, UUID.class); - } + // Immutable properties: + public UUID id() { + return this.get(supply::id, UUID.class); + } - public String region() { - return this.get(supply::region, String.class); - } + public String region() { + return this.get(supply::region, String.class); + } - // Mutable properties: - public String code() { - return this.get(supply::code, String.class); - } + // Mutable properties: + public String code() { + return this.get(supply::code, String.class); + } - public Draft code(String code) { - mutate(supply::code, code); - return this; - } + public Draft code(String code) { + mutate(supply::code, code); + return this; + } - public Draft setCode(String code) { - return code(code); - } + public Draft setCode(String code) { + return code(code); + } - public String description() { - return this.get(supply::description, String.class); - } + public String description() { + return this.get(supply::description, String.class); + } - public Draft description(String description) { - mutate(supply::description, description); - return this; - } + public Draft description(String description) { + mutate(supply::description, description); + return this; + } - public Draft setDescription(String description) { - return description(description); - } + public Draft setDescription(String description) { + return description(description); + } - public Map demand() { - return this.>get(supply::demand, Map.class); - } + public Map demand() { + return this.>get(supply::demand, Map.class); + } - public Draft demand(Map demand) { - mutate(supply::demand, demand); - return this; - } + public Draft demand(Map demand) { + mutate(supply::demand, demand); + return this; + } - public Draft setDemand(Map demand) { - return demand(demand); - } + public Draft setDemand(Map demand) { + return demand(demand); + } - public List suppliers() { - return this.>get(supply::suppliers, List.class); - } + public List suppliers() { + return this.>get(supply::suppliers, List.class); + } - public Draft suppliers(List suppliers) { - mutate(supply::suppliers, suppliers); - return this; - } + public Draft suppliers(List suppliers) { + mutate(supply::suppliers, suppliers); + return this; + } - public Draft setSuppliers(List suppliers) { - return suppliers(suppliers); - } + public Draft setSuppliers(List suppliers) { + return suppliers(suppliers); + } - public Set shipments() { - return this.>get(supply::shipments, Set.class); - } + public Set shipments() { + return this.>get(supply::shipments, Set.class); + } - public Draft shipments(Set shipments) { - mutate(supply::shipments, shipments); - return this; - } + public Draft shipments(Set shipments) { + mutate(supply::shipments, shipments); + return this; + } - public Draft setshipments(Set shipments) { - return shipments(shipments); - } - } + public Draft setshipments(Set shipments) { + return shipments(shipments); + } + } } diff --git a/src/test/java/net/helenus/test/integration/core/hierarchy/Animal.java b/src/test/java/net/helenus/test/integration/core/hierarchy/Animal.java index fe6392f..e5df536 100644 --- a/src/test/java/net/helenus/test/integration/core/hierarchy/Animal.java +++ b/src/test/java/net/helenus/test/integration/core/hierarchy/Animal.java @@ -23,17 +23,17 @@ import net.helenus.mapping.annotation.Transient; @InheritedTable public interface Animal { - @PartitionKey(ordinal = 0) - int id(); + @PartitionKey(ordinal = 0) + int id(); - @Column(ordinal = 1) - boolean eatable(); + @Column(ordinal = 1) + boolean eatable(); - @Column - boolean warmBlodded(); + @Column + boolean warmBlodded(); - @Transient - default Animal me() { - return this; - } + @Transient + default Animal me() { + return this; + } } diff --git a/src/test/java/net/helenus/test/integration/core/hierarchy/Cat.java b/src/test/java/net/helenus/test/integration/core/hierarchy/Cat.java index d0089e0..51ae101 100644 --- a/src/test/java/net/helenus/test/integration/core/hierarchy/Cat.java +++ b/src/test/java/net/helenus/test/integration/core/hierarchy/Cat.java @@ -22,7 +22,7 @@ import net.helenus.mapping.annotation.Table; @Table("cats") public interface Cat extends Mammal { - @Column(ordinal = 0) - @Index(caseSensitive = false) - String nickname(); + @Column(ordinal = 0) + @Index(caseSensitive = false) + String nickname(); } diff --git a/src/test/java/net/helenus/test/integration/core/hierarchy/HierarchyTest.java b/src/test/java/net/helenus/test/integration/core/hierarchy/HierarchyTest.java index f5073bf..bad1cab 100644 --- a/src/test/java/net/helenus/test/integration/core/hierarchy/HierarchyTest.java +++ b/src/test/java/net/helenus/test/integration/core/hierarchy/HierarchyTest.java @@ -5,73 +5,59 @@ import static net.helenus.core.Query.eq; import java.util.Optional; import java.util.Random; import java.util.concurrent.TimeoutException; -import net.helenus.core.Helenus; -import net.helenus.core.HelenusSession; -import net.helenus.test.integration.build.AbstractEmbeddedCassandraTest; + import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; +import net.helenus.core.Helenus; +import net.helenus.core.HelenusSession; +import net.helenus.test.integration.build.AbstractEmbeddedCassandraTest; + public class HierarchyTest extends AbstractEmbeddedCassandraTest { - static Cat cat; + static Cat cat; - static Pig pig; + static Pig pig; - static HelenusSession session; + static HelenusSession session; - static Random rnd = new Random(); + static Random rnd = new Random(); - @BeforeClass - public static void beforeTest() { - session = - Helenus.init(getSession()).showCql().add(Cat.class).add(Pig.class).autoCreateDrop().get(); - cat = Helenus.dsl(Cat.class); - pig = Helenus.dsl(Pig.class); - } + @BeforeClass + public static void beforeTest() { + session = Helenus.init(getSession()).showCql().add(Cat.class).add(Pig.class).autoCreateDrop().get(); + cat = Helenus.dsl(Cat.class); + pig = Helenus.dsl(Pig.class); + } - @Test - public void testPrint() { - System.out.println(cat); - } + @Test + public void testPrint() { + System.out.println(cat); + } - @Test - public void testCounter() throws TimeoutException { + @Test + public void testCounter() throws TimeoutException { - session - .insert() - .value(cat::id, rnd.nextInt()) - .value(cat::nickname, "garfield") - .value(cat::eatable, false) - .sync(); - session - .insert() - .value(pig::id, rnd.nextInt()) - .value(pig::nickname, "porky") - .value(pig::eatable, true) - .sync(); + session.insert().value(cat::id, rnd.nextInt()).value(cat::nickname, "garfield").value(cat::eatable, false) + .sync(); + session.insert().value(pig::id, rnd.nextInt()).value(pig::nickname, "porky").value(pig::eatable, true).sync(); - Optional animal = - session.select(Cat.class).where(cat::nickname, eq("garfield")).sync().findFirst(); - Assert.assertTrue(animal.isPresent()); - Assert.assertTrue(animal.get().warmBlodded()); - Assert.assertFalse(animal.get().eatable()); - } + Optional animal = session.select(Cat.class).where(cat::nickname, eq("garfield")).sync().findFirst(); + Assert.assertTrue(animal.isPresent()); + Assert.assertTrue(animal.get().warmBlodded()); + Assert.assertFalse(animal.get().eatable()); + } - @Test - public void testDefaultMethod() throws TimeoutException { - session - .insert() - .value(cat::id, rnd.nextInt()) - .value(cat::nickname, "garfield") - .value(cat::eatable, false) - .sync(); - Optional animal = - session.select(Cat.class).where(cat::nickname, eq("garfield")).single().sync(); - Assert.assertTrue(animal.isPresent()); + @Test + public void testDefaultMethod() throws TimeoutException { + session.insert().value(cat::id, rnd.nextInt()).value(cat::nickname, "garfield").value(cat::eatable, false) + .sync(); + Optional animal = session.select(Cat.class).where(cat::nickname, eq("garfield")).single().sync(); + Assert.assertTrue(animal.isPresent()); - Cat cat = animal.get(); - Animal itsme = cat.me(); - Assert.assertEquals(cat, itsme); - } + Cat cat = animal.get(); + Animal itsme = cat.me(); + Assert.assertEquals(cat, itsme); + } } diff --git a/src/test/java/net/helenus/test/integration/core/hierarchy/Mammal.java b/src/test/java/net/helenus/test/integration/core/hierarchy/Mammal.java index 950287a..53d8475 100644 --- a/src/test/java/net/helenus/test/integration/core/hierarchy/Mammal.java +++ b/src/test/java/net/helenus/test/integration/core/hierarchy/Mammal.java @@ -20,7 +20,7 @@ import net.helenus.mapping.annotation.InheritedTable; @InheritedTable public interface Mammal extends Animal { - default boolean warmBlodded() { - return true; - } + default boolean warmBlodded() { + return true; + } } diff --git a/src/test/java/net/helenus/test/integration/core/hierarchy/Pig.java b/src/test/java/net/helenus/test/integration/core/hierarchy/Pig.java index 8d12aff..45253cf 100644 --- a/src/test/java/net/helenus/test/integration/core/hierarchy/Pig.java +++ b/src/test/java/net/helenus/test/integration/core/hierarchy/Pig.java @@ -21,6 +21,6 @@ import net.helenus.mapping.annotation.Table; @Table("pigs") public interface Pig extends Mammal { - @Column(ordinal = 0) - String nickname(); + @Column(ordinal = 0) + String nickname(); } diff --git a/src/test/java/net/helenus/test/integration/core/index/Book.java b/src/test/java/net/helenus/test/integration/core/index/Book.java index 1dd86f2..0ae9ab0 100644 --- a/src/test/java/net/helenus/test/integration/core/index/Book.java +++ b/src/test/java/net/helenus/test/integration/core/index/Book.java @@ -23,13 +23,13 @@ import net.helenus.mapping.annotation.Table; @Table("books") public interface Book { - @PartitionKey(ordinal = 0) - long id(); + @PartitionKey(ordinal = 0) + long id(); - @Column(ordinal = 1) - @Index - String isbn(); + @Column(ordinal = 1) + @Index + String isbn(); - @Column(ordinal = 2) - String author(); + @Column(ordinal = 2) + String author(); } diff --git a/src/test/java/net/helenus/test/integration/core/index/SecondaryIndexTest.java b/src/test/java/net/helenus/test/integration/core/index/SecondaryIndexTest.java index 5882d8f..19ccdb0 100644 --- a/src/test/java/net/helenus/test/integration/core/index/SecondaryIndexTest.java +++ b/src/test/java/net/helenus/test/integration/core/index/SecondaryIndexTest.java @@ -16,39 +16,35 @@ package net.helenus.test.integration.core.index; import java.util.concurrent.TimeoutException; -import net.helenus.core.Helenus; -import net.helenus.core.HelenusSession; -import net.helenus.core.Query; -import net.helenus.test.integration.build.AbstractEmbeddedCassandraTest; + import org.junit.Assert; import org.junit.Before; import org.junit.Test; +import net.helenus.core.Helenus; +import net.helenus.core.HelenusSession; +import net.helenus.core.Query; +import net.helenus.test.integration.build.AbstractEmbeddedCassandraTest; + public class SecondaryIndexTest extends AbstractEmbeddedCassandraTest { - Book book; + Book book; - HelenusSession session; + HelenusSession session; - @Before - public void beforeTest() { - session = Helenus.init(getSession()).showCql().add(Book.class).autoCreateDrop().get(); - book = Helenus.dsl(Book.class, session.getMetadata()); - } + @Before + public void beforeTest() { + session = Helenus.init(getSession()).showCql().add(Book.class).autoCreateDrop().get(); + book = Helenus.dsl(Book.class, session.getMetadata()); + } - @Test - public void test() throws TimeoutException { + @Test + public void test() throws TimeoutException { - session - .insert() - .value(book::id, 123L) - .value(book::isbn, "ABC") - .value(book::author, "Alex") - .sync(); + session.insert().value(book::id, 123L).value(book::isbn, "ABC").value(book::author, "Alex").sync(); - long actualId = - session.select(book::id).where(book::isbn, Query.eq("ABC")).sync().findFirst().get()._1; + long actualId = session.select(book::id).where(book::isbn, Query.eq("ABC")).sync().findFirst().get()._1; - Assert.assertEquals(123L, actualId); - } + Assert.assertEquals(123L, actualId); + } } diff --git a/src/test/java/net/helenus/test/integration/core/prepared/Car.java b/src/test/java/net/helenus/test/integration/core/prepared/Car.java index c5fa342..e13fe6e 100644 --- a/src/test/java/net/helenus/test/integration/core/prepared/Car.java +++ b/src/test/java/net/helenus/test/integration/core/prepared/Car.java @@ -16,6 +16,7 @@ package net.helenus.test.integration.core.prepared; import java.math.BigDecimal; + import net.helenus.core.annotation.Cacheable; import net.helenus.mapping.annotation.PartitionKey; import net.helenus.mapping.annotation.Table; @@ -24,13 +25,13 @@ import net.helenus.mapping.annotation.Table; @Cacheable public interface Car { - @PartitionKey(ordinal = 0) - String make(); + @PartitionKey(ordinal = 0) + String make(); - @PartitionKey(ordinal = 1) - String model(); + @PartitionKey(ordinal = 1) + String model(); - int year(); + int year(); - BigDecimal price(); + BigDecimal price(); } diff --git a/src/test/java/net/helenus/test/integration/core/prepared/PreparedStatementTest.java b/src/test/java/net/helenus/test/integration/core/prepared/PreparedStatementTest.java index 4ea8271..1af35b8 100644 --- a/src/test/java/net/helenus/test/integration/core/prepared/PreparedStatementTest.java +++ b/src/test/java/net/helenus/test/integration/core/prepared/PreparedStatementTest.java @@ -15,8 +15,14 @@ */ package net.helenus.test.integration.core.prepared; -import com.datastax.driver.core.ResultSet; import java.math.BigDecimal; + +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; + +import com.datastax.driver.core.ResultSet; + import net.helenus.core.Helenus; import net.helenus.core.HelenusSession; import net.helenus.core.Query; @@ -24,115 +30,86 @@ import net.helenus.core.operation.PreparedOperation; import net.helenus.core.operation.PreparedStreamOperation; import net.helenus.support.Fun; import net.helenus.test.integration.build.AbstractEmbeddedCassandraTest; -import org.junit.Assert; -import org.junit.BeforeClass; -import org.junit.Test; public class PreparedStatementTest extends AbstractEmbeddedCassandraTest { - static Car car; + static Car car; - static HelenusSession session; + static HelenusSession session; - static PreparedOperation insertOp; + static PreparedOperation insertOp; - static PreparedOperation updateOp; + static PreparedOperation updateOp; - static PreparedStreamOperation selectOp; + static PreparedStreamOperation selectOp; - static PreparedStreamOperation> selectPriceOp; + static PreparedStreamOperation> selectPriceOp; - static PreparedOperation deleteOp; + static PreparedOperation deleteOp; - static PreparedOperation countOp; + static PreparedOperation countOp; - @BeforeClass - public static void beforeTest() { + @BeforeClass + public static void beforeTest() { - session = Helenus.init(getSession()).showCql().add(Car.class).autoCreateDrop().get(); - car = Helenus.dsl(Car.class, session.getMetadata()); + session = Helenus.init(getSession()).showCql().add(Car.class).autoCreateDrop().get(); + car = Helenus.dsl(Car.class, session.getMetadata()); - insertOp = - session - .insert() - .value(car::make, Query.marker()) - .value(car::model, Query.marker()) - .value(car::year, 2004) - .prepare(); + insertOp = session.insert().value(car::make, Query.marker()).value(car::model, Query.marker()) + .value(car::year, 2004).prepare(); - updateOp = - session - .update() - .set(car::price, Query.marker()) - .where(car::make, Query.eq(Query.marker())) - .and(car::model, Query.eq(Query.marker())) - .prepare(); + updateOp = session.update().set(car::price, Query.marker()).where(car::make, Query.eq(Query.marker())) + .and(car::model, Query.eq(Query.marker())).prepare(); - selectOp = - session - .select(car) - .where(car::make, Query.eq(Query.marker())) - .and(car::model, Query.eq(Query.marker())) - .prepare(); + selectOp = session.select(car).where(car::make, Query.eq(Query.marker())) + .and(car::model, Query.eq(Query.marker())).prepare(); - selectPriceOp = - session - .select(car::price) - .where(car::make, Query.eq(Query.marker())) - .and(car::model, Query.eq(Query.marker())) - .prepare(); + selectPriceOp = session.select(car::price).where(car::make, Query.eq(Query.marker())) + .and(car::model, Query.eq(Query.marker())).prepare(); - deleteOp = - session - .delete() - .where(car::make, Query.eq(Query.marker())) - .and(car::model, Query.eq(Query.marker())) - .prepare(); + deleteOp = session.delete().where(car::make, Query.eq(Query.marker())).and(car::model, Query.eq(Query.marker())) + .prepare(); - countOp = - session - .count() - .where(car::make, Query.eq(Query.marker())) - .and(car::model, Query.eq(Query.marker())) - .prepare(); - } + countOp = session.count().where(car::make, Query.eq(Query.marker())).and(car::model, Query.eq(Query.marker())) + .prepare(); + } - @Test - public void testPrint() { - System.out.println(car); - } + @Test + public void testPrint() { + System.out.println(car); + } - @Test - public void testCRUID() throws Exception { + @Test + public void testCRUID() throws Exception { - // INSERT + // INSERT - insertOp.bind("Nissan", "350Z").sync(); + insertOp.bind("Nissan", "350Z").sync(); - // SELECT + // SELECT - Car actual = selectOp.bind("Nissan", "350Z").sync().findFirst().get(); - Assert.assertEquals("Nissan", actual.make()); - Assert.assertEquals("350Z", actual.model()); - Assert.assertEquals(2004, actual.year()); - Assert.assertNull(actual.price()); + Car actual = selectOp.bind("Nissan", "350Z").sync().findFirst().get(); + Assert.assertEquals("Nissan", actual.make()); + Assert.assertEquals("350Z", actual.model()); + Assert.assertEquals(2004, actual.year()); + Assert.assertNull(actual.price()); - // UPDATE + // UPDATE - updateOp.bind(BigDecimal.valueOf(10000.0), "Nissan", "350Z").sync(); + updateOp.bind(BigDecimal.valueOf(10000.0), "Nissan", "350Z").sync(); - BigDecimal price = selectPriceOp.bind("Nissan", "350Z").sync().findFirst().get()._1; + BigDecimal price = selectPriceOp.bind("Nissan", "350Z").sync().findFirst().get()._1; - Assert.assertEquals(BigDecimal.valueOf(10000.0), price); + Assert.assertEquals(BigDecimal.valueOf(10000.0), price); - // DELETE + // DELETE - Long cnt = countOp.bind("Nissan", "350Z").sync(); - Assert.assertEquals(Long.valueOf(1), cnt); + Long cnt = countOp.bind("Nissan", "350Z").sync(); + Assert.assertEquals(Long.valueOf(1), cnt); - deleteOp.bind("Nissan", "350Z").sync(); + deleteOp.bind("Nissan", "350Z").sync(); - cnt = countOp.bind("Nissan", "350Z").sync(); - Assert.assertEquals(Long.valueOf(0), cnt); - } + cnt = countOp.bind("Nissan", "350Z").sync(); + Assert.assertEquals(Long.valueOf(0), cnt); + } } diff --git a/src/test/java/net/helenus/test/integration/core/simple/InsertPartialTest.java b/src/test/java/net/helenus/test/integration/core/simple/InsertPartialTest.java index 0ba0d1d..6445186 100644 --- a/src/test/java/net/helenus/test/integration/core/simple/InsertPartialTest.java +++ b/src/test/java/net/helenus/test/integration/core/simple/InsertPartialTest.java @@ -18,48 +18,49 @@ package net.helenus.test.integration.core.simple; import java.util.HashMap; import java.util.Map; import java.util.Random; -import net.helenus.core.Helenus; -import net.helenus.core.HelenusSession; -import net.helenus.core.operation.InsertOperation; -import net.helenus.test.integration.build.AbstractEmbeddedCassandraTest; + import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; +import net.helenus.core.Helenus; +import net.helenus.core.HelenusSession; +import net.helenus.core.operation.InsertOperation; +import net.helenus.test.integration.build.AbstractEmbeddedCassandraTest; + public class InsertPartialTest extends AbstractEmbeddedCassandraTest { - static HelenusSession session; - static User user; - static Random rnd = new Random(); + static HelenusSession session; + static User user; + static Random rnd = new Random(); - @BeforeClass - public static void beforeTests() { - session = Helenus.init(getSession()).showCql().add(User.class).autoCreateDrop().get(); - user = Helenus.dsl(User.class); - } + @BeforeClass + public static void beforeTests() { + session = Helenus.init(getSession()).showCql().add(User.class).autoCreateDrop().get(); + user = Helenus.dsl(User.class); + } - @Test - public void testPartialInsert() throws Exception { - Map map = new HashMap(); - Long id = rnd.nextLong(); - map.put("id", id); - map.put("age", 5); - InsertOperation insert = session.insert(Helenus.map(User.class, map)); - String cql = - "INSERT INTO simple_users (id,age) VALUES (" + id.toString() + ",5) IF NOT EXISTS;"; - Assert.assertEquals(cql, insert.cql()); - insert.sync(); - } + @Test + public void testPartialInsert() throws Exception { + Map map = new HashMap(); + Long id = rnd.nextLong(); + map.put("id", id); + map.put("age", 5); + InsertOperation insert = session.insert(Helenus.map(User.class, map)); + String cql = "INSERT INTO simple_users (id,age) VALUES (" + id.toString() + ",5) IF NOT EXISTS;"; + Assert.assertEquals(cql, insert.cql()); + insert.sync(); + } - @Test - public void testPartialUpsert() throws Exception { - Map map = new HashMap(); - Long id = rnd.nextLong(); - map.put("id", id); - map.put("age", 5); - InsertOperation upsert = session.upsert(Helenus.map(User.class, map)); - String cql = "INSERT INTO simple_users (id,age) VALUES (" + id.toString() + ",5);"; - Assert.assertEquals(cql, upsert.cql()); - upsert.sync(); - } + @Test + public void testPartialUpsert() throws Exception { + Map map = new HashMap(); + Long id = rnd.nextLong(); + map.put("id", id); + map.put("age", 5); + InsertOperation upsert = session.upsert(Helenus.map(User.class, map)); + String cql = "INSERT INTO simple_users (id,age) VALUES (" + id.toString() + ",5);"; + Assert.assertEquals(cql, upsert.cql()); + upsert.sync(); + } } diff --git a/src/test/java/net/helenus/test/integration/core/simple/Message.java b/src/test/java/net/helenus/test/integration/core/simple/Message.java index 832914b..f7c94c7 100644 --- a/src/test/java/net/helenus/test/integration/core/simple/Message.java +++ b/src/test/java/net/helenus/test/integration/core/simple/Message.java @@ -16,29 +16,25 @@ package net.helenus.test.integration.core.simple; import java.util.Date; -import net.helenus.mapping.annotation.ClusteringColumn; -import net.helenus.mapping.annotation.Column; -import net.helenus.mapping.annotation.PartitionKey; -import net.helenus.mapping.annotation.StaticColumn; -import net.helenus.mapping.annotation.Table; -import net.helenus.mapping.annotation.Types; + +import net.helenus.mapping.annotation.*; @Table public interface Message { - @PartitionKey - int id(); + @PartitionKey + int id(); - @ClusteringColumn - @Types.Timeuuid - Date timestamp(); + @ClusteringColumn + @Types.Timeuuid + Date timestamp(); - @StaticColumn(forceQuote = true) - String from(); + @StaticColumn(forceQuote = true) + String from(); - @Column(forceQuote = true) - String to(); + @Column(forceQuote = true) + String to(); - @Column - String message(); + @Column + String message(); } diff --git a/src/test/java/net/helenus/test/integration/core/simple/SimpleUserTest.java b/src/test/java/net/helenus/test/integration/core/simple/SimpleUserTest.java index 0a94e2b..27edf73 100644 --- a/src/test/java/net/helenus/test/integration/core/simple/SimpleUserTest.java +++ b/src/test/java/net/helenus/test/integration/core/simple/SimpleUserTest.java @@ -17,242 +17,173 @@ package net.helenus.test.integration.core.simple; import static net.helenus.core.Query.eq; -import com.datastax.driver.core.ResultSet; -import java.util.*; +import java.util.Optional; import java.util.concurrent.TimeoutException; + +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; + +import com.datastax.driver.core.ResultSet; + import net.helenus.core.Helenus; import net.helenus.core.HelenusSession; import net.helenus.core.Operator; import net.helenus.core.operation.UpdateOperation; import net.helenus.support.Fun; import net.helenus.test.integration.build.AbstractEmbeddedCassandraTest; -import org.junit.Assert; -import org.junit.BeforeClass; -import org.junit.Test; public class SimpleUserTest extends AbstractEmbeddedCassandraTest { - static User user; + static User user; - static HelenusSession session; + static HelenusSession session; - @BeforeClass - public static void beforeTest() { - session = Helenus.init(getSession()).showCql().add(User.class).autoCreateDrop().get(); - user = Helenus.dsl(User.class, session.getMetadata()); - } + @BeforeClass + public static void beforeTest() { + session = Helenus.init(getSession()).showCql().add(User.class).autoCreateDrop().get(); + user = Helenus.dsl(User.class, session.getMetadata()); + } - public static class UserImpl implements User { + @Test + public void testCruid() throws Exception { - Long id; - String name; - Integer age; - UserType type; + UserImpl newUser = new UserImpl(); + newUser.id = 100L; + newUser.name = "alex"; + newUser.age = 34; + newUser.type = UserType.USER; - @Override - public Long id() { - return id; - } + // CREATE - @Override - public String name() { - return name; - } + session.upsert(newUser).sync(); - @Override - public Integer age() { - return age; - } + // READ - @Override - public UserType type() { - return type; - } - } + // select row and map to entity - @Test - public void testCruid() throws Exception { + User actual = session.selectAll(User.class).mapTo(User.class).where(user::id, eq(100L)).sync().findFirst() + .get(); + assertUsers(newUser, actual); - UserImpl newUser = new UserImpl(); - newUser.id = 100L; - newUser.name = "alex"; - newUser.age = 34; - newUser.type = UserType.USER; + // select as object - // CREATE + actual = session.select(user).where(user::id, eq(100L)).single().sync().orElse(null); + assertUsers(newUser, actual); - session.upsert(newUser).sync(); + // select by columns - // READ + actual = session.select().column(user::id).column(user::name).column(user::age).column(user::type) + .mapTo(User.class).where(user::id, eq(100L)).sync().findFirst().get(); + assertUsers(newUser, actual); - // select row and map to entity + // select by columns - User actual = - session - .selectAll(User.class) - .mapTo(User.class) - .where(user::id, eq(100L)) - .sync() - .findFirst() - .get(); - assertUsers(newUser, actual); + actual = session.select(User.class).mapTo(User.class).where(user::id, eq(100L)).sync().findFirst().get(); + assertUsers(newUser, actual); - // select as object + // select as object and mapTo - actual = session.select(user).where(user::id, eq(100L)).single().sync().orElse(null); - assertUsers(newUser, actual); + actual = session.select(user::id, user::name, user::age, user::type).mapTo(User.class).where(user::id, eq(100L)) + .sync().findFirst().get(); + assertUsers(newUser, actual); - // select by columns + // select single column - actual = - session - .select() - .column(user::id) - .column(user::name) - .column(user::age) - .column(user::type) - .mapTo(User.class) - .where(user::id, eq(100L)) - .sync() - .findFirst() - .get(); - assertUsers(newUser, actual); + String name = session.select(user::name).where(user::id, eq(100L)).sync().findFirst().get()._1; - // select by columns + Assert.assertEquals(newUser.name(), name); - actual = - session - .select(User.class) - .mapTo(User.class) - .where(user::id, eq(100L)) - .sync() - .findFirst() - .get(); - assertUsers(newUser, actual); + // select single column in array tuple - // select as object and mapTo + name = (String) session.select().column(user::name).where(user::id, eq(100L)).sync().findFirst().get()._a[0]; - actual = - session - .select(user::id, user::name, user::age, user::type) - .mapTo(User.class) - .where(user::id, eq(100L)) - .sync() - .findFirst() - .get(); - assertUsers(newUser, actual); + Assert.assertEquals(newUser.name(), name); - // select single column + // UPDATE - String name = session.select(user::name).where(user::id, eq(100L)).sync().findFirst().get()._1; + session.update(user::name, "albert").set(user::age, 35).where(user::id, Operator.EQ, 100L).sync(); - Assert.assertEquals(newUser.name(), name); + long cnt = session.count(user).where(user::id, Operator.EQ, 100L).sync(); + Assert.assertEquals(1L, cnt); - // select single column in array tuple + name = session.select(user::name).where(user::id, Operator.EQ, 100L).map(t -> "_" + t._1).sync().findFirst() + .get(); - name = - (String) - session - .select() - .column(user::name) - .where(user::id, eq(100L)) - .sync() - .findFirst() - .get() - ._a[0]; + Assert.assertEquals("_albert", name); - Assert.assertEquals(newUser.name(), name); + User u2 = session.select(user).where(user::id, eq(100L)).single().sync().orElse(null); - // UPDATE + Assert.assertEquals(Long.valueOf(100L), u2.id()); + Assert.assertEquals("albert", u2.name()); + Assert.assertEquals(Integer.valueOf(35), u2.age()); - session - .update(user::name, "albert") - .set(user::age, 35) - .where(user::id, Operator.EQ, 100L) - .sync(); + // + User greg = session.insert(user).value(user::name, "greg").value(user::age, 44) + .value(user::type, UserType.USER).value(user::id, 1234L).sync(); - long cnt = session.count(user).where(user::id, Operator.EQ, 100L).sync(); - Assert.assertEquals(1L, cnt); + Optional maybeGreg = session.select(user).where(user::id, eq(1234L)).single().sync(); - name = - session - .select(user::name) - .where(user::id, Operator.EQ, 100L) - .map(t -> "_" + t._1) - .sync() - .findFirst() - .get(); + // INSERT - Assert.assertEquals("_albert", name); + session.update().set(user::name, null).set(user::age, null).set(user::type, null).where(user::id, eq(100L)) + .zipkinContext(null).sync(); - User u2 = session.select(user).where(user::id, eq(100L)).single().sync().orElse(null); + Fun.Tuple3 tuple = session.select(user::name, user::age, user::type) + .where(user::id, eq(100L)).sync().findFirst().get(); - Assert.assertEquals(Long.valueOf(100L), u2.id()); - Assert.assertEquals("albert", u2.name()); - Assert.assertEquals(Integer.valueOf(35), u2.age()); + Assert.assertNull(tuple._1); + Assert.assertNull(tuple._2); + Assert.assertNull(tuple._3); - // - User greg = - session - .insert(user) - .value(user::name, "greg") - .value(user::age, 44) - .value(user::type, UserType.USER) - .value(user::id, 1234L) - .sync(); + // DELETE - Optional maybeGreg = - session.select(user).where(user::id, eq(1234L)).single().sync(); + session.delete(user).where(user::id, eq(100L)).sync(); - // INSERT + cnt = session.select().count().where(user::id, eq(100L)).sync(); + Assert.assertEquals(0L, cnt); + } - session - .update() - .set(user::name, null) - .set(user::age, null) - .set(user::type, null) - .where(user::id, eq(100L)) - .zipkinContext(null) - .sync(); + public void testZipkin() throws TimeoutException { + session.update().set(user::name, null).set(user::age, null).set(user::type, null).where(user::id, eq(100L)) + .zipkinContext(null).sync(); - Fun.Tuple3 tuple = - session - .select(user::name, user::age, user::type) - .where(user::id, eq(100L)) - .sync() - .findFirst() - .get(); + UpdateOperation update = session.update(); + update.set(user::name, null).zipkinContext(null).sync(); + } - Assert.assertNull(tuple._1); - Assert.assertNull(tuple._2); - Assert.assertNull(tuple._3); + private void assertUsers(User expected, User actual) { + Assert.assertEquals(expected.id(), actual.id()); + Assert.assertEquals(expected.name(), actual.name()); + Assert.assertEquals(expected.age(), actual.age()); + Assert.assertEquals(expected.type(), actual.type()); + } - // DELETE + public static class UserImpl implements User { - session.delete(user).where(user::id, eq(100L)).sync(); + Long id; + String name; + Integer age; + UserType type; - cnt = session.select().count().where(user::id, eq(100L)).sync(); - Assert.assertEquals(0L, cnt); - } + @Override + public Long id() { + return id; + } - public void testZipkin() throws TimeoutException { - session - .update() - .set(user::name, null) - .set(user::age, null) - .set(user::type, null) - .where(user::id, eq(100L)) - .zipkinContext(null) - .sync(); + @Override + public String name() { + return name; + } - UpdateOperation update = session.update(); - update.set(user::name, null).zipkinContext(null).sync(); - } + @Override + public Integer age() { + return age; + } - private void assertUsers(User expected, User actual) { - Assert.assertEquals(expected.id(), actual.id()); - Assert.assertEquals(expected.name(), actual.name()); - Assert.assertEquals(expected.age(), actual.age()); - Assert.assertEquals(expected.type(), actual.type()); - } + @Override + public UserType type() { + return type; + } + } } diff --git a/src/test/java/net/helenus/test/integration/core/simple/StaticColumnTest.java b/src/test/java/net/helenus/test/integration/core/simple/StaticColumnTest.java index c4bd403..4f4f83b 100644 --- a/src/test/java/net/helenus/test/integration/core/simple/StaticColumnTest.java +++ b/src/test/java/net/helenus/test/integration/core/simple/StaticColumnTest.java @@ -19,152 +19,129 @@ import java.util.Date; import java.util.List; import java.util.concurrent.TimeoutException; import java.util.stream.Collectors; -import net.helenus.core.Helenus; -import net.helenus.core.HelenusSession; -import net.helenus.core.Query; -import net.helenus.test.integration.build.AbstractEmbeddedCassandraTest; + import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; +import net.helenus.core.Helenus; +import net.helenus.core.HelenusSession; +import net.helenus.core.Query; +import net.helenus.test.integration.build.AbstractEmbeddedCassandraTest; + public class StaticColumnTest extends AbstractEmbeddedCassandraTest { - static HelenusSession session; - static Message message; + static HelenusSession session; + static Message message; - @BeforeClass - public static void beforeTest() { - session = - Helenus.init(getSession()) - .showCql() - .addPackage(Message.class.getPackage().getName()) - .autoCreateDrop() - .get(); - message = Helenus.dsl(Message.class, session.getMetadata()); - } + @BeforeClass + public static void beforeTest() { + session = Helenus.init(getSession()).showCql().addPackage(Message.class.getPackage().getName()).autoCreateDrop() + .get(); + message = Helenus.dsl(Message.class, session.getMetadata()); + } - @Test - public void testPrint() { - System.out.println(message); - } + @Test + public void testPrint() { + System.out.println(message); + } - private static class MessageImpl implements Message { + @Test + public void testCRUID() throws TimeoutException { - int id; - Date timestamp; - String from; - String to; - String msg; + MessageImpl msg = new MessageImpl(); + msg.id = 123; + msg.timestamp = new Date(); + msg.from = "Alex"; + msg.to = "Bob"; + msg.msg = "hi"; - @Override - public int id() { - return id; - } + // CREATE - @Override - public Date timestamp() { - return timestamp; - } + session.insert(msg).sync(); - @Override - public String from() { - return from; - } + msg.id = 123; + msg.to = "Craig"; - @Override - public String to() { - return to; - } + session.insert(msg).sync(); - @Override - public String message() { - return msg; - } - } + // READ - @Test - public void testCRUID() throws TimeoutException { + List actual = session.select(message).where(message::id, Query.eq(123)).sync() + .collect(Collectors.toList()); - MessageImpl msg = new MessageImpl(); - msg.id = 123; - msg.timestamp = new Date(); - msg.from = "Alex"; - msg.to = "Bob"; - msg.msg = "hi"; + Assert.assertEquals(2, actual.size()); - // CREATE + Message toCraig = actual.stream().filter(m -> m.to().equals("Craig")).findFirst().get(); + assertMessages(msg, toCraig); - session.insert(msg).sync(); + // UPDATE - msg.id = 123; - msg.to = "Craig"; + session.update().set(message::from, "Albert").where(message::id, Query.eq(123)) + .onlyIf(message::from, Query.eq("Alex")).sync(); - session.insert(msg).sync(); + long cnt = session.select(message::from).where(message::id, Query.eq(123)).sync() + .filter(t -> t._1.equals("Albert")).count(); - // READ + Assert.assertEquals(2, cnt); - List actual = - session - .select(message) - .where(message::id, Query.eq(123)) - .sync() - .collect(Collectors.toList()); + // INSERT - Assert.assertEquals(2, actual.size()); + session.update().set(message::from, null).where(message::id, Query.eq(123)).sync(); - Message toCraig = actual.stream().filter(m -> m.to().equals("Craig")).findFirst().get(); - assertMessages(msg, toCraig); + session.select(message::from).where(message::id, Query.eq(123)).sync().map(t -> t._1) + .forEach(Assert::assertNull); - // UPDATE + session.update().set(message::from, "Alex").where(message::id, Query.eq(123)) + .onlyIf(message::from, Query.eq(null)).sync(); - session - .update() - .set(message::from, "Albert") - .where(message::id, Query.eq(123)) - .onlyIf(message::from, Query.eq("Alex")) - .sync(); + // DELETE - long cnt = - session - .select(message::from) - .where(message::id, Query.eq(123)) - .sync() - .filter(t -> t._1.equals("Albert")) - .count(); + session.delete().where(message::id, Query.eq(123)).sync(); - Assert.assertEquals(2, cnt); + cnt = session.count().where(message::id, Query.eq(123)).sync(); + Assert.assertEquals(0, cnt); + } - // INSERT + private void assertMessages(Message expected, Message actual) { + Assert.assertEquals(expected.id(), actual.id()); + Assert.assertEquals(expected.from(), actual.from()); + Assert.assertEquals(expected.timestamp(), actual.timestamp()); + Assert.assertEquals(expected.to(), actual.to()); + Assert.assertEquals(expected.message(), actual.message()); + } - session.update().set(message::from, null).where(message::id, Query.eq(123)).sync(); + private static class MessageImpl implements Message { - session - .select(message::from) - .where(message::id, Query.eq(123)) - .sync() - .map(t -> t._1) - .forEach(Assert::assertNull); + int id; + Date timestamp; + String from; + String to; + String msg; - session - .update() - .set(message::from, "Alex") - .where(message::id, Query.eq(123)) - .onlyIf(message::from, Query.eq(null)) - .sync(); + @Override + public int id() { + return id; + } - // DELETE + @Override + public Date timestamp() { + return timestamp; + } - session.delete().where(message::id, Query.eq(123)).sync(); + @Override + public String from() { + return from; + } - cnt = session.count().where(message::id, Query.eq(123)).sync(); - Assert.assertEquals(0, cnt); - } + @Override + public String to() { + return to; + } - private void assertMessages(Message expected, Message actual) { - Assert.assertEquals(expected.id(), actual.id()); - Assert.assertEquals(expected.from(), actual.from()); - Assert.assertEquals(expected.timestamp(), actual.timestamp()); - Assert.assertEquals(expected.to(), actual.to()); - Assert.assertEquals(expected.message(), actual.message()); - } + @Override + public String message() { + return msg; + } + } } diff --git a/src/test/java/net/helenus/test/integration/core/simple/User.java b/src/test/java/net/helenus/test/integration/core/simple/User.java index f2375e1..f0d5ad4 100644 --- a/src/test/java/net/helenus/test/integration/core/simple/User.java +++ b/src/test/java/net/helenus/test/integration/core/simple/User.java @@ -15,7 +15,6 @@ */ package net.helenus.test.integration.core.simple; -import net.helenus.core.annotation.Cacheable; import net.helenus.mapping.annotation.Column; import net.helenus.mapping.annotation.PartitionKey; import net.helenus.mapping.annotation.Table; @@ -23,14 +22,14 @@ import net.helenus.mapping.annotation.Table; @Table("simple_users") public interface User { - @PartitionKey - Long id(); + @PartitionKey + Long id(); - @Username - @Column("override_name") - String name(); + @Username + @Column("override_name") + String name(); - Integer age(); + Integer age(); - UserType type(); + UserType type(); } diff --git a/src/test/java/net/helenus/test/integration/core/simple/UserType.java b/src/test/java/net/helenus/test/integration/core/simple/UserType.java index 495c799..0a425ce 100644 --- a/src/test/java/net/helenus/test/integration/core/simple/UserType.java +++ b/src/test/java/net/helenus/test/integration/core/simple/UserType.java @@ -16,6 +16,5 @@ package net.helenus.test.integration.core.simple; public enum UserType { - USER, - ADMIN; + USER, ADMIN; } diff --git a/src/test/java/net/helenus/test/integration/core/simple/Username.java b/src/test/java/net/helenus/test/integration/core/simple/Username.java index fa80b0e..3643e3a 100644 --- a/src/test/java/net/helenus/test/integration/core/simple/Username.java +++ b/src/test/java/net/helenus/test/integration/core/simple/Username.java @@ -15,15 +15,13 @@ */ package net.helenus.test.integration.core.simple; -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; +import java.lang.annotation.*; + import net.helenus.mapping.annotation.Constraints; @Documented @Retention(RetentionPolicy.RUNTIME) @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) @Constraints.LowerCase -public @interface Username {} +public @interface Username { +} diff --git a/src/test/java/net/helenus/test/integration/core/tuple/Album.java b/src/test/java/net/helenus/test/integration/core/tuple/Album.java index 8cc2c43..05f381d 100644 --- a/src/test/java/net/helenus/test/integration/core/tuple/Album.java +++ b/src/test/java/net/helenus/test/integration/core/tuple/Album.java @@ -17,6 +17,7 @@ package net.helenus.test.integration.core.tuple; import com.datastax.driver.core.DataType; import com.datastax.driver.core.TupleValue; + import net.helenus.mapping.annotation.Column; import net.helenus.mapping.annotation.PartitionKey; import net.helenus.mapping.annotation.Table; @@ -25,12 +26,12 @@ import net.helenus.mapping.annotation.Types; @Table public interface Album { - @PartitionKey(ordinal = 1) - int id(); + @PartitionKey(ordinal = 1) + int id(); - AlbumInformation info(); + AlbumInformation info(); - @Types.Tuple({DataType.Name.TEXT, DataType.Name.TEXT}) - @Column(ordinal = 1) - TupleValue infoNoMapping(); + @Types.Tuple({DataType.Name.TEXT, DataType.Name.TEXT}) + @Column(ordinal = 1) + TupleValue infoNoMapping(); } diff --git a/src/test/java/net/helenus/test/integration/core/tuple/AlbumInformation.java b/src/test/java/net/helenus/test/integration/core/tuple/AlbumInformation.java index 7211999..3b2235c 100644 --- a/src/test/java/net/helenus/test/integration/core/tuple/AlbumInformation.java +++ b/src/test/java/net/helenus/test/integration/core/tuple/AlbumInformation.java @@ -21,9 +21,9 @@ import net.helenus.mapping.annotation.Tuple; @Tuple public interface AlbumInformation { - @Column(ordinal = 0) - String about(); + @Column(ordinal = 0) + String about(); - @Column(ordinal = 1) - String place(); + @Column(ordinal = 1) + String place(); } diff --git a/src/test/java/net/helenus/test/integration/core/tuple/DslTest.java b/src/test/java/net/helenus/test/integration/core/tuple/DslTest.java index 41667d5..4a3999a 100644 --- a/src/test/java/net/helenus/test/integration/core/tuple/DslTest.java +++ b/src/test/java/net/helenus/test/integration/core/tuple/DslTest.java @@ -15,20 +15,21 @@ */ package net.helenus.test.integration.core.tuple; -import net.helenus.core.Helenus; -import net.helenus.test.integration.build.AbstractEmbeddedCassandraTest; import org.junit.Assert; import org.junit.Test; +import net.helenus.core.Helenus; +import net.helenus.test.integration.build.AbstractEmbeddedCassandraTest; + public class DslTest extends AbstractEmbeddedCassandraTest { - @Test - public void testDslBeforeSessionInit() { - Assert.assertNotNull(Helenus.dsl(Album.class)); - } + @Test + public void testDslBeforeSessionInit() { + Assert.assertNotNull(Helenus.dsl(Album.class)); + } - @Test - public void testSessionInitAddingDslProxy() { - Assert.assertNotNull(Helenus.init(getSession()).showCql().add(Helenus.dsl(Album.class))); - } + @Test + public void testSessionInitAddingDslProxy() { + Assert.assertNotNull(Helenus.init(getSession()).showCql().add(Helenus.dsl(Album.class))); + } } diff --git a/src/test/java/net/helenus/test/integration/core/tuple/InnerTupleTest.java b/src/test/java/net/helenus/test/integration/core/tuple/InnerTupleTest.java index 500689b..8e23606 100644 --- a/src/test/java/net/helenus/test/integration/core/tuple/InnerTupleTest.java +++ b/src/test/java/net/helenus/test/integration/core/tuple/InnerTupleTest.java @@ -16,129 +16,108 @@ package net.helenus.test.integration.core.tuple; import java.util.concurrent.TimeoutException; -import net.helenus.core.Helenus; -import net.helenus.core.HelenusSession; -import net.helenus.core.Query; -import net.helenus.test.integration.build.AbstractEmbeddedCassandraTest; + import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; +import net.helenus.core.Helenus; +import net.helenus.core.HelenusSession; +import net.helenus.core.Query; +import net.helenus.test.integration.build.AbstractEmbeddedCassandraTest; + public class InnerTupleTest extends AbstractEmbeddedCassandraTest { - static PhotoAlbum photoAlbum; + static PhotoAlbum photoAlbum; - static HelenusSession session; + static HelenusSession session; - @BeforeClass - public static void beforeTest() { - session = Helenus.init(getSession()).showCql().add(PhotoAlbum.class).autoCreateDrop().get(); - photoAlbum = Helenus.dsl(PhotoAlbum.class, session.getMetadata()); - } + @BeforeClass + public static void beforeTest() { + session = Helenus.init(getSession()).showCql().add(PhotoAlbum.class).autoCreateDrop().get(); + photoAlbum = Helenus.dsl(PhotoAlbum.class, session.getMetadata()); + } - @Test - public void testPrint() { - System.out.println(photoAlbum); - } + @Test + public void testPrint() { + System.out.println(photoAlbum); + } - @Test - public void testCruid() throws TimeoutException { + @Test + public void testCruid() throws TimeoutException { - Photo photo = - new Photo() { + Photo photo = new Photo() { - @Override - public byte[] blob() { - return "jpeg".getBytes(); - } - }; + @Override + public byte[] blob() { + return "jpeg".getBytes(); + } + }; - PhotoFolder folder = - new PhotoFolder() { + PhotoFolder folder = new PhotoFolder() { - @Override - public String name() { - return "first"; - } + @Override + public String name() { + return "first"; + } - @Override - public Photo photo() { - return photo; - } - }; + @Override + public Photo photo() { + return photo; + } + }; - // CREATE (C) + // CREATE (C) - session.insert().value(photoAlbum::id, 123).value(photoAlbum::folder, folder).sync(); + session.insert().value(photoAlbum::id, 123).value(photoAlbum::folder, folder).sync(); - // READ (R) + // READ (R) - PhotoFolder actual = - session - .select(photoAlbum::folder) - .where(photoAlbum::id, Query.eq(123)) - .sync() - .findFirst() - .get() - ._1; + PhotoFolder actual = session.select(photoAlbum::folder).where(photoAlbum::id, Query.eq(123)).sync().findFirst() + .get()._1; - Assert.assertEquals(folder.name(), actual.name()); + Assert.assertEquals(folder.name(), actual.name()); - // UPDATE (U) + // UPDATE (U) - // unfortunately this is not working right now in Cassandra, can not update a single column in tuple :( - //session.update() - // .set(photoAlbum.folder().photo()::blob, "Helenus".getBytes()) - // .where(photoAlbum::id, eq(123)) - // .sync(); + // unfortunately this is not working right now in Cassandra, can not update a + // single column in tuple :( + // session.update() + // .set(photoAlbum.folder().photo()::blob, "Helenus".getBytes()) + // .where(photoAlbum::id, eq(123)) + // .sync(); - PhotoFolder expected = - new PhotoFolder() { + PhotoFolder expected = new PhotoFolder() { - @Override - public String name() { - return "seconds"; - } + @Override + public String name() { + return "seconds"; + } - @Override - public Photo photo() { - return photo; - } - }; + @Override + public Photo photo() { + return photo; + } + }; - session.update().set(photoAlbum::folder, expected).where(photoAlbum::id, Query.eq(123)).sync(); + session.update().set(photoAlbum::folder, expected).where(photoAlbum::id, Query.eq(123)).sync(); - actual = - session - .select(photoAlbum::folder) - .where(photoAlbum::id, Query.eq(123)) - .sync() - .findFirst() - .get() - ._1; + actual = session.select(photoAlbum::folder).where(photoAlbum::id, Query.eq(123)).sync().findFirst().get()._1; - Assert.assertEquals(expected.name(), actual.name()); + Assert.assertEquals(expected.name(), actual.name()); - // INSERT (I) - // let's insert null ;) + // INSERT (I) + // let's insert null ;) - session.update().set(photoAlbum::folder, null).where(photoAlbum::id, Query.eq(123)).sync(); + session.update().set(photoAlbum::folder, null).where(photoAlbum::id, Query.eq(123)).sync(); - actual = - session - .select(photoAlbum::folder) - .where(photoAlbum::id, Query.eq(123)) - .sync() - .findFirst() - .get() - ._1; - Assert.assertNull(actual); + actual = session.select(photoAlbum::folder).where(photoAlbum::id, Query.eq(123)).sync().findFirst().get()._1; + Assert.assertNull(actual); - // DELETE (D) - session.delete().where(photoAlbum::id, Query.eq(123)).sync(); + // DELETE (D) + session.delete().where(photoAlbum::id, Query.eq(123)).sync(); - long cnt = - session.select(photoAlbum::folder).where(photoAlbum::id, Query.eq(123)).sync().count(); - Assert.assertEquals(0, cnt); - } + long cnt = session.select(photoAlbum::folder).where(photoAlbum::id, Query.eq(123)).sync().count(); + Assert.assertEquals(0, cnt); + } } diff --git a/src/test/java/net/helenus/test/integration/core/tuple/Photo.java b/src/test/java/net/helenus/test/integration/core/tuple/Photo.java index ffae61c..1bf0215 100644 --- a/src/test/java/net/helenus/test/integration/core/tuple/Photo.java +++ b/src/test/java/net/helenus/test/integration/core/tuple/Photo.java @@ -20,5 +20,5 @@ import net.helenus.mapping.annotation.Tuple; @Tuple public interface Photo { - byte[] blob(); + byte[] blob(); } diff --git a/src/test/java/net/helenus/test/integration/core/tuple/PhotoAlbum.java b/src/test/java/net/helenus/test/integration/core/tuple/PhotoAlbum.java index a499e2c..1f6d40a 100644 --- a/src/test/java/net/helenus/test/integration/core/tuple/PhotoAlbum.java +++ b/src/test/java/net/helenus/test/integration/core/tuple/PhotoAlbum.java @@ -21,8 +21,8 @@ import net.helenus.mapping.annotation.Table; @Table public interface PhotoAlbum { - @PartitionKey - int id(); + @PartitionKey + int id(); - PhotoFolder folder(); + PhotoFolder folder(); } diff --git a/src/test/java/net/helenus/test/integration/core/tuple/PhotoFolder.java b/src/test/java/net/helenus/test/integration/core/tuple/PhotoFolder.java index 2b3a541..4352a37 100644 --- a/src/test/java/net/helenus/test/integration/core/tuple/PhotoFolder.java +++ b/src/test/java/net/helenus/test/integration/core/tuple/PhotoFolder.java @@ -21,9 +21,9 @@ import net.helenus.mapping.annotation.Tuple; @Tuple public interface PhotoFolder { - @Column(ordinal = 0) - String name(); + @Column(ordinal = 0) + String name(); - @Column(ordinal = 1) - Photo photo(); + @Column(ordinal = 1) + Photo photo(); } diff --git a/src/test/java/net/helenus/test/integration/core/tuple/TupleTest.java b/src/test/java/net/helenus/test/integration/core/tuple/TupleTest.java index 5fbe1b7..42885e6 100644 --- a/src/test/java/net/helenus/test/integration/core/tuple/TupleTest.java +++ b/src/test/java/net/helenus/test/integration/core/tuple/TupleTest.java @@ -17,157 +17,155 @@ package net.helenus.test.integration.core.tuple; import static net.helenus.core.Query.eq; -import com.datastax.driver.core.DataType; -import com.datastax.driver.core.TupleType; -import com.datastax.driver.core.TupleValue; import java.util.concurrent.TimeoutException; -import net.helenus.core.Helenus; -import net.helenus.core.HelenusSession; -import net.helenus.test.integration.build.AbstractEmbeddedCassandraTest; + import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; +import com.datastax.driver.core.DataType; +import com.datastax.driver.core.TupleType; +import com.datastax.driver.core.TupleValue; + +import net.helenus.core.Helenus; +import net.helenus.core.HelenusSession; +import net.helenus.test.integration.build.AbstractEmbeddedCassandraTest; + public class TupleTest extends AbstractEmbeddedCassandraTest { - static Album album; + static Album album; - static HelenusSession session; + static HelenusSession session; - @BeforeClass - public static void beforeTest() { - Helenus.clearDslCache(); - session = Helenus.init(getSession()).showCql().add(Album.class).autoCreateDrop().get(); - album = Helenus.dsl(Album.class, session.getMetadata()); - } + @BeforeClass + public static void beforeTest() { + Helenus.clearDslCache(); + session = Helenus.init(getSession()).showCql().add(Album.class).autoCreateDrop().get(); + album = Helenus.dsl(Album.class, session.getMetadata()); + } - @Test - public void testPrint() { - System.out.println(album); - } + @Test + public void testPrint() { + System.out.println(album); + } - @Test - public void testCruid() throws TimeoutException { + @Test + public void testCruid() throws TimeoutException { - AlbumInformation info = - new AlbumInformation() { + AlbumInformation info = new AlbumInformation() { - @Override - public String about() { - return "Cassandra"; - } + @Override + public String about() { + return "Cassandra"; + } - @Override - public String place() { - return "San Jose"; - } - }; + @Override + public String place() { + return "San Jose"; + } + }; - // CREATE (C) + // CREATE (C) - session.insert().value(album::id, 123).value(album::info, info).sync(); + session.insert().value(album::id, 123).value(album::info, info).sync(); - // READ (R) + // READ (R) - AlbumInformation actual = - session.select(album::info).where(album::id, eq(123)).sync().findFirst().get()._1; + AlbumInformation actual = session.select(album::info).where(album::id, eq(123)).sync().findFirst().get()._1; - Assert.assertEquals(info.about(), actual.about()); - Assert.assertEquals(info.place(), actual.place()); + Assert.assertEquals(info.about(), actual.about()); + Assert.assertEquals(info.place(), actual.place()); - // UPDATE (U) + // UPDATE (U) - // unfortunately this is not working right now in Cassandra, can not update a single column in tuple :( - //session.update() - // .set(album.info()::about, "Helenus") - // .where(album::id, eq(123)) - // .sync(); + // unfortunately this is not working right now in Cassandra, can not update a + // single column in tuple :( + // session.update() + // .set(album.info()::about, "Helenus") + // .where(album::id, eq(123)) + // .sync(); - AlbumInformation expected = - new AlbumInformation() { + AlbumInformation expected = new AlbumInformation() { - @Override - public String about() { - return "Helenus"; - } + @Override + public String about() { + return "Helenus"; + } - @Override - public String place() { - return "Santa Cruz"; - } - }; + @Override + public String place() { + return "Santa Cruz"; + } + }; - session.update().set(album::info, expected).where(album::id, eq(123)).sync(); + session.update().set(album::info, expected).where(album::id, eq(123)).sync(); - actual = session.select(album::info).where(album::id, eq(123)).sync().findFirst().get()._1; + actual = session.select(album::info).where(album::id, eq(123)).sync().findFirst().get()._1; - Assert.assertEquals(expected.about(), actual.about()); - Assert.assertEquals(expected.place(), actual.place()); + Assert.assertEquals(expected.about(), actual.about()); + Assert.assertEquals(expected.place(), actual.place()); - // INSERT (I) - // let's insert null ;) + // INSERT (I) + // let's insert null ;) - session.update().set(album::info, null).where(album::id, eq(123)).sync(); + session.update().set(album::info, null).where(album::id, eq(123)).sync(); - actual = session.select(album::info).where(album::id, eq(123)).sync().findFirst().get()._1; - Assert.assertNull(actual); + actual = session.select(album::info).where(album::id, eq(123)).sync().findFirst().get()._1; + Assert.assertNull(actual); - // DELETE (D) - session.delete().where(album::id, eq(123)).sync(); + // DELETE (D) + session.delete().where(album::id, eq(123)).sync(); - long cnt = session.select(album::info).where(album::id, eq(123)).sync().count(); - Assert.assertEquals(0, cnt); - } + long cnt = session.select(album::info).where(album::id, eq(123)).sync().count(); + Assert.assertEquals(0, cnt); + } - @Test - public void testNoMapping() throws TimeoutException { + @Test + public void testNoMapping() throws TimeoutException { - TupleType tupleType = session.getMetadata().newTupleType(DataType.text(), DataType.text()); - TupleValue info = tupleType.newValue(); + TupleType tupleType = session.getMetadata().newTupleType(DataType.text(), DataType.text()); + TupleValue info = tupleType.newValue(); - info.setString(0, "Cassandra"); - info.setString(1, "San Jose"); + info.setString(0, "Cassandra"); + info.setString(1, "San Jose"); - // CREATE (C) + // CREATE (C) - session.insert().value(album::id, 555).value(album::infoNoMapping, info).sync(); + session.insert().value(album::id, 555).value(album::infoNoMapping, info).sync(); - // READ (R) + // READ (R) - TupleValue actual = - session.select(album::infoNoMapping).where(album::id, eq(555)).sync().findFirst().get()._1; + TupleValue actual = session.select(album::infoNoMapping).where(album::id, eq(555)).sync().findFirst().get()._1; - Assert.assertEquals(info.getString(0), actual.getString(0)); - Assert.assertEquals(info.getString(1), actual.getString(1)); + Assert.assertEquals(info.getString(0), actual.getString(0)); + Assert.assertEquals(info.getString(1), actual.getString(1)); - // UPDATE (U) + // UPDATE (U) - TupleValue expected = tupleType.newValue(); + TupleValue expected = tupleType.newValue(); - expected.setString(0, "Helenus"); - expected.setString(1, "Los Altos"); + expected.setString(0, "Helenus"); + expected.setString(1, "Los Altos"); - session.update().set(album::infoNoMapping, expected).where(album::id, eq(555)).sync(); + session.update().set(album::infoNoMapping, expected).where(album::id, eq(555)).sync(); - actual = - session.select(album::infoNoMapping).where(album::id, eq(555)).sync().findFirst().get()._1; + actual = session.select(album::infoNoMapping).where(album::id, eq(555)).sync().findFirst().get()._1; - Assert.assertEquals(expected.getString(0), actual.getString(0)); - Assert.assertEquals(expected.getString(1), actual.getString(1)); + Assert.assertEquals(expected.getString(0), actual.getString(0)); + Assert.assertEquals(expected.getString(1), actual.getString(1)); - // INSERT (I) - // let's insert null ;) + // INSERT (I) + // let's insert null ;) - session.update().set(album::infoNoMapping, null).where(album::id, eq(555)).sync(); + session.update().set(album::infoNoMapping, null).where(album::id, eq(555)).sync(); - actual = - session.select(album::infoNoMapping).where(album::id, eq(555)).sync().findFirst().get()._1; - Assert.assertNull(actual); + actual = session.select(album::infoNoMapping).where(album::id, eq(555)).sync().findFirst().get()._1; + Assert.assertNull(actual); - // DELETE (D) - session.delete().where(album::id, eq(555)).sync(); + // DELETE (D) + session.delete().where(album::id, eq(555)).sync(); - long cnt = session.select(album::infoNoMapping).where(album::id, eq(555)).sync().count(); - Assert.assertEquals(0, cnt); - } + long cnt = session.select(album::infoNoMapping).where(album::id, eq(555)).sync().count(); + Assert.assertEquals(0, cnt); + } } diff --git a/src/test/java/net/helenus/test/integration/core/tuplecollection/Author.java b/src/test/java/net/helenus/test/integration/core/tuplecollection/Author.java index 8e4af61..c1487e0 100644 --- a/src/test/java/net/helenus/test/integration/core/tuplecollection/Author.java +++ b/src/test/java/net/helenus/test/integration/core/tuplecollection/Author.java @@ -21,9 +21,9 @@ import net.helenus.mapping.annotation.Tuple; @Tuple public interface Author { - @Column(ordinal = 0) - String name(); + @Column(ordinal = 0) + String name(); - @Column(ordinal = 1) - String city(); + @Column(ordinal = 1) + String city(); } diff --git a/src/test/java/net/helenus/test/integration/core/tuplecollection/Book.java b/src/test/java/net/helenus/test/integration/core/tuplecollection/Book.java index a243efb..53862a3 100644 --- a/src/test/java/net/helenus/test/integration/core/tuplecollection/Book.java +++ b/src/test/java/net/helenus/test/integration/core/tuplecollection/Book.java @@ -18,22 +18,23 @@ package net.helenus.test.integration.core.tuplecollection; import java.util.List; import java.util.Map; import java.util.Set; + import net.helenus.mapping.annotation.PartitionKey; import net.helenus.mapping.annotation.Table; @Table public interface Book { - @PartitionKey - int id(); + @PartitionKey + int id(); - List authors(); + List authors(); - Set reviewers(); + Set reviewers(); - Map contents(); + Map contents(); - Map notes(); + Map notes(); - Map writers(); + Map writers(); } diff --git a/src/test/java/net/helenus/test/integration/core/tuplecollection/Section.java b/src/test/java/net/helenus/test/integration/core/tuplecollection/Section.java index f2edc33..9581df3 100644 --- a/src/test/java/net/helenus/test/integration/core/tuplecollection/Section.java +++ b/src/test/java/net/helenus/test/integration/core/tuplecollection/Section.java @@ -21,9 +21,9 @@ import net.helenus.mapping.annotation.Tuple; @Tuple public interface Section { - @Column(ordinal = 0) - String title(); + @Column(ordinal = 0) + String title(); - @Column(ordinal = 1) - int page(); + @Column(ordinal = 1) + int page(); } diff --git a/src/test/java/net/helenus/test/integration/core/tuplecollection/TupleCollectionTest.java b/src/test/java/net/helenus/test/integration/core/tuplecollection/TupleCollectionTest.java index 526cf8b..628ab79 100644 --- a/src/test/java/net/helenus/test/integration/core/tuplecollection/TupleCollectionTest.java +++ b/src/test/java/net/helenus/test/integration/core/tuplecollection/TupleCollectionTest.java @@ -15,124 +15,138 @@ */ package net.helenus.test.integration.core.tuplecollection; -import net.helenus.core.Helenus; -import net.helenus.core.HelenusSession; -import net.helenus.test.integration.build.AbstractEmbeddedCassandraTest; import org.junit.BeforeClass; import org.junit.Test; +import net.helenus.core.Helenus; +import net.helenus.core.HelenusSession; +import net.helenus.test.integration.build.AbstractEmbeddedCassandraTest; + public abstract class TupleCollectionTest extends AbstractEmbeddedCassandraTest { - static Book book; + static Book book; - static HelenusSession session; + static HelenusSession session; - @BeforeClass - public static void beforeTest() { - session = Helenus.init(getSession()).showCql().add(Book.class).autoCreateDrop().get(); - book = Helenus.dsl(Book.class, session.getMetadata()); - } + @BeforeClass + public static void beforeTest() { + session = Helenus.init(getSession()).showCql().add(Book.class).autoCreateDrop().get(); + book = Helenus.dsl(Book.class, session.getMetadata()); + } - @Test - public void test() { - System.out.println(book); - } + @Test + public void test() { + System.out.println(book); + } - public static final class AuthorImpl implements Author { + public static final class AuthorImpl implements Author { - String name; - String city; + String name; + String city; - AuthorImpl(String name, String city) { - this.name = name; - this.city = city; - } + AuthorImpl(String name, String city) { + this.name = name; + this.city = city; + } - @Override - public String name() { - return name; - } + @Override + public String name() { + return name; + } - @Override - public String city() { - return city; - } + @Override + public String city() { + return city; + } - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((city == null) ? 0 : city.hashCode()); - result = prime * result + ((name == null) ? 0 : name.hashCode()); - return result; - } + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((city == null) ? 0 : city.hashCode()); + result = prime * result + ((name == null) ? 0 : name.hashCode()); + return result; + } - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (obj == null) return false; - if (getClass() != obj.getClass()) return false; - AuthorImpl other = (AuthorImpl) obj; - if (city == null) { - if (other.city != null) return false; - } else if (!city.equals(other.city)) return false; - if (name == null) { - if (other.name != null) return false; - } else if (!name.equals(other.name)) return false; - return true; - } + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + AuthorImpl other = (AuthorImpl) obj; + if (city == null) { + if (other.city != null) + return false; + } else if (!city.equals(other.city)) + return false; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + return true; + } - @Override - public String toString() { - return "AuthorImpl [name=" + name + ", city=" + city + "]"; - } - } + @Override + public String toString() { + return "AuthorImpl [name=" + name + ", city=" + city + "]"; + } + } - public static final class SectionImpl implements Section { + public static final class SectionImpl implements Section { - String title; - int page; + String title; + int page; - SectionImpl(String title, int page) { - this.title = title; - this.page = page; - } + SectionImpl(String title, int page) { + this.title = title; + this.page = page; + } - @Override - public String title() { - return title; - } + @Override + public String title() { + return title; + } - @Override - public int page() { - return page; - } + @Override + public int page() { + return page; + } - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + page; - result = prime * result + ((title == null) ? 0 : title.hashCode()); - return result; - } + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + page; + result = prime * result + ((title == null) ? 0 : title.hashCode()); + return result; + } - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (obj == null) return false; - if (getClass() != obj.getClass()) return false; - SectionImpl other = (SectionImpl) obj; - if (page != other.page) return false; - if (title == null) { - if (other.title != null) return false; - } else if (!title.equals(other.title)) return false; - return true; - } + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + SectionImpl other = (SectionImpl) obj; + if (page != other.page) + return false; + if (title == null) { + if (other.title != null) + return false; + } else if (!title.equals(other.title)) + return false; + return true; + } - @Override - public String toString() { - return "SectionImpl [title=" + title + ", page=" + page + "]"; - } - } + @Override + public String toString() { + return "SectionImpl [title=" + title + ", page=" + page + "]"; + } + } } diff --git a/src/test/java/net/helenus/test/integration/core/tuplecollection/TupleKeyMapTest.java b/src/test/java/net/helenus/test/integration/core/tuplecollection/TupleKeyMapTest.java index b5501e3..41308fc 100644 --- a/src/test/java/net/helenus/test/integration/core/tuplecollection/TupleKeyMapTest.java +++ b/src/test/java/net/helenus/test/integration/core/tuplecollection/TupleKeyMapTest.java @@ -18,130 +18,123 @@ package net.helenus.test.integration.core.tuplecollection; import java.util.HashMap; import java.util.Map; import java.util.concurrent.TimeoutException; -import net.helenus.core.Query; + import org.junit.Assert; import org.junit.Test; +import net.helenus.core.Query; + public class TupleKeyMapTest extends TupleCollectionTest { - @Test - public void testKeyMapCRUID() throws TimeoutException { + @Test + public void testKeyMapCRUID() throws TimeoutException { - int id = 888; + int id = 888; - Map notes = new HashMap(); - notes.put(new SectionImpl("first", 1), "value1"); - notes.put(new SectionImpl("second", 2), "value2"); + Map notes = new HashMap(); + notes.put(new SectionImpl("first", 1), "value1"); + notes.put(new SectionImpl("second", 2), "value2"); - // CREATE + // CREATE - session.insert().value(book::id, id).value(book::notes, notes).sync(); + session.insert().value(book::id, id).value(book::notes, notes).sync(); - // READ + // READ - // read full object + // read full object - Book actual = session.select(book).where(book::id, Query.eq(id)).sync().findFirst().get(); - Assert.assertEquals(id, actual.id()); - assertEqualMaps(notes, actual.notes()); - Assert.assertNull(actual.reviewers()); - Assert.assertNull(actual.writers()); - Assert.assertNull(actual.contents()); + Book actual = session.select(book).where(book::id, Query.eq(id)).sync().findFirst().get(); + Assert.assertEquals(id, actual.id()); + assertEqualMaps(notes, actual.notes()); + Assert.assertNull(actual.reviewers()); + Assert.assertNull(actual.writers()); + Assert.assertNull(actual.contents()); - // read full map + // read full map - Map actualMap = - session.select(book::notes).where(book::id, Query.eq(id)).sync().findFirst().get()._1; - assertEqualMaps(notes, actualMap); + Map actualMap = session.select(book::notes).where(book::id, Query.eq(id)).sync().findFirst() + .get()._1; + assertEqualMaps(notes, actualMap); - // read single key-value in map + // read single key-value in map - String cql = - session - .select(Query.get(book::notes, new SectionImpl("first", 1))) - .where(book::id, Query.eq(id)) - .cql(); + String cql = session.select(Query.get(book::notes, new SectionImpl("first", 1))).where(book::id, Query.eq(id)) + .cql(); - System.out.println("Still not supporting cql = " + cql); + System.out.println("Still not supporting cql = " + cql); - // UPDATE + // UPDATE - Map expected = new HashMap(); - expected.put(new SectionImpl("f", 1), "v1"); - expected.put(new SectionImpl("s", 1), "v2"); + Map expected = new HashMap(); + expected.put(new SectionImpl("f", 1), "v1"); + expected.put(new SectionImpl("s", 1), "v2"); - session.update().set(book::notes, expected).where(book::id, Query.eq(id)).sync(); + session.update().set(book::notes, expected).where(book::id, Query.eq(id)).sync(); - actual = session.select(book).where(book::id, Query.eq(id)).sync().findFirst().get(); - Assert.assertEquals(id, actual.id()); - assertEqualMaps(expected, actual.notes()); + actual = session.select(book).where(book::id, Query.eq(id)).sync().findFirst().get(); + Assert.assertEquals(id, actual.id()); + assertEqualMaps(expected, actual.notes()); - // INSERT + // INSERT - // put operation + // put operation - Section third = new SectionImpl("t", 3); + Section third = new SectionImpl("t", 3); - expected.put(third, "v3"); - session.update().put(book::notes, third, "v3").where(book::id, Query.eq(id)).sync(); + expected.put(third, "v3"); + session.update().put(book::notes, third, "v3").where(book::id, Query.eq(id)).sync(); - actualMap = - session.select(book::notes).where(book::id, Query.eq(id)).sync().findFirst().get()._1; - assertEqualMaps(expected, actualMap); + actualMap = session.select(book::notes).where(book::id, Query.eq(id)).sync().findFirst().get()._1; + assertEqualMaps(expected, actualMap); - // putAll operation - expected.putAll(notes); - session.update().putAll(book::notes, notes).where(book::id, Query.eq(id)).sync(); + // putAll operation + expected.putAll(notes); + session.update().putAll(book::notes, notes).where(book::id, Query.eq(id)).sync(); - actualMap = - session.select(book::notes).where(book::id, Query.eq(id)).sync().findFirst().get()._1; - assertEqualMaps(expected, actualMap); + actualMap = session.select(book::notes).where(book::id, Query.eq(id)).sync().findFirst().get()._1; + assertEqualMaps(expected, actualMap); - // put existing + // put existing - expected.put(third, "v33"); - session.update().put(book::notes, third, "v33").where(book::id, Query.eq(id)).sync(); + expected.put(third, "v33"); + session.update().put(book::notes, third, "v33").where(book::id, Query.eq(id)).sync(); - actualMap = - session.select(book::notes).where(book::id, Query.eq(id)).sync().findFirst().get()._1; - assertEqualMaps(expected, actualMap); + actualMap = session.select(book::notes).where(book::id, Query.eq(id)).sync().findFirst().get()._1; + assertEqualMaps(expected, actualMap); - // DELETE + // DELETE - // remove single key + // remove single key - expected.remove(third); - session.update().put(book::notes, third, null).where(book::id, Query.eq(id)).sync(); + expected.remove(third); + session.update().put(book::notes, third, null).where(book::id, Query.eq(id)).sync(); - actualMap = - session.select(book::notes).where(book::id, Query.eq(id)).sync().findFirst().get()._1; - assertEqualMaps(expected, actualMap); + actualMap = session.select(book::notes).where(book::id, Query.eq(id)).sync().findFirst().get()._1; + assertEqualMaps(expected, actualMap); - // remove full map + // remove full map - session.update().set(book::notes, null).where(book::id, Query.eq(id)).sync(); + session.update().set(book::notes, null).where(book::id, Query.eq(id)).sync(); - actualMap = - session.select(book::notes).where(book::id, Query.eq(id)).sync().findFirst().get()._1; - Assert.assertNull(actualMap); + actualMap = session.select(book::notes).where(book::id, Query.eq(id)).sync().findFirst().get()._1; + Assert.assertNull(actualMap); - // remove object + // remove object - session.delete().where(book::id, Query.eq(id)).sync(); - Long cnt = session.count().where(book::id, Query.eq(id)).sync(); - Assert.assertEquals(Long.valueOf(0), cnt); - } + session.delete().where(book::id, Query.eq(id)).sync(); + Long cnt = session.count().where(book::id, Query.eq(id)).sync(); + Assert.assertEquals(Long.valueOf(0), cnt); + } - private void assertEqualMaps(Map expected, Map actual) { + private void assertEqualMaps(Map expected, Map actual) { - Assert.assertEquals(expected.size(), actual.size()); + Assert.assertEquals(expected.size(), actual.size()); - for (Section e : expected.keySet()) { - Section a = - actual.keySet().stream().filter(p -> p.title().equals(e.title())).findFirst().get(); - Assert.assertEquals(e.title(), a.title()); - Assert.assertEquals(e.page(), a.page()); - Assert.assertEquals(expected.get(e), actual.get(a)); - } - } + for (Section e : expected.keySet()) { + Section a = actual.keySet().stream().filter(p -> p.title().equals(e.title())).findFirst().get(); + Assert.assertEquals(e.title(), a.title()); + Assert.assertEquals(e.page(), a.page()); + Assert.assertEquals(expected.get(e), actual.get(a)); + } + } } diff --git a/src/test/java/net/helenus/test/integration/core/tuplecollection/TupleListTest.java b/src/test/java/net/helenus/test/integration/core/tuplecollection/TupleListTest.java index c09685d..97a92c9 100644 --- a/src/test/java/net/helenus/test/integration/core/tuplecollection/TupleListTest.java +++ b/src/test/java/net/helenus/test/integration/core/tuplecollection/TupleListTest.java @@ -18,157 +18,145 @@ package net.helenus.test.integration.core.tuplecollection; import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeoutException; -import net.helenus.core.Query; + import org.junit.Assert; import org.junit.Test; +import net.helenus.core.Query; + public class TupleListTest extends TupleCollectionTest { - @Test - public void testListCRUID() throws TimeoutException { + @Test + public void testListCRUID() throws TimeoutException { - int id = 777; + int id = 777; - List authors = new ArrayList(); - authors.add(new AuthorImpl("Alex", "San Jose")); - authors.add(new AuthorImpl("Bob", "San Francisco")); + List authors = new ArrayList(); + authors.add(new AuthorImpl("Alex", "San Jose")); + authors.add(new AuthorImpl("Bob", "San Francisco")); - // CREATE + // CREATE - session.insert().value(book::id, id).value(book::authors, authors).sync(); + session.insert().value(book::id, id).value(book::authors, authors).sync(); - // READ + // READ - // read full object + // read full object - Book actual = session.select(Book.class).where(book::id, Query.eq(id)).sync().findFirst().get(); - Assert.assertEquals(id, actual.id()); - assertEqualLists(authors, actual.authors()); - Assert.assertNull(actual.reviewers()); - Assert.assertNull(actual.contents()); + Book actual = session.select(Book.class).where(book::id, Query.eq(id)).sync().findFirst().get(); + Assert.assertEquals(id, actual.id()); + assertEqualLists(authors, actual.authors()); + Assert.assertNull(actual.reviewers()); + Assert.assertNull(actual.contents()); - // read full list + // read full list - List actualList = - session.select(book::authors).where(book::id, Query.eq(id)).sync().findFirst().get()._1; - assertEqualLists(authors, actualList); + List actualList = session.select(book::authors).where(book::id, Query.eq(id)).sync().findFirst() + .get()._1; + assertEqualLists(authors, actualList); - // read single value by index + // read single value by index - String cql = session.select(Query.getIdx(book::authors, 1)).where(book::id, Query.eq(id)).cql(); + String cql = session.select(Query.getIdx(book::authors, 1)).where(book::id, Query.eq(id)).cql(); - System.out.println("Still not supporting cql = " + cql); + System.out.println("Still not supporting cql = " + cql); - // UPDATE + // UPDATE - List expected = new ArrayList(); - expected.add(new AuthorImpl("Unknown", "City 17")); + List expected = new ArrayList(); + expected.add(new AuthorImpl("Unknown", "City 17")); - session.update().set(book::authors, expected).where(book::id, Query.eq(id)).sync(); + session.update().set(book::authors, expected).where(book::id, Query.eq(id)).sync(); - actual = session.select(Book.class).where(book::id, Query.eq(id)).sync().findFirst().get(); - Assert.assertEquals(id, actual.id()); - assertEqualLists(expected, actual.authors()); + actual = session.select(Book.class).where(book::id, Query.eq(id)).sync().findFirst().get(); + Assert.assertEquals(id, actual.id()); + assertEqualLists(expected, actual.authors()); - // INSERT + // INSERT - // prepend operation + // prepend operation - expected.add(0, new AuthorImpl("Prepend", "PrependCity")); - session - .update() - .prepend(book::authors, new AuthorImpl("Prepend", "PrependCity")) - .where(book::id, Query.eq(id)) - .sync(); + expected.add(0, new AuthorImpl("Prepend", "PrependCity")); + session.update().prepend(book::authors, new AuthorImpl("Prepend", "PrependCity")).where(book::id, Query.eq(id)) + .sync(); - actualList = - session.select(book::authors).where(book::id, Query.eq(id)).sync().findFirst().get()._1; - assertEqualLists(expected, actualList); + actualList = session.select(book::authors).where(book::id, Query.eq(id)).sync().findFirst().get()._1; + assertEqualLists(expected, actualList); - // append operation + // append operation - expected.add(new AuthorImpl("Append", "AppendCity")); - session - .update() - .append(book::authors, new AuthorImpl("Append", "AppendCity")) - .where(book::id, Query.eq(id)) - .sync(); + expected.add(new AuthorImpl("Append", "AppendCity")); + session.update().append(book::authors, new AuthorImpl("Append", "AppendCity")).where(book::id, Query.eq(id)) + .sync(); - actualList = - session.select(book::authors).where(book::id, Query.eq(id)).sync().findFirst().get()._1; - assertEqualLists(expected, actualList); + actualList = session.select(book::authors).where(book::id, Query.eq(id)).sync().findFirst().get()._1; + assertEqualLists(expected, actualList); - // prependAll operation - expected.addAll(0, authors); - session.update().prependAll(book::authors, authors).where(book::id, Query.eq(id)).sync(); + // prependAll operation + expected.addAll(0, authors); + session.update().prependAll(book::authors, authors).where(book::id, Query.eq(id)).sync(); - actualList = - session.select(book::authors).where(book::id, Query.eq(id)).sync().findFirst().get()._1; - assertEqualLists(expected, actualList); + actualList = session.select(book::authors).where(book::id, Query.eq(id)).sync().findFirst().get()._1; + assertEqualLists(expected, actualList); - // appendAll operation - expected.addAll(authors); - session.update().appendAll(book::authors, authors).where(book::id, Query.eq(id)).sync(); + // appendAll operation + expected.addAll(authors); + session.update().appendAll(book::authors, authors).where(book::id, Query.eq(id)).sync(); - actualList = - session.select(book::authors).where(book::id, Query.eq(id)).sync().findFirst().get()._1; - assertEqualLists(expected, actualList); + actualList = session.select(book::authors).where(book::id, Query.eq(id)).sync().findFirst().get()._1; + assertEqualLists(expected, actualList); - // set by Index + // set by Index - Author inserted = new AuthorImpl("Insert", "InsertCity"); - expected.set(5, inserted); - session.update().setIdx(book::authors, 5, inserted).where(book::id, Query.eq(id)).sync(); + Author inserted = new AuthorImpl("Insert", "InsertCity"); + expected.set(5, inserted); + session.update().setIdx(book::authors, 5, inserted).where(book::id, Query.eq(id)).sync(); - actualList = - session.select(book::authors).where(book::id, Query.eq(id)).sync().findFirst().get()._1; - assertEqualLists(expected, actualList); + actualList = session.select(book::authors).where(book::id, Query.eq(id)).sync().findFirst().get()._1; + assertEqualLists(expected, actualList); - // DELETE + // DELETE - // remove single value + // remove single value - expected.remove(inserted); - session.update().discard(book::authors, inserted).where(book::id, Query.eq(id)).sync(); + expected.remove(inserted); + session.update().discard(book::authors, inserted).where(book::id, Query.eq(id)).sync(); - actualList = - session.select(book::authors).where(book::id, Query.eq(id)).sync().findFirst().get()._1; - assertEqualLists(expected, actualList); + actualList = session.select(book::authors).where(book::id, Query.eq(id)).sync().findFirst().get()._1; + assertEqualLists(expected, actualList); - // remove values + // remove values - expected.removeAll(authors); - session.update().discardAll(book::authors, authors).where(book::id, Query.eq(id)).sync(); + expected.removeAll(authors); + session.update().discardAll(book::authors, authors).where(book::id, Query.eq(id)).sync(); - actualList = - session.select(book::authors).where(book::id, Query.eq(id)).sync().findFirst().get()._1; - assertEqualLists(expected, actualList); + actualList = session.select(book::authors).where(book::id, Query.eq(id)).sync().findFirst().get()._1; + assertEqualLists(expected, actualList); - // remove full list + // remove full list - session.update().set(book::authors, null).where(book::id, Query.eq(id)).sync(); + session.update().set(book::authors, null).where(book::id, Query.eq(id)).sync(); - actualList = - session.select(book::authors).where(book::id, Query.eq(id)).sync().findFirst().get()._1; - Assert.assertNull(actualList); + actualList = session.select(book::authors).where(book::id, Query.eq(id)).sync().findFirst().get()._1; + Assert.assertNull(actualList); - // remove object + // remove object - session.delete().where(book::id, Query.eq(id)).sync(); - Long cnt = session.count().where(book::id, Query.eq(id)).sync(); - Assert.assertEquals(Long.valueOf(0), cnt); - } + session.delete().where(book::id, Query.eq(id)).sync(); + Long cnt = session.count().where(book::id, Query.eq(id)).sync(); + Assert.assertEquals(Long.valueOf(0), cnt); + } - private void assertEqualLists(List expected, List actual) { - Assert.assertEquals(expected.size(), actual.size()); + private void assertEqualLists(List expected, List actual) { + Assert.assertEquals(expected.size(), actual.size()); - int size = expected.size(); + int size = expected.size(); - for (int i = 0; i != size; ++i) { - Author e = expected.get(i); - Author a = actual.get(i); - Assert.assertEquals(e.name(), a.name()); - Assert.assertEquals(e.city(), a.city()); - } - } + for (int i = 0; i != size; ++i) { + Author e = expected.get(i); + Author a = actual.get(i); + Assert.assertEquals(e.name(), a.name()); + Assert.assertEquals(e.city(), a.city()); + } + } } diff --git a/src/test/java/net/helenus/test/integration/core/tuplecollection/TupleMapTest.java b/src/test/java/net/helenus/test/integration/core/tuplecollection/TupleMapTest.java index ef95e1f..4e1b381 100644 --- a/src/test/java/net/helenus/test/integration/core/tuplecollection/TupleMapTest.java +++ b/src/test/java/net/helenus/test/integration/core/tuplecollection/TupleMapTest.java @@ -18,140 +18,130 @@ package net.helenus.test.integration.core.tuplecollection; import java.util.HashMap; import java.util.Map; import java.util.concurrent.TimeoutException; -import net.helenus.core.Query; + import org.junit.Assert; import org.junit.Test; +import net.helenus.core.Query; + public class TupleMapTest extends TupleCollectionTest { - @Test - public void testMapCRUID() throws TimeoutException { + @Test + public void testMapCRUID() throws TimeoutException { - int id = 333; + int id = 333; - Map writers = new HashMap(); - writers.put( - new SectionImpl("first", 1), new TupleCollectionTest.AuthorImpl("Alex", "San Jose")); - writers.put( - new SectionImpl("second", 2), new TupleCollectionTest.AuthorImpl("Bob", "San Francisco")); + Map writers = new HashMap(); + writers.put(new SectionImpl("first", 1), new TupleCollectionTest.AuthorImpl("Alex", "San Jose")); + writers.put(new SectionImpl("second", 2), new TupleCollectionTest.AuthorImpl("Bob", "San Francisco")); - // CREATE + // CREATE - session.insert().value(book::id, id).value(book::writers, writers).sync(); + session.insert().value(book::id, id).value(book::writers, writers).sync(); - // READ + // READ - // read full object + // read full object - Book actual = - session.select(book).where(book::id, Query.eq(id)).single().sync().orElse(null); - Assert.assertEquals(id, actual.id()); - assertEqualMaps(writers, actual.writers()); - Assert.assertNull(actual.reviewers()); - Assert.assertNull(actual.notes()); - Assert.assertNull(actual.contents()); + Book actual = session.select(book).where(book::id, Query.eq(id)).single().sync().orElse(null); + Assert.assertEquals(id, actual.id()); + assertEqualMaps(writers, actual.writers()); + Assert.assertNull(actual.reviewers()); + Assert.assertNull(actual.notes()); + Assert.assertNull(actual.contents()); - // read full map + // read full map - Map actualMap = - session.select(book::writers).where(book::id, Query.eq(id)).sync().findFirst().get()._1; - assertEqualMaps(writers, actualMap); + Map actualMap = session.select(book::writers).where(book::id, Query.eq(id)).sync().findFirst() + .get()._1; + assertEqualMaps(writers, actualMap); - // read single key-value in map + // read single key-value in map - String cql = - session - .select(Query.get(book::writers, new SectionImpl("first", 1))) - .where(book::id, Query.eq(id)) - .cql(); + String cql = session.select(Query.get(book::writers, new SectionImpl("first", 1))).where(book::id, Query.eq(id)) + .cql(); - System.out.println("Still not supporting cql = " + cql); + System.out.println("Still not supporting cql = " + cql); - // UPDATE + // UPDATE - Map expected = new HashMap(); - expected.put(new SectionImpl("f", 1), new TupleCollectionTest.AuthorImpl("A", "SJ")); - expected.put(new SectionImpl("s", 1), new TupleCollectionTest.AuthorImpl("B", "SF")); + Map expected = new HashMap(); + expected.put(new SectionImpl("f", 1), new TupleCollectionTest.AuthorImpl("A", "SJ")); + expected.put(new SectionImpl("s", 1), new TupleCollectionTest.AuthorImpl("B", "SF")); - session.update().set(book::writers, expected).where(book::id, Query.eq(id)).sync(); + session.update().set(book::writers, expected).where(book::id, Query.eq(id)).sync(); - actual = session.select(book).where(book::id, Query.eq(id)).single().sync().orElse(null); + actual = session.select(book).where(book::id, Query.eq(id)).single().sync().orElse(null); - Assert.assertEquals(id, actual.id()); - assertEqualMaps(expected, actual.writers()); + Assert.assertEquals(id, actual.id()); + assertEqualMaps(expected, actual.writers()); - // INSERT + // INSERT - // put operation + // put operation - Section third = new SectionImpl("t", 3); - Author unk = new TupleCollectionTest.AuthorImpl("Unk", "City 17"); + Section third = new SectionImpl("t", 3); + Author unk = new TupleCollectionTest.AuthorImpl("Unk", "City 17"); - expected.put(third, unk); - session.update().put(book::writers, third, unk).where(book::id, Query.eq(id)).sync(); + expected.put(third, unk); + session.update().put(book::writers, third, unk).where(book::id, Query.eq(id)).sync(); - actualMap = - session.select(book::writers).where(book::id, Query.eq(id)).sync().findFirst().get()._1; - assertEqualMaps(expected, actualMap); + actualMap = session.select(book::writers).where(book::id, Query.eq(id)).sync().findFirst().get()._1; + assertEqualMaps(expected, actualMap); - // putAll operation - expected.putAll(writers); - session.update().putAll(book::writers, writers).where(book::id, Query.eq(id)).sync(); + // putAll operation + expected.putAll(writers); + session.update().putAll(book::writers, writers).where(book::id, Query.eq(id)).sync(); - actualMap = - session.select(book::writers).where(book::id, Query.eq(id)).sync().findFirst().get()._1; - assertEqualMaps(expected, actualMap); + actualMap = session.select(book::writers).where(book::id, Query.eq(id)).sync().findFirst().get()._1; + assertEqualMaps(expected, actualMap); - // put existing + // put existing - expected.put(third, unk); - session.update().put(book::writers, third, unk).where(book::id, Query.eq(id)).sync(); + expected.put(third, unk); + session.update().put(book::writers, third, unk).where(book::id, Query.eq(id)).sync(); - actualMap = - session.select(book::writers).where(book::id, Query.eq(id)).sync().findFirst().get()._1; - assertEqualMaps(expected, actualMap); + actualMap = session.select(book::writers).where(book::id, Query.eq(id)).sync().findFirst().get()._1; + assertEqualMaps(expected, actualMap); - // DELETE + // DELETE - // remove single key + // remove single key - expected.remove(third); - session.update().put(book::writers, third, null).where(book::id, Query.eq(id)).sync(); + expected.remove(third); + session.update().put(book::writers, third, null).where(book::id, Query.eq(id)).sync(); - actualMap = - session.select(book::writers).where(book::id, Query.eq(id)).sync().findFirst().get()._1; - assertEqualMaps(expected, actualMap); + actualMap = session.select(book::writers).where(book::id, Query.eq(id)).sync().findFirst().get()._1; + assertEqualMaps(expected, actualMap); - // remove full map + // remove full map - session.update().set(book::writers, null).where(book::id, Query.eq(id)).sync(); + session.update().set(book::writers, null).where(book::id, Query.eq(id)).sync(); - actualMap = - session.select(book::writers).where(book::id, Query.eq(id)).sync().findFirst().get()._1; - Assert.assertNull(actualMap); + actualMap = session.select(book::writers).where(book::id, Query.eq(id)).sync().findFirst().get()._1; + Assert.assertNull(actualMap); - // remove object + // remove object - session.delete().where(book::id, Query.eq(id)).sync(); - Long cnt = session.count().where(book::id, Query.eq(id)).sync(); - Assert.assertEquals(Long.valueOf(0), cnt); - } + session.delete().where(book::id, Query.eq(id)).sync(); + Long cnt = session.count().where(book::id, Query.eq(id)).sync(); + Assert.assertEquals(Long.valueOf(0), cnt); + } - private void assertEqualMaps(Map expected, Map actual) { + private void assertEqualMaps(Map expected, Map actual) { - Assert.assertEquals(expected.size(), actual.size()); + Assert.assertEquals(expected.size(), actual.size()); - for (Section e : expected.keySet()) { - Section a = - actual.keySet().stream().filter(p -> p.title().equals(e.title())).findFirst().get(); - Assert.assertEquals(e.title(), a.title()); - Assert.assertEquals(e.page(), a.page()); + for (Section e : expected.keySet()) { + Section a = actual.keySet().stream().filter(p -> p.title().equals(e.title())).findFirst().get(); + Assert.assertEquals(e.title(), a.title()); + Assert.assertEquals(e.page(), a.page()); - Author ea = expected.get(e); - Author aa = actual.get(a); + Author ea = expected.get(e); + Author aa = actual.get(a); - Assert.assertEquals(ea.name(), aa.name()); - Assert.assertEquals(ea.city(), aa.city()); - } - } + Assert.assertEquals(ea.name(), aa.name()); + Assert.assertEquals(ea.city(), aa.city()); + } + } } diff --git a/src/test/java/net/helenus/test/integration/core/tuplecollection/TupleSetTest.java b/src/test/java/net/helenus/test/integration/core/tuplecollection/TupleSetTest.java index 24c1da5..257956a 100644 --- a/src/test/java/net/helenus/test/integration/core/tuplecollection/TupleSetTest.java +++ b/src/test/java/net/helenus/test/integration/core/tuplecollection/TupleSetTest.java @@ -18,107 +18,100 @@ package net.helenus.test.integration.core.tuplecollection; import java.util.HashSet; import java.util.Set; import java.util.concurrent.TimeoutException; -import net.helenus.core.Query; + import org.junit.Assert; import org.junit.Test; +import net.helenus.core.Query; + public class TupleSetTest extends TupleCollectionTest { - @Test - public void testSetCRUID() throws TimeoutException { + @Test + public void testSetCRUID() throws TimeoutException { - int id = 555; + int id = 555; - // CREATE + // CREATE - Set reviewers = new HashSet(); - reviewers.add(new AuthorImpl("Alex", "San Jose")); - reviewers.add(new AuthorImpl("Bob", "San Francisco")); + Set reviewers = new HashSet(); + 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(); + session.insert().value(book::id, id).value(book::reviewers, reviewers).sync(); - // READ + // READ - Book actual = session.select(Book.class).where(book::id, Query.eq(id)).sync().findFirst().get(); - Assert.assertEquals(id, actual.id()); - assertEqualSets(reviewers, actual.reviewers()); + Book actual = session.select(Book.class).where(book::id, Query.eq(id)).sync().findFirst().get(); + Assert.assertEquals(id, actual.id()); + assertEqualSets(reviewers, actual.reviewers()); - // UPDATE + // UPDATE - Set expected = new HashSet(); - expected.add(new AuthorImpl("Craig", "Los Altos")); + Set expected = new HashSet(); + expected.add(new AuthorImpl("Craig", "Los Altos")); - session.update().set(book::reviewers, expected).where(book::id, Query.eq(id)).sync(); + session.update().set(book::reviewers, expected).where(book::id, Query.eq(id)).sync(); - Set actualSet = - session.select(book::reviewers).where(book::id, Query.eq(id)).sync().findFirst().get()._1; - assertEqualSets(expected, actualSet); + Set actualSet = session.select(book::reviewers).where(book::id, Query.eq(id)).sync().findFirst() + .get()._1; + assertEqualSets(expected, actualSet); - // add operation + // add operation - expected.add(new AuthorImpl("Add", "AddCity")); - session - .update() - .add(book::reviewers, new AuthorImpl("Add", "AddCity")) - .where(book::id, Query.eq(id)) - .sync(); + expected.add(new AuthorImpl("Add", "AddCity")); + session.update().add(book::reviewers, new AuthorImpl("Add", "AddCity")).where(book::id, Query.eq(id)).sync(); - actualSet = - session.select(book::reviewers).where(book::id, Query.eq(id)).sync().findFirst().get()._1; - assertEqualSets(expected, actualSet); + actualSet = session.select(book::reviewers).where(book::id, Query.eq(id)).sync().findFirst().get()._1; + assertEqualSets(expected, actualSet); - // addAll operation - expected.addAll(reviewers); - session.update().addAll(book::reviewers, reviewers).where(book::id, Query.eq(id)).sync(); + // addAll operation + expected.addAll(reviewers); + session.update().addAll(book::reviewers, reviewers).where(book::id, Query.eq(id)).sync(); - actualSet = - session.select(book::reviewers).where(book::id, Query.eq(id)).sync().findFirst().get()._1; - assertEqualSets(expected, actualSet); + actualSet = session.select(book::reviewers).where(book::id, Query.eq(id)).sync().findFirst().get()._1; + assertEqualSets(expected, actualSet); - // DELETE + // DELETE - // remove single value + // remove single value - Author a = expected.stream().filter(p -> p.name().equals("Add")).findFirst().get(); - expected.remove(a); + Author a = expected.stream().filter(p -> p.name().equals("Add")).findFirst().get(); + expected.remove(a); - session.update().remove(book::reviewers, a).where(book::id, Query.eq(id)).sync(); + session.update().remove(book::reviewers, a).where(book::id, Query.eq(id)).sync(); - actualSet = - session.select(book::reviewers).where(book::id, Query.eq(id)).sync().findFirst().get()._1; - assertEqualSets(expected, actualSet); + actualSet = session.select(book::reviewers).where(book::id, Query.eq(id)).sync().findFirst().get()._1; + assertEqualSets(expected, actualSet); - // remove values + // remove values - expected.remove(expected.stream().filter(p -> p.name().equals("Alex")).findFirst().get()); - expected.remove(expected.stream().filter(p -> p.name().equals("Bob")).findFirst().get()); - session.update().removeAll(book::reviewers, reviewers).where(book::id, Query.eq(id)).sync(); + expected.remove(expected.stream().filter(p -> p.name().equals("Alex")).findFirst().get()); + expected.remove(expected.stream().filter(p -> p.name().equals("Bob")).findFirst().get()); + session.update().removeAll(book::reviewers, reviewers).where(book::id, Query.eq(id)).sync(); - actualSet = - session.select(book::reviewers).where(book::id, Query.eq(id)).sync().findFirst().get()._1; - assertEqualSets(expected, actualSet); + actualSet = session.select(book::reviewers).where(book::id, Query.eq(id)).sync().findFirst().get()._1; + assertEqualSets(expected, actualSet); - // remove full list + // remove full list - session.update().set(book::reviewers, null).where(book::id, Query.eq(id)).sync(); + session.update().set(book::reviewers, null).where(book::id, Query.eq(id)).sync(); - actualSet = - session.select(book::reviewers).where(book::id, Query.eq(id)).sync().findFirst().get()._1; - Assert.assertNull(actualSet); + actualSet = session.select(book::reviewers).where(book::id, Query.eq(id)).sync().findFirst().get()._1; + Assert.assertNull(actualSet); - // remove object + // remove object - session.delete().where(book::id, Query.eq(id)).sync(); - Long cnt = session.count().where(book::id, Query.eq(id)).sync(); - Assert.assertEquals(Long.valueOf(0), cnt); - } + session.delete().where(book::id, Query.eq(id)).sync(); + Long cnt = session.count().where(book::id, Query.eq(id)).sync(); + Assert.assertEquals(Long.valueOf(0), cnt); + } - private void assertEqualSets(Set expected, Set actual) { - Assert.assertEquals(expected.size(), actual.size()); + private void assertEqualSets(Set expected, Set actual) { + Assert.assertEquals(expected.size(), actual.size()); - for (Author e : expected) { - Author a = actual.stream().filter(p -> p.name().equals(e.name())).findFirst().get(); - Assert.assertEquals(e.city(), a.city()); - } - } + for (Author e : expected) { + Author a = actual.stream().filter(p -> p.name().equals(e.name())).findFirst().get(); + Assert.assertEquals(e.city(), a.city()); + } + } } diff --git a/src/test/java/net/helenus/test/integration/core/tuplecollection/TupleValueMapTest.java b/src/test/java/net/helenus/test/integration/core/tuplecollection/TupleValueMapTest.java index c0de2a3..f1f776e 100644 --- a/src/test/java/net/helenus/test/integration/core/tuplecollection/TupleValueMapTest.java +++ b/src/test/java/net/helenus/test/integration/core/tuplecollection/TupleValueMapTest.java @@ -18,126 +18,123 @@ package net.helenus.test.integration.core.tuplecollection; import java.util.HashMap; import java.util.Map; import java.util.concurrent.TimeoutException; -import net.helenus.core.Query; + import org.junit.Assert; import org.junit.Test; +import net.helenus.core.Query; + public class TupleValueMapTest extends TupleCollectionTest { - @Test - public void testValueMapCRUID() throws TimeoutException { + @Test + public void testValueMapCRUID() throws TimeoutException { - int id = 999; + int id = 999; - Map contents = new HashMap(); - contents.put(1, new SectionImpl("first", 1)); - contents.put(2, new SectionImpl("second", 2)); + Map contents = new HashMap(); + contents.put(1, new SectionImpl("first", 1)); + contents.put(2, new SectionImpl("second", 2)); - // CREATE + // CREATE - session.insert().value(book::id, id).value(book::contents, contents).sync(); + session.insert().value(book::id, id).value(book::contents, contents).sync(); - // READ + // READ - // read full object + // read full object - Book actual = session.select(Book.class).where(book::id, Query.eq(id)).sync().findFirst().get(); - Assert.assertEquals(id, actual.id()); - assertEqualMaps(contents, actual.contents()); - Assert.assertNull(actual.reviewers()); - Assert.assertNull(actual.writers()); - Assert.assertNull(actual.notes()); + Book actual = session.select(Book.class).where(book::id, Query.eq(id)).sync().findFirst().get(); + Assert.assertEquals(id, actual.id()); + assertEqualMaps(contents, actual.contents()); + Assert.assertNull(actual.reviewers()); + Assert.assertNull(actual.writers()); + Assert.assertNull(actual.notes()); - // read full map + // read full map - Map actualMap = - session.select(book::contents).where(book::id, Query.eq(id)).sync().findFirst().get()._1; - assertEqualMaps(contents, actualMap); + Map actualMap = session.select(book::contents).where(book::id, Query.eq(id)).sync() + .findFirst().get()._1; + assertEqualMaps(contents, actualMap); - // read single key-value in map + // read single key-value in map - String cql = session.select(Query.get(book::contents, 1)).where(book::id, Query.eq(id)).cql(); + String cql = session.select(Query.get(book::contents, 1)).where(book::id, Query.eq(id)).cql(); - System.out.println("Still not supporting cql = " + cql); + System.out.println("Still not supporting cql = " + cql); - // UPDATE + // UPDATE - Map expected = new HashMap(); - expected.put(4, new SectionImpl("4", 4)); - expected.put(5, new SectionImpl("5", 5)); + Map expected = new HashMap(); + expected.put(4, new SectionImpl("4", 4)); + expected.put(5, new SectionImpl("5", 5)); - session.update().set(book::contents, expected).where(book::id, Query.eq(id)).sync(); + session.update().set(book::contents, expected).where(book::id, Query.eq(id)).sync(); - actual = session.select(Book.class).where(book::id, Query.eq(id)).sync().findFirst().get(); - Assert.assertEquals(id, actual.id()); - assertEqualMaps(expected, actual.contents()); + actual = session.select(Book.class).where(book::id, Query.eq(id)).sync().findFirst().get(); + Assert.assertEquals(id, actual.id()); + assertEqualMaps(expected, actual.contents()); - // INSERT + // INSERT - // put operation + // put operation - Section third = new SectionImpl("t", 3); + Section third = new SectionImpl("t", 3); - expected.put(3, third); - session.update().put(book::contents, 3, third).where(book::id, Query.eq(id)).sync(); + expected.put(3, third); + session.update().put(book::contents, 3, third).where(book::id, Query.eq(id)).sync(); - actualMap = - session.select(book::contents).where(book::id, Query.eq(id)).sync().findFirst().get()._1; - assertEqualMaps(expected, actualMap); + actualMap = session.select(book::contents).where(book::id, Query.eq(id)).sync().findFirst().get()._1; + assertEqualMaps(expected, actualMap); - // putAll operation - expected.putAll(contents); - session.update().putAll(book::contents, contents).where(book::id, Query.eq(id)).sync(); + // putAll operation + expected.putAll(contents); + session.update().putAll(book::contents, contents).where(book::id, Query.eq(id)).sync(); - actualMap = - session.select(book::contents).where(book::id, Query.eq(id)).sync().findFirst().get()._1; - assertEqualMaps(expected, actualMap); + actualMap = session.select(book::contents).where(book::id, Query.eq(id)).sync().findFirst().get()._1; + assertEqualMaps(expected, actualMap); - // put existing + // put existing - third = new SectionImpl("t-replace", 3); - expected.put(3, third); - session.update().put(book::contents, 3, third).where(book::id, Query.eq(id)).sync(); + third = new SectionImpl("t-replace", 3); + expected.put(3, third); + session.update().put(book::contents, 3, third).where(book::id, Query.eq(id)).sync(); - actualMap = - session.select(book::contents).where(book::id, Query.eq(id)).sync().findFirst().get()._1; - assertEqualMaps(expected, actualMap); + actualMap = session.select(book::contents).where(book::id, Query.eq(id)).sync().findFirst().get()._1; + assertEqualMaps(expected, actualMap); - // DELETE + // DELETE - // remove single key + // remove single key - expected.remove(3); - session.update().put(book::contents, 3, null).where(book::id, Query.eq(id)).sync(); + expected.remove(3); + session.update().put(book::contents, 3, null).where(book::id, Query.eq(id)).sync(); - actualMap = - session.select(book::contents).where(book::id, Query.eq(id)).sync().findFirst().get()._1; - assertEqualMaps(expected, actualMap); + actualMap = session.select(book::contents).where(book::id, Query.eq(id)).sync().findFirst().get()._1; + assertEqualMaps(expected, actualMap); - // remove full map + // remove full map - session.update().set(book::contents, null).where(book::id, Query.eq(id)).sync(); + session.update().set(book::contents, null).where(book::id, Query.eq(id)).sync(); - actualMap = - session.select(book::contents).where(book::id, Query.eq(id)).sync().findFirst().get()._1; - Assert.assertNull(actualMap); + actualMap = session.select(book::contents).where(book::id, Query.eq(id)).sync().findFirst().get()._1; + Assert.assertNull(actualMap); - // remove object + // remove object - session.delete().where(book::id, Query.eq(id)).sync(); - Long cnt = session.count().where(book::id, Query.eq(id)).sync(); - Assert.assertEquals(Long.valueOf(0), cnt); - } + session.delete().where(book::id, Query.eq(id)).sync(); + Long cnt = session.count().where(book::id, Query.eq(id)).sync(); + Assert.assertEquals(Long.valueOf(0), cnt); + } - private void assertEqualMaps(Map expected, Map actual) { + private void assertEqualMaps(Map expected, Map actual) { - Assert.assertEquals(expected.size(), actual.size()); + Assert.assertEquals(expected.size(), actual.size()); - for (Integer i : expected.keySet()) { - Section e = expected.get(i); - Section a = actual.get(i); - Assert.assertEquals(e.title(), a.title()); - Assert.assertEquals(e.page(), a.page()); - } - } + for (Integer i : expected.keySet()) { + Section e = expected.get(i); + Section a = actual.get(i); + Assert.assertEquals(e.title(), a.title()); + Assert.assertEquals(e.page(), a.page()); + } + } } diff --git a/src/test/java/net/helenus/test/integration/core/udtcollection/Author.java b/src/test/java/net/helenus/test/integration/core/udtcollection/Author.java index b1266af..7571ba5 100644 --- a/src/test/java/net/helenus/test/integration/core/udtcollection/Author.java +++ b/src/test/java/net/helenus/test/integration/core/udtcollection/Author.java @@ -20,7 +20,7 @@ import net.helenus.mapping.annotation.UDT; @UDT public interface Author { - String name(); + String name(); - String city(); + String city(); } diff --git a/src/test/java/net/helenus/test/integration/core/udtcollection/Book.java b/src/test/java/net/helenus/test/integration/core/udtcollection/Book.java index 4ad9c7f..0e30234 100644 --- a/src/test/java/net/helenus/test/integration/core/udtcollection/Book.java +++ b/src/test/java/net/helenus/test/integration/core/udtcollection/Book.java @@ -18,22 +18,23 @@ package net.helenus.test.integration.core.udtcollection; import java.util.List; import java.util.Map; import java.util.Set; + import net.helenus.mapping.annotation.PartitionKey; import net.helenus.mapping.annotation.Table; @Table public interface Book { - @PartitionKey - int id(); + @PartitionKey + int id(); - List authors(); + List authors(); - Set reviewers(); + Set reviewers(); - Map contents(); + Map contents(); - Map notes(); + Map notes(); - Map writers(); + Map writers(); } diff --git a/src/test/java/net/helenus/test/integration/core/udtcollection/Section.java b/src/test/java/net/helenus/test/integration/core/udtcollection/Section.java index 0dba42b..394084d 100644 --- a/src/test/java/net/helenus/test/integration/core/udtcollection/Section.java +++ b/src/test/java/net/helenus/test/integration/core/udtcollection/Section.java @@ -20,7 +20,7 @@ import net.helenus.mapping.annotation.UDT; @UDT public interface Section { - String title(); + String title(); - int page(); + int page(); } diff --git a/src/test/java/net/helenus/test/integration/core/udtcollection/UDTCollectionTest.java b/src/test/java/net/helenus/test/integration/core/udtcollection/UDTCollectionTest.java index f50e34d..c199afd 100644 --- a/src/test/java/net/helenus/test/integration/core/udtcollection/UDTCollectionTest.java +++ b/src/test/java/net/helenus/test/integration/core/udtcollection/UDTCollectionTest.java @@ -15,125 +15,139 @@ */ package net.helenus.test.integration.core.udtcollection; -import net.helenus.core.Helenus; -import net.helenus.core.HelenusSession; -import net.helenus.test.integration.build.AbstractEmbeddedCassandraTest; import org.junit.BeforeClass; import org.junit.Test; +import net.helenus.core.Helenus; +import net.helenus.core.HelenusSession; +import net.helenus.test.integration.build.AbstractEmbeddedCassandraTest; + public abstract class UDTCollectionTest extends AbstractEmbeddedCassandraTest { - static Book book; + static Book book; - static HelenusSession session; + static HelenusSession session; - @BeforeClass - public static void beforeTest() { - Helenus.clearDslCache(); - session = Helenus.init(getSession()).showCql().add(Book.class).autoCreateDrop().get(); - book = Helenus.dsl(Book.class); - } + @BeforeClass + public static void beforeTest() { + Helenus.clearDslCache(); + session = Helenus.init(getSession()).showCql().add(Book.class).autoCreateDrop().get(); + book = Helenus.dsl(Book.class); + } - @Test - public void test() { - System.out.println(book); - } + @Test + public void test() { + System.out.println(book); + } - public static final class AuthorImpl implements Author { + public static final class AuthorImpl implements Author { - String name; - String city; + String name; + String city; - AuthorImpl(String name, String city) { - this.name = name; - this.city = city; - } + AuthorImpl(String name, String city) { + this.name = name; + this.city = city; + } - @Override - public String name() { - return name; - } + @Override + public String name() { + return name; + } - @Override - public String city() { - return city; - } + @Override + public String city() { + return city; + } - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((city == null) ? 0 : city.hashCode()); - result = prime * result + ((name == null) ? 0 : name.hashCode()); - return result; - } + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((city == null) ? 0 : city.hashCode()); + result = prime * result + ((name == null) ? 0 : name.hashCode()); + return result; + } - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (obj == null) return false; - if (getClass() != obj.getClass()) return false; - AuthorImpl other = (AuthorImpl) obj; - if (city == null) { - if (other.city != null) return false; - } else if (!city.equals(other.city)) return false; - if (name == null) { - if (other.name != null) return false; - } else if (!name.equals(other.name)) return false; - return true; - } + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + AuthorImpl other = (AuthorImpl) obj; + if (city == null) { + if (other.city != null) + return false; + } else if (!city.equals(other.city)) + return false; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + return true; + } - @Override - public String toString() { - return "AuthorImpl [name=" + name + ", city=" + city + "]"; - } - } + @Override + public String toString() { + return "AuthorImpl [name=" + name + ", city=" + city + "]"; + } + } - public static final class SectionImpl implements Section { + public static final class SectionImpl implements Section { - String title; - int page; + String title; + int page; - SectionImpl(String title, int page) { - this.title = title; - this.page = page; - } + SectionImpl(String title, int page) { + this.title = title; + this.page = page; + } - @Override - public String title() { - return title; - } + @Override + public String title() { + return title; + } - @Override - public int page() { - return page; - } + @Override + public int page() { + return page; + } - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + page; - result = prime * result + ((title == null) ? 0 : title.hashCode()); - return result; - } + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + page; + result = prime * result + ((title == null) ? 0 : title.hashCode()); + return result; + } - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (obj == null) return false; - if (getClass() != obj.getClass()) return false; - SectionImpl other = (SectionImpl) obj; - if (page != other.page) return false; - if (title == null) { - if (other.title != null) return false; - } else if (!title.equals(other.title)) return false; - return true; - } + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + SectionImpl other = (SectionImpl) obj; + if (page != other.page) + return false; + if (title == null) { + if (other.title != null) + return false; + } else if (!title.equals(other.title)) + return false; + return true; + } - @Override - public String toString() { - return "SectionImpl [title=" + title + ", page=" + page + "]"; - } - } + @Override + public String toString() { + return "SectionImpl [title=" + title + ", page=" + page + "]"; + } + } } diff --git a/src/test/java/net/helenus/test/integration/core/udtcollection/UDTKeyMapTest.java b/src/test/java/net/helenus/test/integration/core/udtcollection/UDTKeyMapTest.java index c6d55e3..44cd0b6 100644 --- a/src/test/java/net/helenus/test/integration/core/udtcollection/UDTKeyMapTest.java +++ b/src/test/java/net/helenus/test/integration/core/udtcollection/UDTKeyMapTest.java @@ -21,121 +21,120 @@ import static net.helenus.core.Query.get; import java.util.HashMap; import java.util.Map; import java.util.concurrent.TimeoutException; + import org.junit.Assert; import org.junit.Test; public class UDTKeyMapTest extends UDTCollectionTest { - @Test - public void testKeyMapCRUID() throws TimeoutException { + @Test + public void testKeyMapCRUID() throws TimeoutException { - int id = 888; + int id = 888; - Map notes = new HashMap(); - notes.put(new SectionImpl("first", 1), "value1"); - notes.put(new SectionImpl("second", 2), "value2"); + Map notes = new HashMap(); + notes.put(new SectionImpl("first", 1), "value1"); + notes.put(new SectionImpl("second", 2), "value2"); - // CREATE + // CREATE - session.insert().value(book::id, id).value(book::notes, notes).sync(); + session.insert().value(book::id, id).value(book::notes, notes).sync(); - // READ + // READ - // read full object + // read full object - Book actual = session.select(book).where(book::id, eq(id)).sync().findFirst().get(); - Assert.assertEquals(id, actual.id()); - assertEqualMaps(notes, actual.notes()); - Assert.assertNull(actual.reviewers()); - Assert.assertNull(actual.writers()); - Assert.assertNull(actual.contents()); + Book actual = session.select(book).where(book::id, eq(id)).sync().findFirst().get(); + Assert.assertEquals(id, actual.id()); + assertEqualMaps(notes, actual.notes()); + Assert.assertNull(actual.reviewers()); + Assert.assertNull(actual.writers()); + Assert.assertNull(actual.contents()); - // read full map + // read full map - Map actualMap = - session.select(book::notes).where(book::id, eq(id)).sync().findFirst().get()._1; - assertEqualMaps(notes, actualMap); + Map actualMap = session.select(book::notes).where(book::id, eq(id)).sync().findFirst() + .get()._1; + assertEqualMaps(notes, actualMap); - // read single key-value in map + // read single key-value in map - String cql = - session.select(get(book::notes, new SectionImpl("first", 1))).where(book::id, eq(id)).cql(); + String cql = session.select(get(book::notes, new SectionImpl("first", 1))).where(book::id, eq(id)).cql(); - System.out.println("Still not supporting cql = " + cql); + System.out.println("Still not supporting cql = " + cql); - // UPDATE + // UPDATE - Map expected = new HashMap(); - expected.put(new SectionImpl("f", 1), "v1"); - expected.put(new SectionImpl("s", 1), "v2"); + Map expected = new HashMap(); + expected.put(new SectionImpl("f", 1), "v1"); + expected.put(new SectionImpl("s", 1), "v2"); - session.update().set(book::notes, expected).where(book::id, eq(id)).sync(); + session.update().set(book::notes, expected).where(book::id, eq(id)).sync(); - actual = session.select(book).where(book::id, eq(id)).sync().findFirst().get(); - Assert.assertEquals(id, actual.id()); - assertEqualMaps(expected, actual.notes()); + actual = session.select(book).where(book::id, eq(id)).sync().findFirst().get(); + Assert.assertEquals(id, actual.id()); + assertEqualMaps(expected, actual.notes()); - // INSERT + // INSERT - // put operation + // put operation - Section third = new SectionImpl("t", 3); + Section third = new SectionImpl("t", 3); - expected.put(third, "v3"); - session.update().put(book::notes, third, "v3").where(book::id, eq(id)).sync(); + expected.put(third, "v3"); + session.update().put(book::notes, third, "v3").where(book::id, eq(id)).sync(); - actualMap = session.select(book::notes).where(book::id, eq(id)).sync().findFirst().get()._1; - assertEqualMaps(expected, actualMap); + actualMap = session.select(book::notes).where(book::id, eq(id)).sync().findFirst().get()._1; + assertEqualMaps(expected, actualMap); - // putAll operation - expected.putAll(notes); - session.update().putAll(book::notes, notes).where(book::id, eq(id)).sync(); + // putAll operation + expected.putAll(notes); + session.update().putAll(book::notes, notes).where(book::id, eq(id)).sync(); - actualMap = session.select(book::notes).where(book::id, eq(id)).sync().findFirst().get()._1; - assertEqualMaps(expected, actualMap); + actualMap = session.select(book::notes).where(book::id, eq(id)).sync().findFirst().get()._1; + assertEqualMaps(expected, actualMap); - // put existing + // put existing - expected.put(third, "v33"); - session.update().put(book::notes, third, "v33").where(book::id, eq(id)).sync(); + expected.put(third, "v33"); + session.update().put(book::notes, third, "v33").where(book::id, eq(id)).sync(); - actualMap = session.select(book::notes).where(book::id, eq(id)).sync().findFirst().get()._1; - assertEqualMaps(expected, actualMap); + actualMap = session.select(book::notes).where(book::id, eq(id)).sync().findFirst().get()._1; + assertEqualMaps(expected, actualMap); - // DELETE + // DELETE - // remove single key + // remove single key - expected.remove(third); - session.update().put(book::notes, third, null).where(book::id, eq(id)).sync(); + expected.remove(third); + session.update().put(book::notes, third, null).where(book::id, eq(id)).sync(); - actualMap = session.select(book::notes).where(book::id, eq(id)).sync().findFirst().get()._1; - assertEqualMaps(expected, actualMap); + actualMap = session.select(book::notes).where(book::id, eq(id)).sync().findFirst().get()._1; + assertEqualMaps(expected, actualMap); - // remove full map + // remove full map - session.update().set(book::notes, null).where(book::id, eq(id)).sync(); + session.update().set(book::notes, null).where(book::id, eq(id)).sync(); - actualMap = session.select(book::notes).where(book::id, eq(id)).sync().findFirst().get()._1; - Assert.assertNull(actualMap); + actualMap = session.select(book::notes).where(book::id, eq(id)).sync().findFirst().get()._1; + Assert.assertNull(actualMap); - // remove object + // remove object - session.delete().where(book::id, eq(id)).sync(); - Long cnt = session.count().where(book::id, eq(id)).sync(); - Assert.assertEquals(Long.valueOf(0), cnt); - } + session.delete().where(book::id, eq(id)).sync(); + Long cnt = session.count().where(book::id, eq(id)).sync(); + Assert.assertEquals(Long.valueOf(0), cnt); + } - private void assertEqualMaps(Map expected, Map actual) { + private void assertEqualMaps(Map expected, Map actual) { - Assert.assertEquals(expected.size(), actual.size()); + Assert.assertEquals(expected.size(), actual.size()); - for (Section e : expected.keySet()) { - Section a = - actual.keySet().stream().filter(p -> p.title().equals(e.title())).findFirst().get(); - Assert.assertEquals(e.title(), a.title()); - Assert.assertEquals(e.page(), a.page()); - Assert.assertEquals(expected.get(e), actual.get(a)); - } - } + for (Section e : expected.keySet()) { + Section a = actual.keySet().stream().filter(p -> p.title().equals(e.title())).findFirst().get(); + Assert.assertEquals(e.title(), a.title()); + Assert.assertEquals(e.page(), a.page()); + Assert.assertEquals(expected.get(e), actual.get(a)); + } + } } diff --git a/src/test/java/net/helenus/test/integration/core/udtcollection/UDTListTest.java b/src/test/java/net/helenus/test/integration/core/udtcollection/UDTListTest.java index 378d559..48aec46 100644 --- a/src/test/java/net/helenus/test/integration/core/udtcollection/UDTListTest.java +++ b/src/test/java/net/helenus/test/integration/core/udtcollection/UDTListTest.java @@ -18,157 +18,145 @@ package net.helenus.test.integration.core.udtcollection; import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeoutException; -import net.helenus.core.Query; + import org.junit.Assert; import org.junit.Test; +import net.helenus.core.Query; + public class UDTListTest extends UDTCollectionTest { - @Test - public void testListCRUID() throws TimeoutException { + @Test + public void testListCRUID() throws TimeoutException { - int id = 777; + int id = 777; - List authors = new ArrayList(); - authors.add(new AuthorImpl("Alex", "San Jose")); - authors.add(new AuthorImpl("Bob", "San Francisco")); + List authors = new ArrayList(); + authors.add(new AuthorImpl("Alex", "San Jose")); + authors.add(new AuthorImpl("Bob", "San Francisco")); - // CREATE + // CREATE - session.insert().value(book::id, id).value(book::authors, authors).sync(); + session.insert().value(book::id, id).value(book::authors, authors).sync(); - // READ + // READ - // read full object + // read full object - Book actual = session.select(book).where(book::id, Query.eq(id)).sync().findFirst().get(); - Assert.assertEquals(id, actual.id()); - assertEqualLists(authors, actual.authors()); - Assert.assertNull(actual.reviewers()); - Assert.assertNull(actual.contents()); + Book actual = session.select(book).where(book::id, Query.eq(id)).sync().findFirst().get(); + Assert.assertEquals(id, actual.id()); + assertEqualLists(authors, actual.authors()); + Assert.assertNull(actual.reviewers()); + Assert.assertNull(actual.contents()); - // read full list + // read full list - List actualList = - session.select(book::authors).where(book::id, Query.eq(id)).sync().findFirst().get()._1; - assertEqualLists(authors, actualList); + List actualList = session.select(book::authors).where(book::id, Query.eq(id)).sync().findFirst() + .get()._1; + assertEqualLists(authors, actualList); - // read single value by index + // read single value by index - String cql = session.select(Query.getIdx(book::authors, 1)).where(book::id, Query.eq(id)).cql(); + String cql = session.select(Query.getIdx(book::authors, 1)).where(book::id, Query.eq(id)).cql(); - System.out.println("Still not supporting cql = " + cql); + System.out.println("Still not supporting cql = " + cql); - // UPDATE + // UPDATE - List expected = new ArrayList(); - expected.add(new AuthorImpl("Unknown", "City 17")); + List expected = new ArrayList(); + expected.add(new AuthorImpl("Unknown", "City 17")); - session.update().set(book::authors, expected).where(book::id, Query.eq(id)).sync(); + session.update().set(book::authors, expected).where(book::id, Query.eq(id)).sync(); - actual = session.select(book).where(book::id, Query.eq(id)).sync().findFirst().get(); - Assert.assertEquals(id, actual.id()); - assertEqualLists(expected, actual.authors()); + actual = session.select(book).where(book::id, Query.eq(id)).sync().findFirst().get(); + Assert.assertEquals(id, actual.id()); + assertEqualLists(expected, actual.authors()); - // INSERT + // INSERT - // prepend operation + // prepend operation - expected.add(0, new AuthorImpl("Prepend", "PrependCity")); - session - .update() - .prepend(book::authors, new AuthorImpl("Prepend", "PrependCity")) - .where(book::id, Query.eq(id)) - .sync(); + expected.add(0, new AuthorImpl("Prepend", "PrependCity")); + session.update().prepend(book::authors, new AuthorImpl("Prepend", "PrependCity")).where(book::id, Query.eq(id)) + .sync(); - actualList = - session.select(book::authors).where(book::id, Query.eq(id)).sync().findFirst().get()._1; - assertEqualLists(expected, actualList); + actualList = session.select(book::authors).where(book::id, Query.eq(id)).sync().findFirst().get()._1; + assertEqualLists(expected, actualList); - // append operation + // append operation - expected.add(new AuthorImpl("Append", "AppendCity")); - session - .update() - .append(book::authors, new AuthorImpl("Append", "AppendCity")) - .where(book::id, Query.eq(id)) - .sync(); + expected.add(new AuthorImpl("Append", "AppendCity")); + session.update().append(book::authors, new AuthorImpl("Append", "AppendCity")).where(book::id, Query.eq(id)) + .sync(); - actualList = - session.select(book::authors).where(book::id, Query.eq(id)).sync().findFirst().get()._1; - assertEqualLists(expected, actualList); + actualList = session.select(book::authors).where(book::id, Query.eq(id)).sync().findFirst().get()._1; + assertEqualLists(expected, actualList); - // prependAll operation - expected.addAll(0, authors); - session.update().prependAll(book::authors, authors).where(book::id, Query.eq(id)).sync(); + // prependAll operation + expected.addAll(0, authors); + session.update().prependAll(book::authors, authors).where(book::id, Query.eq(id)).sync(); - actualList = - session.select(book::authors).where(book::id, Query.eq(id)).sync().findFirst().get()._1; - assertEqualLists(expected, actualList); + actualList = session.select(book::authors).where(book::id, Query.eq(id)).sync().findFirst().get()._1; + assertEqualLists(expected, actualList); - // appendAll operation - expected.addAll(authors); - session.update().appendAll(book::authors, authors).where(book::id, Query.eq(id)).sync(); + // appendAll operation + expected.addAll(authors); + session.update().appendAll(book::authors, authors).where(book::id, Query.eq(id)).sync(); - actualList = - session.select(book::authors).where(book::id, Query.eq(id)).sync().findFirst().get()._1; - assertEqualLists(expected, actualList); + actualList = session.select(book::authors).where(book::id, Query.eq(id)).sync().findFirst().get()._1; + assertEqualLists(expected, actualList); - // set by Index + // set by Index - Author inserted = new AuthorImpl("Insert", "InsertCity"); - expected.set(5, inserted); - session.update().setIdx(book::authors, 5, inserted).where(book::id, Query.eq(id)).sync(); + Author inserted = new AuthorImpl("Insert", "InsertCity"); + expected.set(5, inserted); + session.update().setIdx(book::authors, 5, inserted).where(book::id, Query.eq(id)).sync(); - actualList = - session.select(book::authors).where(book::id, Query.eq(id)).sync().findFirst().get()._1; - assertEqualLists(expected, actualList); + actualList = session.select(book::authors).where(book::id, Query.eq(id)).sync().findFirst().get()._1; + assertEqualLists(expected, actualList); - // DELETE + // DELETE - // remove single value + // remove single value - expected.remove(inserted); - session.update().discard(book::authors, inserted).where(book::id, Query.eq(id)).sync(); + expected.remove(inserted); + session.update().discard(book::authors, inserted).where(book::id, Query.eq(id)).sync(); - actualList = - session.select(book::authors).where(book::id, Query.eq(id)).sync().findFirst().get()._1; - assertEqualLists(expected, actualList); + actualList = session.select(book::authors).where(book::id, Query.eq(id)).sync().findFirst().get()._1; + assertEqualLists(expected, actualList); - // remove values + // remove values - expected.removeAll(authors); - session.update().discardAll(book::authors, authors).where(book::id, Query.eq(id)).sync(); + expected.removeAll(authors); + session.update().discardAll(book::authors, authors).where(book::id, Query.eq(id)).sync(); - actualList = - session.select(book::authors).where(book::id, Query.eq(id)).sync().findFirst().get()._1; - assertEqualLists(expected, actualList); + actualList = session.select(book::authors).where(book::id, Query.eq(id)).sync().findFirst().get()._1; + assertEqualLists(expected, actualList); - // remove full list + // remove full list - session.update().set(book::authors, null).where(book::id, Query.eq(id)).sync(); + session.update().set(book::authors, null).where(book::id, Query.eq(id)).sync(); - actualList = - session.select(book::authors).where(book::id, Query.eq(id)).sync().findFirst().get()._1; - Assert.assertNull(actualList); + actualList = session.select(book::authors).where(book::id, Query.eq(id)).sync().findFirst().get()._1; + Assert.assertNull(actualList); - // remove object + // remove object - session.delete().where(book::id, Query.eq(id)).sync(); - Long cnt = session.count().where(book::id, Query.eq(id)).sync(); - Assert.assertEquals(Long.valueOf(0), cnt); - } + session.delete().where(book::id, Query.eq(id)).sync(); + Long cnt = session.count().where(book::id, Query.eq(id)).sync(); + Assert.assertEquals(Long.valueOf(0), cnt); + } - private void assertEqualLists(List expected, List actual) { - Assert.assertEquals(expected.size(), actual.size()); + private void assertEqualLists(List expected, List actual) { + Assert.assertEquals(expected.size(), actual.size()); - int size = expected.size(); + int size = expected.size(); - for (int i = 0; i != size; ++i) { - Author e = expected.get(i); - Author a = actual.get(i); - Assert.assertEquals(e.name(), a.name()); - Assert.assertEquals(e.city(), a.city()); - } - } + for (int i = 0; i != size; ++i) { + Author e = expected.get(i); + Author a = actual.get(i); + Assert.assertEquals(e.name(), a.name()); + Assert.assertEquals(e.city(), a.city()); + } + } } diff --git a/src/test/java/net/helenus/test/integration/core/udtcollection/UDTMapTest.java b/src/test/java/net/helenus/test/integration/core/udtcollection/UDTMapTest.java index b563202..63a2422 100644 --- a/src/test/java/net/helenus/test/integration/core/udtcollection/UDTMapTest.java +++ b/src/test/java/net/helenus/test/integration/core/udtcollection/UDTMapTest.java @@ -18,136 +18,129 @@ package net.helenus.test.integration.core.udtcollection; import java.util.HashMap; import java.util.Map; import java.util.concurrent.TimeoutException; -import net.helenus.core.Query; + import org.junit.Assert; import org.junit.Test; +import net.helenus.core.Query; + public class UDTMapTest extends UDTCollectionTest { - @Test - public void testMapCRUID() throws TimeoutException { + @Test + public void testMapCRUID() throws TimeoutException { - int id = 333; + int id = 333; - Map writers = new HashMap(); - writers.put(new SectionImpl("first", 1), new AuthorImpl("Alex", "San Jose")); - writers.put(new SectionImpl("second", 2), new AuthorImpl("Bob", "San Francisco")); + Map writers = new HashMap(); + writers.put(new SectionImpl("first", 1), new AuthorImpl("Alex", "San Jose")); + writers.put(new SectionImpl("second", 2), new AuthorImpl("Bob", "San Francisco")); - // CREATE + // CREATE - session.insert().value(book::id, id).value(book::writers, writers).sync(); + session.insert().value(book::id, id).value(book::writers, writers).sync(); - // READ + // READ - // read full object + // read full object - Book actual = session.select(book).where(book::id, Query.eq(id)).sync().findFirst().get(); - Assert.assertEquals(id, actual.id()); - assertEqualMaps(writers, actual.writers()); - Assert.assertNull(actual.reviewers()); - Assert.assertNull(actual.notes()); - Assert.assertNull(actual.contents()); + Book actual = session.select(book).where(book::id, Query.eq(id)).sync().findFirst().get(); + Assert.assertEquals(id, actual.id()); + assertEqualMaps(writers, actual.writers()); + Assert.assertNull(actual.reviewers()); + Assert.assertNull(actual.notes()); + Assert.assertNull(actual.contents()); - // read full map + // read full map - Map actualMap = - session.select(book::writers).where(book::id, Query.eq(id)).sync().findFirst().get()._1; - assertEqualMaps(writers, actualMap); + Map actualMap = session.select(book::writers).where(book::id, Query.eq(id)).sync().findFirst() + .get()._1; + assertEqualMaps(writers, actualMap); - // read single key-value in map + // read single key-value in map - String cql = - session - .select(Query.get(book::writers, new SectionImpl("first", 1))) - .where(book::id, Query.eq(id)) - .cql(); + String cql = session.select(Query.get(book::writers, new SectionImpl("first", 1))).where(book::id, Query.eq(id)) + .cql(); - System.out.println("Still not supporting cql = " + cql); + System.out.println("Still not supporting cql = " + cql); - // UPDATE + // UPDATE - Map expected = new HashMap(); - expected.put(new SectionImpl("f", 1), new AuthorImpl("A", "SJ")); - expected.put(new SectionImpl("s", 1), new AuthorImpl("B", "SF")); + Map expected = new HashMap(); + expected.put(new SectionImpl("f", 1), new AuthorImpl("A", "SJ")); + expected.put(new SectionImpl("s", 1), new AuthorImpl("B", "SF")); - session.update().set(book::writers, expected).where(book::id, Query.eq(id)).sync(); + session.update().set(book::writers, expected).where(book::id, Query.eq(id)).sync(); - actual = session.select(book).where(book::id, Query.eq(id)).sync().findFirst().get(); - Assert.assertEquals(id, actual.id()); - assertEqualMaps(expected, actual.writers()); + actual = session.select(book).where(book::id, Query.eq(id)).sync().findFirst().get(); + Assert.assertEquals(id, actual.id()); + assertEqualMaps(expected, actual.writers()); - // INSERT + // INSERT - // put operation + // put operation - Section third = new SectionImpl("t", 3); - Author unk = new AuthorImpl("Unk", "City 17"); + Section third = new SectionImpl("t", 3); + Author unk = new AuthorImpl("Unk", "City 17"); - expected.put(third, unk); - session.update().put(book::writers, third, unk).where(book::id, Query.eq(id)).sync(); + expected.put(third, unk); + session.update().put(book::writers, third, unk).where(book::id, Query.eq(id)).sync(); - actualMap = - session.select(book::writers).where(book::id, Query.eq(id)).sync().findFirst().get()._1; - assertEqualMaps(expected, actualMap); + actualMap = session.select(book::writers).where(book::id, Query.eq(id)).sync().findFirst().get()._1; + assertEqualMaps(expected, actualMap); - // putAll operation - expected.putAll(writers); - session.update().putAll(book::writers, writers).where(book::id, Query.eq(id)).sync(); + // putAll operation + expected.putAll(writers); + session.update().putAll(book::writers, writers).where(book::id, Query.eq(id)).sync(); - actualMap = - session.select(book::writers).where(book::id, Query.eq(id)).sync().findFirst().get()._1; - assertEqualMaps(expected, actualMap); + actualMap = session.select(book::writers).where(book::id, Query.eq(id)).sync().findFirst().get()._1; + assertEqualMaps(expected, actualMap); - // put existing + // put existing - expected.put(third, unk); - session.update().put(book::writers, third, unk).where(book::id, Query.eq(id)).sync(); + expected.put(third, unk); + session.update().put(book::writers, third, unk).where(book::id, Query.eq(id)).sync(); - actualMap = - session.select(book::writers).where(book::id, Query.eq(id)).sync().findFirst().get()._1; - assertEqualMaps(expected, actualMap); + actualMap = session.select(book::writers).where(book::id, Query.eq(id)).sync().findFirst().get()._1; + assertEqualMaps(expected, actualMap); - // DELETE + // DELETE - // remove single key + // remove single key - expected.remove(third); - session.update().put(book::writers, third, null).where(book::id, Query.eq(id)).sync(); + expected.remove(third); + session.update().put(book::writers, third, null).where(book::id, Query.eq(id)).sync(); - actualMap = - session.select(book::writers).where(book::id, Query.eq(id)).sync().findFirst().get()._1; - assertEqualMaps(expected, actualMap); + actualMap = session.select(book::writers).where(book::id, Query.eq(id)).sync().findFirst().get()._1; + assertEqualMaps(expected, actualMap); - // remove full map + // remove full map - session.update().set(book::writers, null).where(book::id, Query.eq(id)).sync(); + session.update().set(book::writers, null).where(book::id, Query.eq(id)).sync(); - actualMap = - session.select(book::writers).where(book::id, Query.eq(id)).sync().findFirst().get()._1; - Assert.assertNull(actualMap); + actualMap = session.select(book::writers).where(book::id, Query.eq(id)).sync().findFirst().get()._1; + Assert.assertNull(actualMap); - // remove object + // remove object - session.delete().where(book::id, Query.eq(id)).sync(); - Long cnt = session.count().where(book::id, Query.eq(id)).sync(); - Assert.assertEquals(Long.valueOf(0), cnt); - } + session.delete().where(book::id, Query.eq(id)).sync(); + Long cnt = session.count().where(book::id, Query.eq(id)).sync(); + Assert.assertEquals(Long.valueOf(0), cnt); + } - private void assertEqualMaps(Map expected, Map actual) { + private void assertEqualMaps(Map expected, Map actual) { - Assert.assertEquals(expected.size(), actual.size()); + Assert.assertEquals(expected.size(), actual.size()); - for (Section e : expected.keySet()) { - Section a = - actual.keySet().stream().filter(p -> p.title().equals(e.title())).findFirst().get(); - Assert.assertEquals(e.title(), a.title()); - Assert.assertEquals(e.page(), a.page()); + for (Section e : expected.keySet()) { + Section a = actual.keySet().stream().filter(p -> p.title().equals(e.title())).findFirst().get(); + Assert.assertEquals(e.title(), a.title()); + Assert.assertEquals(e.page(), a.page()); - Author ea = expected.get(e); - Author aa = actual.get(a); + Author ea = expected.get(e); + Author aa = actual.get(a); - Assert.assertEquals(ea.name(), aa.name()); - Assert.assertEquals(ea.city(), aa.city()); - } - } + Assert.assertEquals(ea.name(), aa.name()); + Assert.assertEquals(ea.city(), aa.city()); + } + } } diff --git a/src/test/java/net/helenus/test/integration/core/udtcollection/UDTSetTest.java b/src/test/java/net/helenus/test/integration/core/udtcollection/UDTSetTest.java index 7a23687..b9f6538 100644 --- a/src/test/java/net/helenus/test/integration/core/udtcollection/UDTSetTest.java +++ b/src/test/java/net/helenus/test/integration/core/udtcollection/UDTSetTest.java @@ -18,107 +18,100 @@ package net.helenus.test.integration.core.udtcollection; import java.util.HashSet; import java.util.Set; import java.util.concurrent.TimeoutException; -import net.helenus.core.Query; + import org.junit.Assert; import org.junit.Test; +import net.helenus.core.Query; + public class UDTSetTest extends UDTCollectionTest { - @Test - public void testSetCRUID() throws TimeoutException { + @Test + public void testSetCRUID() throws TimeoutException { - int id = 555; + int id = 555; - // CREATE + // CREATE - Set reviewers = new HashSet(); - reviewers.add(new AuthorImpl("Alex", "San Jose")); - reviewers.add(new AuthorImpl("Bob", "San Francisco")); + Set reviewers = new HashSet(); + 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(); + session.insert().value(book::id, id).value(book::reviewers, reviewers).sync(); - // READ + // READ - Book actual = session.select(Book.class).where(book::id, Query.eq(id)).sync().findFirst().get(); - Assert.assertEquals(id, actual.id()); - assertEqualSets(reviewers, actual.reviewers()); + Book actual = session.select(Book.class).where(book::id, Query.eq(id)).sync().findFirst().get(); + Assert.assertEquals(id, actual.id()); + assertEqualSets(reviewers, actual.reviewers()); - // UPDATE + // UPDATE - Set expected = new HashSet(); - expected.add(new AuthorImpl("Craig", "Los Altos")); + Set expected = new HashSet(); + expected.add(new AuthorImpl("Craig", "Los Altos")); - session.update().set(book::reviewers, expected).where(book::id, Query.eq(id)).sync(); + session.update().set(book::reviewers, expected).where(book::id, Query.eq(id)).sync(); - Set actualSet = - session.select(book::reviewers).where(book::id, Query.eq(id)).sync().findFirst().get()._1; - assertEqualSets(expected, actualSet); + Set actualSet = session.select(book::reviewers).where(book::id, Query.eq(id)).sync().findFirst() + .get()._1; + assertEqualSets(expected, actualSet); - // add operation + // add operation - expected.add(new AuthorImpl("Add", "AddCity")); - session - .update() - .add(book::reviewers, new AuthorImpl("Add", "AddCity")) - .where(book::id, Query.eq(id)) - .sync(); + expected.add(new AuthorImpl("Add", "AddCity")); + session.update().add(book::reviewers, new AuthorImpl("Add", "AddCity")).where(book::id, Query.eq(id)).sync(); - actualSet = - session.select(book::reviewers).where(book::id, Query.eq(id)).sync().findFirst().get()._1; - assertEqualSets(expected, actualSet); + actualSet = session.select(book::reviewers).where(book::id, Query.eq(id)).sync().findFirst().get()._1; + assertEqualSets(expected, actualSet); - // addAll operation - expected.addAll(reviewers); - session.update().addAll(book::reviewers, reviewers).where(book::id, Query.eq(id)).sync(); + // addAll operation + expected.addAll(reviewers); + session.update().addAll(book::reviewers, reviewers).where(book::id, Query.eq(id)).sync(); - actualSet = - session.select(book::reviewers).where(book::id, Query.eq(id)).sync().findFirst().get()._1; - assertEqualSets(expected, actualSet); + actualSet = session.select(book::reviewers).where(book::id, Query.eq(id)).sync().findFirst().get()._1; + assertEqualSets(expected, actualSet); - // DELETE + // DELETE - // remove single value + // remove single value - Author a = expected.stream().filter(p -> p.name().equals("Add")).findFirst().get(); - expected.remove(a); + Author a = expected.stream().filter(p -> p.name().equals("Add")).findFirst().get(); + expected.remove(a); - session.update().remove(book::reviewers, a).where(book::id, Query.eq(id)).sync(); + session.update().remove(book::reviewers, a).where(book::id, Query.eq(id)).sync(); - actualSet = - session.select(book::reviewers).where(book::id, Query.eq(id)).sync().findFirst().get()._1; - assertEqualSets(expected, actualSet); + actualSet = session.select(book::reviewers).where(book::id, Query.eq(id)).sync().findFirst().get()._1; + assertEqualSets(expected, actualSet); - // remove values + // remove values - expected.remove(expected.stream().filter(p -> p.name().equals("Alex")).findFirst().get()); - expected.remove(expected.stream().filter(p -> p.name().equals("Bob")).findFirst().get()); - session.update().removeAll(book::reviewers, reviewers).where(book::id, Query.eq(id)).sync(); + expected.remove(expected.stream().filter(p -> p.name().equals("Alex")).findFirst().get()); + expected.remove(expected.stream().filter(p -> p.name().equals("Bob")).findFirst().get()); + session.update().removeAll(book::reviewers, reviewers).where(book::id, Query.eq(id)).sync(); - actualSet = - session.select(book::reviewers).where(book::id, Query.eq(id)).sync().findFirst().get()._1; - assertEqualSets(expected, actualSet); + actualSet = session.select(book::reviewers).where(book::id, Query.eq(id)).sync().findFirst().get()._1; + assertEqualSets(expected, actualSet); - // remove full list + // remove full list - session.update().set(book::reviewers, null).where(book::id, Query.eq(id)).sync(); + session.update().set(book::reviewers, null).where(book::id, Query.eq(id)).sync(); - actualSet = - session.select(book::reviewers).where(book::id, Query.eq(id)).sync().findFirst().get()._1; - Assert.assertNull(actualSet); + actualSet = session.select(book::reviewers).where(book::id, Query.eq(id)).sync().findFirst().get()._1; + Assert.assertNull(actualSet); - // remove object + // remove object - session.delete().where(book::id, Query.eq(id)).sync(); - Long cnt = session.count().where(book::id, Query.eq(id)).sync(); - Assert.assertEquals(Long.valueOf(0), cnt); - } + session.delete().where(book::id, Query.eq(id)).sync(); + Long cnt = session.count().where(book::id, Query.eq(id)).sync(); + Assert.assertEquals(Long.valueOf(0), cnt); + } - private void assertEqualSets(Set expected, Set actual) { - Assert.assertEquals(expected.size(), actual.size()); + private void assertEqualSets(Set expected, Set actual) { + Assert.assertEquals(expected.size(), actual.size()); - for (Author e : expected) { - Author a = actual.stream().filter(p -> p.name().equals(e.name())).findFirst().get(); - Assert.assertEquals(e.city(), a.city()); - } - } + for (Author e : expected) { + Author a = actual.stream().filter(p -> p.name().equals(e.name())).findFirst().get(); + Assert.assertEquals(e.city(), a.city()); + } + } } diff --git a/src/test/java/net/helenus/test/integration/core/udtcollection/UDTValueMapTest.java b/src/test/java/net/helenus/test/integration/core/udtcollection/UDTValueMapTest.java index e1b50f0..a90de36 100644 --- a/src/test/java/net/helenus/test/integration/core/udtcollection/UDTValueMapTest.java +++ b/src/test/java/net/helenus/test/integration/core/udtcollection/UDTValueMapTest.java @@ -21,120 +21,121 @@ import static net.helenus.core.Query.get; import java.util.HashMap; import java.util.Map; import java.util.concurrent.TimeoutException; + import org.junit.Assert; import org.junit.Test; public class UDTValueMapTest extends UDTCollectionTest { - @Test - public void testValueMapCRUID() throws TimeoutException { + @Test + public void testValueMapCRUID() throws TimeoutException { - int id = 999; + int id = 999; - Map contents = new HashMap(); - contents.put(1, new SectionImpl("first", 1)); - contents.put(2, new SectionImpl("second", 2)); + Map contents = new HashMap(); + contents.put(1, new SectionImpl("first", 1)); + contents.put(2, new SectionImpl("second", 2)); - // CREATE + // CREATE - session.insert().value(book::id, id).value(book::contents, contents).sync(); + session.insert().value(book::id, id).value(book::contents, contents).sync(); - // READ + // READ - // read full object + // read full object - Book actual = session.select(Book.class).where(book::id, eq(id)).sync().findFirst().get(); - Assert.assertEquals(id, actual.id()); - assertEqualMaps(contents, actual.contents()); - Assert.assertNull(actual.reviewers()); - Assert.assertNull(actual.writers()); - Assert.assertNull(actual.notes()); + Book actual = session.select(Book.class).where(book::id, eq(id)).sync().findFirst().get(); + Assert.assertEquals(id, actual.id()); + assertEqualMaps(contents, actual.contents()); + Assert.assertNull(actual.reviewers()); + Assert.assertNull(actual.writers()); + Assert.assertNull(actual.notes()); - // read full map + // read full map - Map actualMap = - session.select(book::contents).where(book::id, eq(id)).sync().findFirst().get()._1; - assertEqualMaps(contents, actualMap); + Map actualMap = session.select(book::contents).where(book::id, eq(id)).sync().findFirst() + .get()._1; + assertEqualMaps(contents, actualMap); - // read single key-value in map + // read single key-value in map - String cql = session.select(get(book::contents, 1)).where(book::id, eq(id)).cql(); + String cql = session.select(get(book::contents, 1)).where(book::id, eq(id)).cql(); - System.out.println("Still not supporting cql = " + cql); + System.out.println("Still not supporting cql = " + cql); - // UPDATE + // UPDATE - Map expected = new HashMap(); - expected.put(4, new SectionImpl("4", 4)); - expected.put(5, new SectionImpl("5", 5)); + Map expected = new HashMap(); + expected.put(4, new SectionImpl("4", 4)); + expected.put(5, new SectionImpl("5", 5)); - session.update().set(book::contents, expected).where(book::id, eq(id)).sync(); + session.update().set(book::contents, expected).where(book::id, eq(id)).sync(); - actual = session.select(Book.class).where(book::id, eq(id)).sync().findFirst().get(); - Assert.assertEquals(id, actual.id()); - assertEqualMaps(expected, actual.contents()); + actual = session.select(Book.class).where(book::id, eq(id)).sync().findFirst().get(); + Assert.assertEquals(id, actual.id()); + assertEqualMaps(expected, actual.contents()); - // INSERT + // INSERT - // put operation + // put operation - Section third = new SectionImpl("t", 3); + Section third = new SectionImpl("t", 3); - expected.put(3, third); - session.update().put(book::contents, 3, third).where(book::id, eq(id)).sync(); + expected.put(3, third); + session.update().put(book::contents, 3, third).where(book::id, eq(id)).sync(); - actualMap = session.select(book::contents).where(book::id, eq(id)).sync().findFirst().get()._1; - assertEqualMaps(expected, actualMap); + actualMap = session.select(book::contents).where(book::id, eq(id)).sync().findFirst().get()._1; + assertEqualMaps(expected, actualMap); - // putAll operation - expected.putAll(contents); - session.update().putAll(book::contents, contents).where(book::id, eq(id)).sync(); + // putAll operation + expected.putAll(contents); + session.update().putAll(book::contents, contents).where(book::id, eq(id)).sync(); - actualMap = session.select(book::contents).where(book::id, eq(id)).sync().findFirst().get()._1; - assertEqualMaps(expected, actualMap); + actualMap = session.select(book::contents).where(book::id, eq(id)).sync().findFirst().get()._1; + assertEqualMaps(expected, actualMap); - // put existing + // put existing - third = new SectionImpl("t-replace", 3); - expected.put(3, third); - session.update().put(book::contents, 3, third).where(book::id, eq(id)).sync(); + third = new SectionImpl("t-replace", 3); + expected.put(3, third); + session.update().put(book::contents, 3, third).where(book::id, eq(id)).sync(); - actualMap = session.select(book::contents).where(book::id, eq(id)).sync().findFirst().get()._1; - assertEqualMaps(expected, actualMap); + actualMap = session.select(book::contents).where(book::id, eq(id)).sync().findFirst().get()._1; + assertEqualMaps(expected, actualMap); - // DELETE + // DELETE - // remove single key + // remove single key - expected.remove(3); - session.update().put(book::contents, 3, null).where(book::id, eq(id)).sync(); + expected.remove(3); + session.update().put(book::contents, 3, null).where(book::id, eq(id)).sync(); - actualMap = session.select(book::contents).where(book::id, eq(id)).sync().findFirst().get()._1; - assertEqualMaps(expected, actualMap); + actualMap = session.select(book::contents).where(book::id, eq(id)).sync().findFirst().get()._1; + assertEqualMaps(expected, actualMap); - // remove full map + // remove full map - session.update().set(book::contents, null).where(book::id, eq(id)).sync(); + session.update().set(book::contents, null).where(book::id, eq(id)).sync(); - actualMap = session.select(book::contents).where(book::id, eq(id)).sync().findFirst().get()._1; - Assert.assertNull(actualMap); + actualMap = session.select(book::contents).where(book::id, eq(id)).sync().findFirst().get()._1; + Assert.assertNull(actualMap); - // remove object + // remove object - session.delete().where(book::id, eq(id)).sync(); - Long cnt = session.count().where(book::id, eq(id)).sync(); - Assert.assertEquals(Long.valueOf(0), cnt); - } + session.delete().where(book::id, eq(id)).sync(); + Long cnt = session.count().where(book::id, eq(id)).sync(); + Assert.assertEquals(Long.valueOf(0), cnt); + } - private void assertEqualMaps(Map expected, Map actual) { + private void assertEqualMaps(Map expected, Map actual) { - Assert.assertEquals(expected.size(), actual.size()); + Assert.assertEquals(expected.size(), actual.size()); - for (Integer i : expected.keySet()) { - Section e = expected.get(i); - Section a = actual.get(i); - Assert.assertEquals(e.title(), a.title()); - Assert.assertEquals(e.page(), a.page()); - } - } + for (Integer i : expected.keySet()) { + Section e = expected.get(i); + Section a = actual.get(i); + Assert.assertEquals(e.title(), a.title()); + Assert.assertEquals(e.page(), a.page()); + } + } } diff --git a/src/test/java/net/helenus/test/integration/core/unitofwork/AndThenOrderTest.java b/src/test/java/net/helenus/test/integration/core/unitofwork/AndThenOrderTest.java index 2b3ebcd..9a20ad2 100644 --- a/src/test/java/net/helenus/test/integration/core/unitofwork/AndThenOrderTest.java +++ b/src/test/java/net/helenus/test/integration/core/unitofwork/AndThenOrderTest.java @@ -18,133 +18,112 @@ package net.helenus.test.integration.core.unitofwork; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import net.helenus.core.Helenus; -import net.helenus.core.HelenusSession; -import net.helenus.core.UnitOfWork; -import net.helenus.test.integration.build.AbstractEmbeddedCassandraTest; + import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; +import net.helenus.core.Helenus; +import net.helenus.core.HelenusSession; +import net.helenus.core.UnitOfWork; +import net.helenus.test.integration.build.AbstractEmbeddedCassandraTest; + public class AndThenOrderTest extends AbstractEmbeddedCassandraTest { - static HelenusSession session; + static HelenusSession session; - @BeforeClass - public static void beforeTest() { - session = Helenus.init(getSession()).showCql().autoCreateDrop().get(); - } + @BeforeClass + public static void beforeTest() { + session = Helenus.init(getSession()).showCql().autoCreateDrop().get(); + } - @Test - public void testAndThenOrdering() throws Exception { - List q = new ArrayList(5); - UnitOfWork uow1, uow2, uow3, uow4, uow5; + @Test + public void testAndThenOrdering() throws Exception { + List q = new ArrayList(5); + UnitOfWork uow1, uow2, uow3, uow4, uow5; - uow5 = session.begin(); - uow3 = session.begin(uow5); - uow1 = session.begin(uow3); - uow1.commit() - .andThen( - () -> { - q.add("1"); - }); - uow2 = session.begin(uow3); - uow2.commit() - .andThen( - () -> { - q.add("2"); - }); - uow3.commit() - .andThen( - () -> { - q.add("3"); - }); - uow4 = session.begin(uow5); - uow4.commit() - .andThen( - () -> { - q.add("4"); - }); - uow5.commit() - .andThen( - () -> { - q.add("5"); - }); + uow5 = session.begin(); + uow3 = session.begin(uow5); + uow1 = session.begin(uow3); + uow1.commit().andThen(() -> { + q.add("1"); + }); + uow2 = session.begin(uow3); + uow2.commit().andThen(() -> { + q.add("2"); + }); + uow3.commit().andThen(() -> { + q.add("3"); + }); + uow4 = session.begin(uow5); + uow4.commit().andThen(() -> { + q.add("4"); + }); + uow5.commit().andThen(() -> { + q.add("5"); + }); - System.out.println(q); - Assert.assertTrue( - Arrays.equals(q.toArray(new String[5]), new String[] {"1", "2", "3", "4", "5"})); - } + System.out.println(q); + Assert.assertTrue(Arrays.equals(q.toArray(new String[5]), new String[]{"1", "2", "3", "4", "5"})); + } - @Test - public void testExceptionWithinAndThen() throws Exception { - List q = new ArrayList(5); - UnitOfWork uow1, uow2, uow3, uow4, uow5; + @Test + public void testExceptionWithinAndThen() throws Exception { + List q = new ArrayList(5); + UnitOfWork uow1, uow2, uow3, uow4, uow5; - uow5 = session.begin(); - uow4 = session.begin(uow5); - try { - uow3 = session.begin(uow4); - uow1 = session.begin(uow3); - uow1.commit() - .andThen( - () -> { - q.add("1"); - }); - uow2 = session.begin(uow3); - uow2.commit() - .andThen( - () -> { - q.add("2"); - }); - uow3.commit() - .andThen( - () -> { - q.add("3"); - }); - uow4.commit() - .andThen( - () -> { - q.add("4"); - }); - throw new Exception(); - } catch (Exception e) { - uow4.abort(); - } - uow5.commit() - .andThen( - () -> { - q.add("5"); - }); + uow5 = session.begin(); + uow4 = session.begin(uow5); + try { + uow3 = session.begin(uow4); + uow1 = session.begin(uow3); + uow1.commit().andThen(() -> { + q.add("1"); + }); + uow2 = session.begin(uow3); + uow2.commit().andThen(() -> { + q.add("2"); + }); + uow3.commit().andThen(() -> { + q.add("3"); + }); + uow4.commit().andThen(() -> { + q.add("4"); + }); + throw new Exception(); + } catch (Exception e) { + uow4.abort(); + } + uow5.commit().andThen(() -> { + q.add("5"); + }); - System.out.println(q); - Assert.assertTrue(q.isEmpty() == true); - } + System.out.println(q); + Assert.assertTrue(q.isEmpty() == true); + } - @Test - public void testClosableWillAbortWhenNotCommitted() throws Exception { - UnitOfWork unitOfWork; - try (UnitOfWork uow = session.begin()) { - unitOfWork = uow; - Assert.assertFalse(uow.hasAborted()); - } - Assert.assertTrue(unitOfWork.hasAborted()); - } + @Test + public void testClosableWillAbortWhenNotCommitted() throws Exception { + UnitOfWork unitOfWork; + try (UnitOfWork uow = session.begin()) { + unitOfWork = uow; + Assert.assertFalse(uow.hasAborted()); + } + Assert.assertTrue(unitOfWork.hasAborted()); + } - @Test - public void testClosable() throws Exception { - UnitOfWork unitOfWork; - try (UnitOfWork uow = session.begin()) { - unitOfWork = uow; - Assert.assertFalse(uow.hasAborted()); - uow.commit() - .andThen( - () -> { - Assert.assertFalse(uow.hasAborted()); - Assert.assertTrue(uow.hasCommitted()); - }); - } - Assert.assertFalse(unitOfWork.hasAborted()); - Assert.assertTrue(unitOfWork.hasCommitted()); - } + @Test + public void testClosable() throws Exception { + UnitOfWork unitOfWork; + try (UnitOfWork uow = session.begin()) { + unitOfWork = uow; + Assert.assertFalse(uow.hasAborted()); + uow.commit().andThen(() -> { + Assert.assertFalse(uow.hasAborted()); + Assert.assertTrue(uow.hasCommitted()); + }); + } + Assert.assertFalse(unitOfWork.hasAborted()); + Assert.assertTrue(unitOfWork.hasCommitted()); + } } diff --git a/src/test/java/net/helenus/test/integration/core/unitofwork/Directory.java b/src/test/java/net/helenus/test/integration/core/unitofwork/Directory.java index 70cf9e9..282a666 100644 --- a/src/test/java/net/helenus/test/integration/core/unitofwork/Directory.java +++ b/src/test/java/net/helenus/test/integration/core/unitofwork/Directory.java @@ -15,13 +15,16 @@ */ package net.helenus.test.integration.core.unitofwork; -import com.datastax.driver.core.DataType.Name; import java.util.Set; -import net.helenus.mapping.annotation.*; + +import com.datastax.driver.core.DataType.Name; + +import net.helenus.mapping.annotation.Types; +import net.helenus.mapping.annotation.UDT; @UDT public interface Directory extends FilesystemNode { - @Types.Set(Name.TIMEUUID) - Set inodes(); + @Types.Set(Name.TIMEUUID) + Set inodes(); } diff --git a/src/test/java/net/helenus/test/integration/core/unitofwork/File.java b/src/test/java/net/helenus/test/integration/core/unitofwork/File.java index a0ccebd..2997650 100644 --- a/src/test/java/net/helenus/test/integration/core/unitofwork/File.java +++ b/src/test/java/net/helenus/test/integration/core/unitofwork/File.java @@ -15,11 +15,12 @@ */ package net.helenus.test.integration.core.unitofwork; -import net.helenus.mapping.annotation.*; +import net.helenus.mapping.annotation.Column; +import net.helenus.mapping.annotation.UDT; @UDT public interface File extends FilesystemNode { - @Column - byte[] data(); + @Column + byte[] data(); } diff --git a/src/test/java/net/helenus/test/integration/core/unitofwork/FileAttributes.java b/src/test/java/net/helenus/test/integration/core/unitofwork/FileAttributes.java index f2eaccc..934eb32 100644 --- a/src/test/java/net/helenus/test/integration/core/unitofwork/FileAttributes.java +++ b/src/test/java/net/helenus/test/integration/core/unitofwork/FileAttributes.java @@ -20,5 +20,5 @@ import net.helenus.mapping.annotation.UDT; @UDT public interface FileAttributes { - String owner(); + String owner(); } diff --git a/src/test/java/net/helenus/test/integration/core/unitofwork/FilesystemNode.java b/src/test/java/net/helenus/test/integration/core/unitofwork/FilesystemNode.java index 7907fbd..0fcaea7 100644 --- a/src/test/java/net/helenus/test/integration/core/unitofwork/FilesystemNode.java +++ b/src/test/java/net/helenus/test/integration/core/unitofwork/FilesystemNode.java @@ -16,17 +16,21 @@ package net.helenus.test.integration.core.unitofwork; import java.util.UUID; -import net.helenus.mapping.annotation.*; + +import net.helenus.mapping.annotation.ClusteringColumn; +import net.helenus.mapping.annotation.Column; +import net.helenus.mapping.annotation.PartitionKey; +import net.helenus.mapping.annotation.Table; @Table("fs") public interface FilesystemNode { - @PartitionKey - UUID inode(); + @PartitionKey + UUID inode(); - @ClusteringColumn - String name(); + @ClusteringColumn + String name(); - @Column - FileAttributes attr(); + @Column + FileAttributes attr(); } diff --git a/src/test/java/net/helenus/test/integration/core/unitofwork/UnitOfWorkTest.java b/src/test/java/net/helenus/test/integration/core/unitofwork/UnitOfWorkTest.java index ecc048c..328fb67 100644 --- a/src/test/java/net/helenus/test/integration/core/unitofwork/UnitOfWorkTest.java +++ b/src/test/java/net/helenus/test/integration/core/unitofwork/UnitOfWorkTest.java @@ -17,220 +17,191 @@ package net.helenus.test.integration.core.unitofwork; import static net.helenus.core.Query.eq; -import com.datastax.driver.core.utils.UUIDs; import java.util.UUID; + +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; + +import com.datastax.driver.core.utils.UUIDs; + import net.bytebuddy.utility.RandomString; import net.helenus.core.Helenus; import net.helenus.core.HelenusSession; import net.helenus.core.UnitOfWork; import net.helenus.core.annotation.Cacheable; -import net.helenus.mapping.annotation.*; +import net.helenus.mapping.annotation.Constraints; +import net.helenus.mapping.annotation.Index; +import net.helenus.mapping.annotation.PartitionKey; +import net.helenus.mapping.annotation.Table; import net.helenus.test.integration.build.AbstractEmbeddedCassandraTest; -import org.junit.Assert; -import org.junit.BeforeClass; -import org.junit.Test; @Table @Cacheable interface Widget { - @PartitionKey - UUID id(); + @PartitionKey + UUID id(); - @Index - @Constraints.Distinct() - String name(); + @Index + @Constraints.Distinct() + String name(); } public class UnitOfWorkTest extends AbstractEmbeddedCassandraTest { - static Widget widget; - static HelenusSession session; + static Widget widget; + static HelenusSession session; - @BeforeClass - public static void beforeTest() { - session = Helenus.init(getSession()).showCql().add(Widget.class).autoCreateDrop().get(); - widget = session.dsl(Widget.class); - } + @BeforeClass + public static void beforeTest() { + session = Helenus.init(getSession()).showCql().add(Widget.class).autoCreateDrop().get(); + widget = session.dsl(Widget.class); + } - @Test - public void testSelectAfterSelect() throws Exception { - Widget w1, w2, w3; - UUID key = UUIDs.timeBased(); + @Test + public void testSelectAfterSelect() throws Exception { + Widget w1, w2, w3, w4; + UUID key = UUIDs.timeBased(); - // This should inserted Widget, but not cache it. - session - .insert(widget) - .value(widget::id, key) - .value(widget::name, RandomString.make(20)) - .sync(); + // This should inserted Widget, but not cache it. + w1 = session.insert(widget).value(widget::id, key).value(widget::name, RandomString.make(20)).sync(); - try (UnitOfWork uow = session.begin()) { + try (UnitOfWork uow = session.begin()) { - uow.setPurpose("testSelectAfterSelect"); + uow.setPurpose("testSelectAfterSelect"); - // This should read from the database and return a Widget. - w1 = - session.select(widget).where(widget::id, eq(key)).single().sync(uow).orElse(null); + // This should read from the database and return a Widget. + w2 = session.select(widget).where(widget::id, eq(key)).single().sync(uow).orElse(null); - // This should read from the cache and get the same instance of a Widget. - w2 = - session.select(widget).where(widget::id, eq(key)).single().sync(uow).orElse(null); + // This should read from the cache and get the same instance of a Widget. + w3 = session.select(widget).where(widget::id, eq(key)).single().sync(uow).orElse(null); - uow.commit() - .andThen( - () -> { - Assert.assertEquals(w1, w2); - }); - } + uow.commit().andThen(() -> { + Assert.assertEquals(w2, w3); + }); + } - w3 = session.select(widget).where(widget::name, eq(w1.name())).single().sync().orElse(null); - Assert.assertEquals(w1, w3); - } + w4 = session.select(widget).where(widget::name, eq(w1.name())).single().sync().orElse(null); + Assert.assertEquals(w4, w1); + } - @Test - public void testSelectAfterNestedSelect() throws Exception { - Widget w1, w2, w3, w4; - UUID key1 = UUIDs.timeBased(); - UUID key2 = UUIDs.timeBased(); + @Test + public void testSelectAfterNestedSelect() throws Exception { + Widget w1, w2, w3, w4; + UUID key1 = UUIDs.timeBased(); + UUID key2 = UUIDs.timeBased(); - // This should inserted Widget, and not cache it in uow1. - try (UnitOfWork uow1 = session.begin()) { - w1 = - session - .insert(widget) - .value(widget::id, key1) - .value(widget::name, RandomString.make(20)) - .sync(uow1); + // This should inserted Widget, and not cache it in uow1. + try (UnitOfWork uow1 = session.begin()) { + w1 = session.insert(widget).value(widget::id, key1).value(widget::name, RandomString.make(20)) + .sync(uow1); - try (UnitOfWork uow2 = session.begin(uow1)) { + try (UnitOfWork uow2 = session.begin(uow1)) { - // This should read from uow1's cache and return the same Widget. - w2 = - session - .select(widget) - .where(widget::id, eq(key1)) - .single() - .sync(uow2) - .orElse(null); + // This should read from uow1's cache and return the same Widget. + w2 = session.select(widget).where(widget::id, eq(key1)).single().sync(uow2).orElse(null); - Assert.assertEquals(w1, w2); + Assert.assertEquals(w1, w2); - w3 = - session - .insert(widget) - .value(widget::id, key2) - .value(widget::name, RandomString.make(20)) - .sync(uow2); + w3 = session.insert(widget).value(widget::id, key2).value(widget::name, RandomString.make(20)) + .sync(uow2); - uow2.commit() - .andThen( - () -> { - Assert.assertEquals(w1, w2); - }); - } + uow2.commit().andThen(() -> { + Assert.assertEquals(w1, w2); + }); + } - // This should read from the cache and get the same instance of a Widget. - w4 = - session - .select(widget) - .where(widget::id, eq(key2)) - .single() - .sync(uow1) - .orElse(null); + // This should read from the cache and get the same instance of a Widget. + w4 = session.select(widget).where(widget::id, eq(key2)).single().sync(uow1).orElse(null); - uow1.commit() - .andThen( - () -> { - Assert.assertEquals(w3, w4); - }); - } - } + uow1.commit().andThen(() -> { + Assert.assertEquals(w3, w4); + }); + } + } - @Test - public void testSelectViaIndexAfterSelect() throws Exception { - Widget w1, w2; - UUID key = UUIDs.timeBased(); + @Test + public void testSelectViaIndexAfterSelect() throws Exception { + Widget w1, w2; + UUID key = UUIDs.timeBased(); - try (UnitOfWork uow = session.begin()) { - // This should insert and cache Widget in the uow. - session - .insert(widget) - .value(widget::id, key) - .value(widget::name, RandomString.make(20)) - .sync(uow); + try (UnitOfWork uow = session.begin()) { + // This should insert and cache Widget in the uow. + session.insert(widget).value(widget::id, key).value(widget::name, RandomString.make(20)).sync(uow); - // This should read from the database and return a Widget. - w1 = - session - .select(widget) - .where(widget::id, eq(key)) - .single() - .sync(uow) - .orElse(null); + // This should read from the database and return a Widget. + w1 = session.select(widget).where(widget::id, eq(key)).single().sync(uow).orElse(null); - // This should read from the cache and get the same instance of a Widget. - w2 = - session - .select(widget) - .where(widget::name, eq(w1.name())) - .single() - .sync(uow) - .orElse(null); + // This should read from the cache and get the same instance of a Widget. + w2 = session.select(widget).where(widget::name, eq(w1.name())).single().sync(uow).orElse(null); - uow.commit() - .andThen( - () -> { - Assert.assertEquals(w1, w2); - }); - } - } + uow.commit().andThen(() -> { + Assert.assertEquals(w1, w2); + }); + } + } + @Test + public void testSelectAfterDeleted() 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(); + // This should inserted Widget, but not cache it. + w1 = session.insert(widget).value(widget::id, key).value(widget::name, RandomString.make(20)).sync(); - try (UnitOfWork uow = session.begin()) { + try (UnitOfWork uow = session.begin()) { - // This should cache the inserted Widget. - w1 = session.insert(widget) - .value(widget::id, key) - .value(widget::name, RandomString.make(20)) - .sync(uow); + // This should read from the database and return a Widget. + w2 = session.select(widget).where(widget::id, eq(key)).single() + .sync(uow).orElse(null); - // This should read from the cache and get the same instance of a Widget. - w2 = session.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); - uow.commit() - .andThen(() -> { - Assert.assertEquals(w1, w2); - }); - } + // This should fail to read from the cache. + w3 = session.select(widget).where(widget::id, eq(key)).single() + .sync(uow).orElse(null); - // This should read the widget from the session cache and maintain object identity. - w3 = session.select(widget) - .where(widget::id, eq(key)) - .single() - .sync() - .orElse(null); + Assert.assertEquals(w3, null); - Assert.assertEquals(w1, w3); + uow.commit().andThen(() -> { + Assert.assertEquals(w1, w2); + Assert.assertEquals(w3, null); + }); + } - // This should read the widget from the database, no object identity but values should match. - w4 = session.select(widget) - .where(widget::id, eq(key)) - .ignoreCache() - .single() - .sync() - .orElse(null); + w4 = session.select(widget).where(widget::name, eq(w1.name())).single() + .sync().orElse(null); - Assert.assertNotEquals(w1, w4); - Assert.assertTrue(w1.equals(w4)); - } - */ + Assert.assertEquals(w4, null); + } + + /* + * @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.insert(widget) + * .value(widget::id, key) .value(widget::name, RandomString.make(20)) + * .sync(uow); + * + * // This should read from the cache and get the same instance of a Widget. w2 + * = session.select(widget) .where(widget::id, eq(key)) .single() + * .sync(uow) .orElse(null); + * + * uow.commit() .andThen(() -> { Assert.assertEquals(w1, w2); }); } + * + * // This should read the widget from the session cache and maintain object + * identity. w3 = session.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.select(widget) .where(widget::id, + * eq(key)) .ignoreCache() .single() .sync() .orElse(null); + * + * Assert.assertNotEquals(w1, w4); Assert.assertTrue(w1.equals(w4)); } + */ } diff --git a/src/test/java/net/helenus/test/integration/core/usertype/Account.java b/src/test/java/net/helenus/test/integration/core/usertype/Account.java index 27d0f2e..ec26e2d 100644 --- a/src/test/java/net/helenus/test/integration/core/usertype/Account.java +++ b/src/test/java/net/helenus/test/integration/core/usertype/Account.java @@ -16,6 +16,7 @@ package net.helenus.test.integration.core.usertype; import com.datastax.driver.core.UDTValue; + import net.helenus.mapping.annotation.Column; import net.helenus.mapping.annotation.PartitionKey; import net.helenus.mapping.annotation.Table; @@ -24,13 +25,13 @@ import net.helenus.mapping.annotation.Types; @Table public interface Account { - @PartitionKey(ordinal = 0) - long id(); + @PartitionKey(ordinal = 0) + long id(); - @Column - Address address(); + @Column + Address address(); - @Types.UDT("address") - @Column - UDTValue addressNoMapping(); + @Types.UDT("address") + @Column + UDTValue addressNoMapping(); } diff --git a/src/test/java/net/helenus/test/integration/core/usertype/Address.java b/src/test/java/net/helenus/test/integration/core/usertype/Address.java index 0d00876..0e6e965 100644 --- a/src/test/java/net/helenus/test/integration/core/usertype/Address.java +++ b/src/test/java/net/helenus/test/integration/core/usertype/Address.java @@ -15,8 +15,10 @@ */ package net.helenus.test.integration.core.usertype; -import com.datastax.driver.core.DataType; import java.util.Set; + +import com.datastax.driver.core.DataType; + import net.helenus.mapping.annotation.Column; import net.helenus.mapping.annotation.Types; import net.helenus.mapping.annotation.UDT; @@ -24,19 +26,19 @@ import net.helenus.mapping.annotation.UDT; @UDT("address") public interface Address { - @Column(ordinal = 0, value = "line_1") - String street(); + @Column(ordinal = 0, value = "line_1") + String street(); - @Column - String city(); + @Column + String city(); - @Column - int zip(); + @Column + int zip(); - @Column - String country(); + @Column + String country(); - @Column - @Types.Set(DataType.Name.TEXT) - Set phones(); + @Column + @Types.Set(DataType.Name.TEXT) + Set phones(); } diff --git a/src/test/java/net/helenus/test/integration/core/usertype/AddressInformation.java b/src/test/java/net/helenus/test/integration/core/usertype/AddressInformation.java index 5c8c9ee..82f5cf1 100644 --- a/src/test/java/net/helenus/test/integration/core/usertype/AddressInformation.java +++ b/src/test/java/net/helenus/test/integration/core/usertype/AddressInformation.java @@ -6,6 +6,6 @@ import net.helenus.mapping.annotation.UDT; @UDT public interface AddressInformation { - @Column - Address address(); + @Column + Address address(); } diff --git a/src/test/java/net/helenus/test/integration/core/usertype/Customer.java b/src/test/java/net/helenus/test/integration/core/usertype/Customer.java index 9290d0a..a5afdf0 100644 --- a/src/test/java/net/helenus/test/integration/core/usertype/Customer.java +++ b/src/test/java/net/helenus/test/integration/core/usertype/Customer.java @@ -1,6 +1,7 @@ package net.helenus.test.integration.core.usertype; import java.util.UUID; + import net.helenus.mapping.annotation.Column; import net.helenus.mapping.annotation.PartitionKey; import net.helenus.mapping.annotation.Table; @@ -8,9 +9,9 @@ import net.helenus.mapping.annotation.Table; @Table public interface Customer { - @PartitionKey - UUID id(); + @PartitionKey + UUID id(); - @Column - AddressInformation addressInformation(); + @Column + AddressInformation addressInformation(); } diff --git a/src/test/java/net/helenus/test/integration/core/usertype/InnerUserDefinedTypeTest.java b/src/test/java/net/helenus/test/integration/core/usertype/InnerUserDefinedTypeTest.java index bb0a287..d5496b3 100644 --- a/src/test/java/net/helenus/test/integration/core/usertype/InnerUserDefinedTypeTest.java +++ b/src/test/java/net/helenus/test/integration/core/usertype/InnerUserDefinedTypeTest.java @@ -15,118 +15,111 @@ */ package net.helenus.test.integration.core.usertype; -import com.google.common.collect.Sets; import java.util.Set; import java.util.UUID; import java.util.concurrent.TimeoutException; -import net.helenus.core.Helenus; -import net.helenus.core.HelenusSession; -import net.helenus.core.Query; -import net.helenus.test.integration.build.AbstractEmbeddedCassandraTest; + import org.junit.AfterClass; import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; +import com.google.common.collect.Sets; + +import net.helenus.core.Helenus; +import net.helenus.core.HelenusSession; +import net.helenus.core.Query; +import net.helenus.test.integration.build.AbstractEmbeddedCassandraTest; + public class InnerUserDefinedTypeTest extends AbstractEmbeddedCassandraTest { - static Customer customer; - static AddressInformation addressInformation; + static Customer customer; + static AddressInformation addressInformation; - static HelenusSession session; + static HelenusSession session; - @BeforeClass - public static void beforeTest() { - Helenus.clearDslCache(); - session = Helenus.init(getSession()).showCql().add(Customer.class).autoCreateDrop().get(); - customer = Helenus.dsl(Customer.class); - addressInformation = Helenus.dsl(AddressInformation.class); - } + @BeforeClass + public static void beforeTest() { + Helenus.clearDslCache(); + session = Helenus.init(getSession()).showCql().add(Customer.class).autoCreateDrop().get(); + customer = Helenus.dsl(Customer.class); + addressInformation = Helenus.dsl(AddressInformation.class); + } - @AfterClass - public static void afterTest() { - session.getSession().execute("DROP TABLE IF EXISTS customer;"); - session.getSession().execute("DROP TYPE IF EXISTS address_information;"); - // SchemaUtil.dropUserType(session.getSessionRepository().findUserType("address_information")), true); - } + @AfterClass + public static void afterTest() { + session.getSession().execute("DROP TABLE IF EXISTS customer;"); + session.getSession().execute("DROP TYPE IF EXISTS address_information;"); + // SchemaUtil.dropUserType(session.getSessionRepository().findUserType("address_information")), + // true); + } - @Test - public void testPrint() { - System.out.println(addressInformation); - System.out.println(customer); - } + @Test + public void testPrint() { + System.out.println(addressInformation); + System.out.println(customer); + } - @Test - public void testCrud() throws TimeoutException { + @Test + public void testCrud() throws TimeoutException { - UUID id = UUID.randomUUID(); + UUID id = UUID.randomUUID(); - Address a = - new Address() { + Address a = new Address() { - @Override - public String street() { - return "1 st"; - } + @Override + public String street() { + return "1 st"; + } - @Override - public String city() { - return "San Jose"; - } + @Override + public String city() { + return "San Jose"; + } - @Override - public int zip() { - return 95131; - } + @Override + public int zip() { + return 95131; + } - @Override - public String country() { - return "USA"; - } + @Override + public String country() { + return "USA"; + } - @Override - public Set phones() { - return Sets.newHashSet("14080000000"); - } - }; + @Override + public Set phones() { + return Sets.newHashSet("14080000000"); + } + }; - AddressInformation ai = - new AddressInformation() { + AddressInformation ai = new AddressInformation() { - @Override - public Address address() { - return a; - } - }; + @Override + public Address address() { + return a; + } + }; - session.insert().value(customer::id, id).value(customer::addressInformation, ai).sync(); + session.insert().value(customer::id, id).value(customer::addressInformation, ai).sync(); - String cql = - session - .update() - .set(customer.addressInformation().address()::street, "3 st") - .where(customer::id, Query.eq(id)) - .cql(); + String cql = session.update().set(customer.addressInformation().address()::street, "3 st") + .where(customer::id, Query.eq(id)).cql(); - //TODO: System.out.println("At the time when this test was written Cassandra did not support queries like this: " + cql); + // TODO: System.out.println("At the time when this test was written Cassandra + // did not support queries like this: " + cql); - session.update().set(customer::addressInformation, ai).where(customer::id, Query.eq(id)).sync(); + session.update().set(customer::addressInformation, ai).where(customer::id, Query.eq(id)).sync(); - String street = - session - .select(customer.addressInformation().address()::street) - .where(customer::id, Query.eq(id)) - .sync() - .findFirst() - .get() - ._1; + String street = session.select(customer.addressInformation().address()::street) + .where(customer::id, Query.eq(id)).sync().findFirst().get()._1; - Assert.assertEquals("1 st", street); + Assert.assertEquals("1 st", street); - session.delete().where(customer::id, Query.eq(id)).sync(); + session.delete().where(customer::id, Query.eq(id)).sync(); - Long cnt = session.count().where(customer::id, Query.eq(id)).sync(); + Long cnt = session.count().where(customer::id, Query.eq(id)).sync(); - Assert.assertEquals(Long.valueOf(0), cnt); - } + Assert.assertEquals(Long.valueOf(0), cnt); + } } diff --git a/src/test/java/net/helenus/test/integration/core/usertype/UserDefinedTypeTest.java b/src/test/java/net/helenus/test/integration/core/usertype/UserDefinedTypeTest.java index b5e5ef9..8c8ffaa 100644 --- a/src/test/java/net/helenus/test/integration/core/usertype/UserDefinedTypeTest.java +++ b/src/test/java/net/helenus/test/integration/core/usertype/UserDefinedTypeTest.java @@ -15,242 +15,204 @@ */ package net.helenus.test.integration.core.usertype; -import com.datastax.driver.core.UDTValue; -import com.datastax.driver.core.UserType; import java.util.Set; import java.util.concurrent.TimeoutException; -import net.helenus.core.Helenus; -import net.helenus.core.HelenusSession; -import net.helenus.core.Query; -import net.helenus.test.integration.build.AbstractEmbeddedCassandraTest; + import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; +import com.datastax.driver.core.UDTValue; +import com.datastax.driver.core.UserType; + +import net.helenus.core.Helenus; +import net.helenus.core.HelenusSession; +import net.helenus.core.Query; +import net.helenus.test.integration.build.AbstractEmbeddedCassandraTest; + public class UserDefinedTypeTest extends AbstractEmbeddedCassandraTest { - static Address address; - static Account account; + static Address address; + static Account account; - static HelenusSession session; + static HelenusSession session; - public static class AccountImpl implements Account { + @BeforeClass + public static void beforeTest() { + session = Helenus.init(getSession()).showCql().add(Account.class).autoCreateDrop().get(); + address = Helenus.dsl(Address.class); + account = Helenus.dsl(Account.class); + } - long id; - Address address; - UDTValue addressNoMapping; + @Test + public void testPrint() { + System.out.println(address); + System.out.println(account); + } - @Override - public long id() { - return id; - } + @Test + public void testMappingCRUID() throws TimeoutException { - @Override - public Address address() { - return address; - } + AddressImpl addr = new AddressImpl(); + addr.street = "1 st"; + addr.city = "San Jose"; - @Override - public UDTValue addressNoMapping() { - return addressNoMapping; - } - } + AccountImpl acc = new AccountImpl(); + acc.id = 123L; + acc.address = addr; - public static class AddressImpl implements Address { + // CREATE - String street; - String city; - int zip; - String country; - Set phones; + session.upsert(acc).sync(); - @Override - public String street() { - return street; - } + // READ - @Override - public String city() { - return city; - } + String streetName = session.select(account.address()::street).where(account::id, Query.eq(123L)).sync() + .findFirst().get()._1; - @Override - public int zip() { - return zip; - } + Assert.assertEquals("1 st", streetName); - @Override - public String country() { - return country; - } + // UPDATE - @Override - public Set phones() { - return phones; - } - } + AddressImpl expected = new AddressImpl(); + expected.street = "2 st"; + expected.city = "San Francisco"; - @BeforeClass - public static void beforeTest() { - session = Helenus.init(getSession()).showCql().add(Account.class).autoCreateDrop().get(); - address = Helenus.dsl(Address.class); - account = Helenus.dsl(Account.class); - } + session.update().set(account::address, expected).where(account::id, Query.eq(123L)).sync(); - @Test - public void testPrint() { - System.out.println(address); - System.out.println(account); - } + Address actual = session.select(account::address).where(account::id, Query.eq(123L)).sync().findFirst() + .get()._1; - @Test - public void testMappingCRUID() throws TimeoutException { + Assert.assertEquals(expected.street(), actual.street()); + Assert.assertEquals(expected.city(), actual.city()); + Assert.assertNull(actual.country()); + Assert.assertEquals(0, actual.zip()); - AddressImpl addr = new AddressImpl(); - addr.street = "1 st"; - addr.city = "San Jose"; + // INSERT using UPDATE + session.update().set(account::address, null).where(account::id, Query.eq(123L)).sync(); - AccountImpl acc = new AccountImpl(); - acc.id = 123L; - acc.address = addr; + Address adrNull = session.select(account::address).where(account::id, Query.eq(123L)).sync().findFirst() + .get()._1; + Assert.assertNull(adrNull); - // CREATE + // DELETE - session.upsert(acc).sync(); + session.delete().where(account::id, Query.eq(123L)).sync(); - // READ + Long cnt = session.count().where(account::id, Query.eq(123L)).sync(); + Assert.assertEquals(Long.valueOf(0), cnt); + } - String streetName = - session - .select(account.address()::street) - .where(account::id, Query.eq(123L)) - .sync() - .findFirst() - .get() - ._1; + @Test + public void testNoMapping() throws TimeoutException { - Assert.assertEquals("1 st", streetName); + String ks = getSession().getLoggedKeyspace(); + UserType addressType = getSession().getCluster().getMetadata().getKeyspace(ks).getUserType("address"); - // UPDATE + UDTValue addressNoMapping = addressType.newValue(); + addressNoMapping.setString("line_1", "1st street"); + addressNoMapping.setString("city", "San Jose"); - AddressImpl expected = new AddressImpl(); - expected.street = "2 st"; - expected.city = "San Francisco"; + AccountImpl acc = new AccountImpl(); + acc.id = 777L; + acc.addressNoMapping = addressNoMapping; - session.update().set(account::address, expected).where(account::id, Query.eq(123L)).sync(); + // CREATE - Address actual = - session - .select(account::address) - .where(account::id, Query.eq(123L)) - .sync() - .findFirst() - .get() - ._1; + session.upsert(acc).sync(); - Assert.assertEquals(expected.street(), actual.street()); - Assert.assertEquals(expected.city(), actual.city()); - Assert.assertNull(actual.country()); - Assert.assertEquals(0, actual.zip()); + // READ - // INSERT using UPDATE - session.update().set(account::address, null).where(account::id, Query.eq(123L)).sync(); + UDTValue found = session.select(account::addressNoMapping).where(account::id, Query.eq(777L)).sync().findFirst() + .get()._1; - Address adrNull = - session - .select(account::address) - .where(account::id, Query.eq(123L)) - .sync() - .findFirst() - .get() - ._1; - Assert.assertNull(adrNull); + Assert.assertEquals(addressNoMapping.getType(), found.getType()); + Assert.assertEquals(addressNoMapping.getString("line_1"), found.getString("line_1")); + Assert.assertEquals(addressNoMapping.getString("city"), found.getString("city")); - // DELETE + // UPDATE - session.delete().where(account::id, Query.eq(123L)).sync(); + addressNoMapping = addressType.newValue(); + addressNoMapping.setString("line_1", "Market street"); + addressNoMapping.setString("city", "San Francisco"); - Long cnt = session.count().where(account::id, Query.eq(123L)).sync(); - Assert.assertEquals(Long.valueOf(0), cnt); - } + session.update().set(account::addressNoMapping, addressNoMapping).where(account::id, Query.eq(777L)).sync(); - @Test - public void testNoMapping() throws TimeoutException { + found = session.select(account::addressNoMapping).where(account::id, Query.eq(777L)).sync().findFirst() + .get()._1; - String ks = getSession().getLoggedKeyspace(); - UserType addressType = - getSession().getCluster().getMetadata().getKeyspace(ks).getUserType("address"); + Assert.assertEquals(addressNoMapping.getType(), found.getType()); + Assert.assertEquals(addressNoMapping.getString("line_1"), found.getString("line_1")); + Assert.assertEquals(addressNoMapping.getString("city"), found.getString("city")); - UDTValue addressNoMapping = addressType.newValue(); - addressNoMapping.setString("line_1", "1st street"); - addressNoMapping.setString("city", "San Jose"); + // INSERT using UPDATE + session.update().set(account::addressNoMapping, null).where(account::id, Query.eq(777L)).sync(); - AccountImpl acc = new AccountImpl(); - acc.id = 777L; - acc.addressNoMapping = addressNoMapping; + found = session.select(account::addressNoMapping).where(account::id, Query.eq(777L)).sync().findFirst() + .get()._1; + Assert.assertNull(found); - // CREATE + // DELETE - session.upsert(acc).sync(); + session.delete().where(account::id, Query.eq(777L)).sync(); - // READ + Long cnt = session.count().where(account::id, Query.eq(777L)).sync(); + Assert.assertEquals(Long.valueOf(0), cnt); + } - UDTValue found = - session - .select(account::addressNoMapping) - .where(account::id, Query.eq(777L)) - .sync() - .findFirst() - .get() - ._1; + public static class AccountImpl implements Account { - Assert.assertEquals(addressNoMapping.getType(), found.getType()); - Assert.assertEquals(addressNoMapping.getString("line_1"), found.getString("line_1")); - Assert.assertEquals(addressNoMapping.getString("city"), found.getString("city")); + long id; + Address address; + UDTValue addressNoMapping; - // UPDATE + @Override + public long id() { + return id; + } - addressNoMapping = addressType.newValue(); - addressNoMapping.setString("line_1", "Market street"); - addressNoMapping.setString("city", "San Francisco"); + @Override + public Address address() { + return address; + } - session - .update() - .set(account::addressNoMapping, addressNoMapping) - .where(account::id, Query.eq(777L)) - .sync(); + @Override + public UDTValue addressNoMapping() { + return addressNoMapping; + } + } - found = - session - .select(account::addressNoMapping) - .where(account::id, Query.eq(777L)) - .sync() - .findFirst() - .get() - ._1; + public static class AddressImpl implements Address { - Assert.assertEquals(addressNoMapping.getType(), found.getType()); - Assert.assertEquals(addressNoMapping.getString("line_1"), found.getString("line_1")); - Assert.assertEquals(addressNoMapping.getString("city"), found.getString("city")); + String street; + String city; + int zip; + String country; + Set phones; - // INSERT using UPDATE - session.update().set(account::addressNoMapping, null).where(account::id, Query.eq(777L)).sync(); + @Override + public String street() { + return street; + } - found = - session - .select(account::addressNoMapping) - .where(account::id, Query.eq(777L)) - .sync() - .findFirst() - .get() - ._1; - Assert.assertNull(found); + @Override + public String city() { + return city; + } - // DELETE + @Override + public int zip() { + return zip; + } - session.delete().where(account::id, Query.eq(777L)).sync(); + @Override + public String country() { + return country; + } - Long cnt = session.count().where(account::id, Query.eq(777L)).sync(); - Assert.assertEquals(Long.valueOf(0), cnt); - } + @Override + public Set phones() { + return phones; + } + } } diff --git a/src/test/java/net/helenus/test/integration/core/views/Cyclist.java b/src/test/java/net/helenus/test/integration/core/views/Cyclist.java index 0ab5a73..2829a0c 100644 --- a/src/test/java/net/helenus/test/integration/core/views/Cyclist.java +++ b/src/test/java/net/helenus/test/integration/core/views/Cyclist.java @@ -2,28 +2,25 @@ package net.helenus.test.integration.core.views; import java.util.Date; import java.util.UUID; + import net.helenus.mapping.annotation.ClusteringColumn; import net.helenus.mapping.annotation.CoveringIndex; import net.helenus.mapping.annotation.PartitionKey; import net.helenus.mapping.annotation.Table; @Table -@CoveringIndex( - name = "cyclist_mv", - covering = {"age", "birthday", "country"}, - partitionKeys = {"age", "cid"}, - clusteringColumns = {} -) +@CoveringIndex(name = "cyclist_mv", covering = {"age", "birthday", "country"}, partitionKeys = {"age", + "cid"}, clusteringColumns = {}) public interface Cyclist { - @ClusteringColumn - UUID cid(); + @ClusteringColumn + UUID cid(); - String name(); + String name(); - @PartitionKey - int age(); + @PartitionKey + int age(); - Date birthday(); + Date birthday(); - String country(); + String country(); } diff --git a/src/test/java/net/helenus/test/integration/core/views/CyclistsByAge.java b/src/test/java/net/helenus/test/integration/core/views/CyclistsByAge.java index 555155f..0ce45bb 100644 --- a/src/test/java/net/helenus/test/integration/core/views/CyclistsByAge.java +++ b/src/test/java/net/helenus/test/integration/core/views/CyclistsByAge.java @@ -2,19 +2,23 @@ package net.helenus.test.integration.core.views; import java.util.Date; import java.util.UUID; + import net.helenus.mapping.OrderingDirection; -import net.helenus.mapping.annotation.*; +import net.helenus.mapping.annotation.ClusteringColumn; +import net.helenus.mapping.annotation.Index; +import net.helenus.mapping.annotation.MaterializedView; +import net.helenus.mapping.annotation.PartitionKey; @MaterializedView public interface CyclistsByAge extends Cyclist { - @PartitionKey - UUID cid(); + @PartitionKey + UUID cid(); - @ClusteringColumn(ordering = OrderingDirection.ASC) - int age(); + @ClusteringColumn(ordering = OrderingDirection.ASC) + int age(); - Date birthday(); + Date birthday(); - @Index - String country(); + @Index + String country(); } diff --git a/src/test/java/net/helenus/test/integration/core/views/MaterializedViewTest.java b/src/test/java/net/helenus/test/integration/core/views/MaterializedViewTest.java index a733c1e..7cbc247 100644 --- a/src/test/java/net/helenus/test/integration/core/views/MaterializedViewTest.java +++ b/src/test/java/net/helenus/test/integration/core/views/MaterializedViewTest.java @@ -19,13 +19,16 @@ import static net.helenus.core.Query.eq; import java.text.ParseException; import java.text.SimpleDateFormat; -import java.util.*; +import java.util.Date; +import java.util.UUID; import java.util.concurrent.TimeoutException; + +import org.junit.BeforeClass; +import org.junit.Test; + import net.helenus.core.Helenus; import net.helenus.core.HelenusSession; import net.helenus.test.integration.build.AbstractEmbeddedCassandraTest; -import org.junit.BeforeClass; -import org.junit.Test; // See: https://docs.datastax.com/en/cql/3.3/cql/cql_using/useCreateMV.html // https://docs.datastax.com/en/cql/3.3/cql/cql_reference/cqlCreateMaterializedView.html @@ -33,45 +36,35 @@ import org.junit.Test; // https://cassandra-zone.com/materialized-views/ public class MaterializedViewTest extends AbstractEmbeddedCassandraTest { - static Cyclist cyclist; - static HelenusSession session; + static Cyclist cyclist; + static HelenusSession session; - static Date dateFromString(String dateInString) { - SimpleDateFormat formatter = new SimpleDateFormat("dd-MMM-yyyy"); - try { - return formatter.parse(dateInString); - } catch (ParseException e) { - e.printStackTrace(); - } - return null; - } + static Date dateFromString(String dateInString) { + SimpleDateFormat formatter = new SimpleDateFormat("dd-MMM-yyyy"); + try { + return formatter.parse(dateInString); + } catch (ParseException e) { + e.printStackTrace(); + } + return null; + } - @BeforeClass - public static void beforeTest() { - session = - Helenus.init(getSession()) - .showCql() - .add(Cyclist.class) - .add(CyclistsByAge.class) - .autoCreateDrop() - .get(); - cyclist = session.dsl(Cyclist.class); + @BeforeClass + public static void beforeTest() { + session = Helenus.init(getSession()).showCql().add(Cyclist.class).add(CyclistsByAge.class).autoCreateDrop() + .get(); + cyclist = session.dsl(Cyclist.class); - //try { - session - .insert(cyclist) - .value(cyclist::cid, UUID.randomUUID()) - .value(cyclist::age, 18) - .value(cyclist::birthday, dateFromString("1997-02-08")) - .value(cyclist::country, "Netherlands") - .value(cyclist::name, "Pascal EENKHOORN") - .sync(); - //} catch (TimeoutException e) { - //} - } + // try { + session.insert(cyclist).value(cyclist::cid, UUID.randomUUID()).value(cyclist::age, 18) + .value(cyclist::birthday, dateFromString("1997-02-08")).value(cyclist::country, "Netherlands") + .value(cyclist::name, "Pascal EENKHOORN").sync(); + // } catch (TimeoutException e) { + // } + } - @Test - public void testMv() throws TimeoutException { - session.select(Cyclist.class).from(CyclistsByAge.class).where(cyclist::age, eq(18)).sync(); - } + @Test + public void testMv() throws TimeoutException { + session.select(Cyclist.class).from(CyclistsByAge.class).where(cyclist::age, eq(18)).sync(); + } } diff --git a/src/test/java/net/helenus/test/performance/core/dsl/CachedElevatorImpl.java b/src/test/java/net/helenus/test/performance/core/dsl/CachedElevatorImpl.java index ed797f7..0167259 100644 --- a/src/test/java/net/helenus/test/performance/core/dsl/CachedElevatorImpl.java +++ b/src/test/java/net/helenus/test/performance/core/dsl/CachedElevatorImpl.java @@ -16,74 +16,75 @@ package net.helenus.test.performance.core.dsl; import java.util.Map; + import net.helenus.core.reflect.MapExportable; public final class CachedElevatorImpl implements Elevator, MapExportable { - private final Map backingMap; + private final Map backingMap; - private int mask = 0; + private int mask = 0; - private int height; - private Double price; - private String name; + private int height; + private Double price; + private String name; - public CachedElevatorImpl(Map backingMap) { - this.backingMap = backingMap; - } + public CachedElevatorImpl(Map backingMap) { + this.backingMap = backingMap; + } - @Override - public int height() { + @Override + public int height() { - if ((mask & 1) == 0) { + if ((mask & 1) == 0) { - Object obj = backingMap.get("height"); - if (obj != null) { - height = ((Integer) obj).intValue(); - } + Object obj = backingMap.get("height"); + if (obj != null) { + height = ((Integer) obj).intValue(); + } - mask &= 1; - } - return height; - } + mask &= 1; + } + return height; + } - @Override - public Double price() { + @Override + public Double price() { - if ((mask & 2) == 0) { + if ((mask & 2) == 0) { - Object obj = backingMap.get("price"); - if (obj != null) { - price = (Double) obj; - } + Object obj = backingMap.get("price"); + if (obj != null) { + price = (Double) obj; + } - mask &= 2; - } - return price; - } + mask &= 2; + } + return price; + } - @Override - public String name() { + @Override + public String name() { - if ((mask & 4) == 0) { + if ((mask & 4) == 0) { - Object obj = backingMap.get("name"); - if (obj != null) { - name = (String) obj; - } + Object obj = backingMap.get("name"); + if (obj != null) { + name = (String) obj; + } - mask &= 4; - } - return name; - } + mask &= 4; + } + return name; + } - @Override - public Map toMap() { - return backingMap; - } + @Override + public Map toMap() { + return backingMap; + } - @Override - public String toString() { - return backingMap.toString(); - } + @Override + public String toString() { + return backingMap.toString(); + } } diff --git a/src/test/java/net/helenus/test/performance/core/dsl/Elevator.java b/src/test/java/net/helenus/test/performance/core/dsl/Elevator.java index 26707cd..bb91c59 100644 --- a/src/test/java/net/helenus/test/performance/core/dsl/Elevator.java +++ b/src/test/java/net/helenus/test/performance/core/dsl/Elevator.java @@ -17,9 +17,9 @@ package net.helenus.test.performance.core.dsl; public interface Elevator { - int height(); + int height(); - Double price(); + Double price(); - String name(); + String name(); } diff --git a/src/test/java/net/helenus/test/performance/core/dsl/ElevatorImpl.java b/src/test/java/net/helenus/test/performance/core/dsl/ElevatorImpl.java index 4eaa3d7..0e86dc9 100644 --- a/src/test/java/net/helenus/test/performance/core/dsl/ElevatorImpl.java +++ b/src/test/java/net/helenus/test/performance/core/dsl/ElevatorImpl.java @@ -16,50 +16,51 @@ package net.helenus.test.performance.core.dsl; import java.util.Map; + import net.helenus.core.reflect.MapExportable; public final class ElevatorImpl implements Elevator, MapExportable { - private final Map backingMap; + private final Map backingMap; - public ElevatorImpl(Map backingMap) { - this.backingMap = backingMap; - } + public ElevatorImpl(Map backingMap) { + this.backingMap = backingMap; + } - @Override - public int height() { - Object obj = backingMap.get("height"); - if (obj != null) { - return ((Integer) obj).intValue(); - } - return 0; - } + @Override + public int height() { + Object obj = backingMap.get("height"); + if (obj != null) { + return ((Integer) obj).intValue(); + } + return 0; + } - @Override - public Double price() { - Object obj = backingMap.get("price"); - if (obj != null) { - return (Double) obj; - } - return null; - } + @Override + public Double price() { + Object obj = backingMap.get("price"); + if (obj != null) { + return (Double) obj; + } + return null; + } - @Override - public String name() { - Object obj = backingMap.get("name"); - if (obj != null) { - return (String) obj; - } - return null; - } + @Override + public String name() { + Object obj = backingMap.get("name"); + if (obj != null) { + return (String) obj; + } + return null; + } - @Override - public Map toMap() { - return backingMap; - } + @Override + public Map toMap() { + return backingMap; + } - @Override - public String toString() { - return backingMap.toString(); - } + @Override + public String toString() { + return backingMap.toString(); + } } diff --git a/src/test/java/net/helenus/test/performance/core/dsl/MappingTest.java b/src/test/java/net/helenus/test/performance/core/dsl/MappingTest.java index 0f58c97..5e6bd7d 100644 --- a/src/test/java/net/helenus/test/performance/core/dsl/MappingTest.java +++ b/src/test/java/net/helenus/test/performance/core/dsl/MappingTest.java @@ -17,99 +17,101 @@ package net.helenus.test.performance.core.dsl; import java.util.HashMap; import java.util.Map; -import net.helenus.core.Helenus; + import org.junit.Test; +import net.helenus.core.Helenus; + public class MappingTest { - static Map fixture; + static Map fixture; - static { - fixture = new HashMap(); - fixture.put("height", Integer.valueOf(55)); - fixture.put("price", Double.valueOf(44.99)); - fixture.put("name", "first"); - } + static { + fixture = new HashMap(); + fixture.put("height", Integer.valueOf(55)); + fixture.put("price", Double.valueOf(44.99)); + fixture.put("name", "first"); + } - @Test - public void testReflectionConstructor() { + @Test + public void testReflectionConstructor() { - long t0 = System.currentTimeMillis(); + long t0 = System.currentTimeMillis(); - for (int i = 0; i != 100000; ++i) { - Helenus.map(Elevator.class, fixture); - } + for (int i = 0; i != 100000; ++i) { + Helenus.map(Elevator.class, fixture); + } - long t1 = System.currentTimeMillis() - t0; + long t1 = System.currentTimeMillis() - t0; - System.out.println("ReflectionConstructor = " + t1); - } + System.out.println("ReflectionConstructor = " + t1); + } - @Test - public void testReflectionAccess() { + @Test + public void testReflectionAccess() { - long t0 = System.currentTimeMillis(); + long t0 = System.currentTimeMillis(); - Elevator elevator = Helenus.map(Elevator.class, fixture); + Elevator elevator = Helenus.map(Elevator.class, fixture); - for (int i = 0; i != 100000; ++i) { - elevator.height(); - elevator.price(); - elevator.name(); - } + for (int i = 0; i != 100000; ++i) { + elevator.height(); + elevator.price(); + elevator.name(); + } - long t1 = System.currentTimeMillis() - t0; + long t1 = System.currentTimeMillis() - t0; - System.out.println("ReflectionAccess = " + t1); - } + System.out.println("ReflectionAccess = " + t1); + } - @Test - public void testJavaAccess() { + @Test + public void testJavaAccess() { - long t0 = System.currentTimeMillis(); + long t0 = System.currentTimeMillis(); - Elevator elevator = new ElevatorImpl(fixture); + Elevator elevator = new ElevatorImpl(fixture); - for (int i = 0; i != 100000; ++i) { - elevator.height(); - elevator.price(); - elevator.name(); - } + for (int i = 0; i != 100000; ++i) { + elevator.height(); + elevator.price(); + elevator.name(); + } - long t1 = System.currentTimeMillis() - t0; + long t1 = System.currentTimeMillis() - t0; - System.out.println("JavaAccess = " + t1); - } + System.out.println("JavaAccess = " + t1); + } - @Test - public void testJavaCachedAccess() { + @Test + public void testJavaCachedAccess() { - long t0 = System.currentTimeMillis(); + long t0 = System.currentTimeMillis(); - Elevator elevator = new CachedElevatorImpl(fixture); + Elevator elevator = new CachedElevatorImpl(fixture); - for (int i = 0; i != 100000; ++i) { - elevator.height(); - elevator.price(); - elevator.name(); - } + for (int i = 0; i != 100000; ++i) { + elevator.height(); + elevator.price(); + elevator.name(); + } - long t1 = System.currentTimeMillis() - t0; + long t1 = System.currentTimeMillis() - t0; - System.out.println("JavaCachedAccess = " + t1); - } + System.out.println("JavaCachedAccess = " + t1); + } - @Test - public void testJavaConstructor() { + @Test + public void testJavaConstructor() { - long t0 = System.currentTimeMillis(); + long t0 = System.currentTimeMillis(); - for (int i = 0; i != 100000; ++i) { - new ElevatorImpl(fixture); - } + for (int i = 0; i != 100000; ++i) { + new ElevatorImpl(fixture); + } - long t1 = System.currentTimeMillis() - t0; + long t1 = System.currentTimeMillis() - t0; - System.out.println("JavaConstructor = " + t1); - } + System.out.println("JavaConstructor = " + t1); + } } diff --git a/src/test/java/net/helenus/test/unit/core/dsl/Account.java b/src/test/java/net/helenus/test/unit/core/dsl/Account.java index 10fc9fd..62da359 100644 --- a/src/test/java/net/helenus/test/unit/core/dsl/Account.java +++ b/src/test/java/net/helenus/test/unit/core/dsl/Account.java @@ -18,42 +18,43 @@ package net.helenus.test.unit.core.dsl; import java.util.Date; import java.util.Map; import java.util.Set; + import net.helenus.core.reflect.Drafted; import net.helenus.mapping.annotation.*; @Table public interface Account { - @PartitionKey - Long id(); + @PartitionKey + Long id(); - @ClusteringColumn - Date time(); + @ClusteringColumn + Date time(); - @Index - @Column("is_active") - boolean active(); + @Index + @Column("is_active") + boolean active(); - @Transient - default Draft draft() { - return new Draft(); - } + @Transient + default Draft draft() { + return new Draft(); + } - class Draft implements Drafted { //TODO + class Draft implements Drafted { // TODO - @Override - public Set mutated() { - return null; - } + @Override + public Set mutated() { + return null; + } - @Override - public Object build() { - return null; - } + @Override + public Object build() { + return null; + } - @Override - public Map toMap() { - return null; - } - } + @Override + public Map toMap() { + return null; + } + } } diff --git a/src/test/java/net/helenus/test/unit/core/dsl/AccountWithCollections.java b/src/test/java/net/helenus/test/unit/core/dsl/AccountWithCollections.java index ce78d99..53f2e35 100644 --- a/src/test/java/net/helenus/test/unit/core/dsl/AccountWithCollections.java +++ b/src/test/java/net/helenus/test/unit/core/dsl/AccountWithCollections.java @@ -15,10 +15,12 @@ */ package net.helenus.test.unit.core.dsl; -import com.datastax.driver.core.DataType.Name; import java.util.List; import java.util.Map; import java.util.Set; + +import com.datastax.driver.core.DataType.Name; + import net.helenus.mapping.annotation.PartitionKey; import net.helenus.mapping.annotation.Table; import net.helenus.mapping.annotation.Types; @@ -26,15 +28,15 @@ import net.helenus.mapping.annotation.Types; @Table public interface AccountWithCollections { - @PartitionKey - long id(); + @PartitionKey + long id(); - @Types.Set(Name.TEXT) - Set aliases(); + @Types.Set(Name.TEXT) + Set aliases(); - @Types.List(Name.TEXT) - List name(); + @Types.List(Name.TEXT) + List name(); - @Types.Map(key = Name.TEXT, value = Name.TEXT) - Map properties(); + @Types.Map(key = Name.TEXT, value = Name.TEXT) + Map properties(); } diff --git a/src/test/java/net/helenus/test/unit/core/dsl/CollectionsDlsTest.java b/src/test/java/net/helenus/test/unit/core/dsl/CollectionsDlsTest.java index 14f2576..1cb9e4b 100644 --- a/src/test/java/net/helenus/test/unit/core/dsl/CollectionsDlsTest.java +++ b/src/test/java/net/helenus/test/unit/core/dsl/CollectionsDlsTest.java @@ -15,63 +15,64 @@ */ package net.helenus.test.unit.core.dsl; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; + import net.helenus.core.Getter; import net.helenus.core.Helenus; import net.helenus.core.Query; import net.helenus.core.reflect.HelenusPropertyNode; import net.helenus.support.DslPropertyException; -import org.junit.Assert; -import org.junit.BeforeClass; -import org.junit.Test; public class CollectionsDlsTest { - static AccountWithCollections account; + static AccountWithCollections account; - @BeforeClass - public static void beforeTests() { - account = Helenus.dsl(AccountWithCollections.class); - } + @BeforeClass + public static void beforeTests() { + account = Helenus.dsl(AccountWithCollections.class); + } - @Test - public void testPrint() { - System.out.println(account); - } + @Test + public void testPrint() { + System.out.println(account); + } - @Test - public void testMapGet() { + @Test + public void testMapGet() { - String columnName = null; + String columnName = null; - Getter getter = Query.get(account::properties, "key1"); + Getter getter = Query.get(account::properties, "key1"); - try { - getter.get(); - } catch (DslPropertyException e) { + try { + getter.get(); + } catch (DslPropertyException e) { - HelenusPropertyNode node = e.getPropertyNode(); - columnName = node.getColumnName(); - } + HelenusPropertyNode node = e.getPropertyNode(); + columnName = node.getColumnName(); + } - Assert.assertEquals("\"properties\"[\"key1\"]", columnName); - } + Assert.assertEquals("\"properties\"[\"key1\"]", columnName); + } - @Test - public void testListGet() { + @Test + public void testListGet() { - String columnName = null; + String columnName = null; - Getter getter = Query.getIdx(account::name, 2); + Getter getter = Query.getIdx(account::name, 2); - try { - getter.get(); - } catch (DslPropertyException e) { + try { + getter.get(); + } catch (DslPropertyException e) { - HelenusPropertyNode node = e.getPropertyNode(); + HelenusPropertyNode node = e.getPropertyNode(); - columnName = node.getColumnName(); - } + columnName = node.getColumnName(); + } - Assert.assertEquals("\"name\"[\"2\"]", columnName); - } + Assert.assertEquals("\"name\"[\"2\"]", columnName); + } } diff --git a/src/test/java/net/helenus/test/unit/core/dsl/DslTest.java b/src/test/java/net/helenus/test/unit/core/dsl/DslTest.java index ca9ecae..a151bb4 100644 --- a/src/test/java/net/helenus/test/unit/core/dsl/DslTest.java +++ b/src/test/java/net/helenus/test/unit/core/dsl/DslTest.java @@ -15,27 +15,28 @@ */ package net.helenus.test.unit.core.dsl; -import net.helenus.core.Helenus; -import net.helenus.support.DslPropertyException; import org.junit.BeforeClass; import org.junit.Test; +import net.helenus.core.Helenus; +import net.helenus.support.DslPropertyException; + public class DslTest { - static Account account; + static Account account; - @BeforeClass - public static void beforeTests() { - account = Helenus.dsl(Account.class); - } + @BeforeClass + public static void beforeTests() { + account = Helenus.dsl(Account.class); + } - @Test - public void testToString() throws Exception { - System.out.println(account); - } + @Test + public void testToString() throws Exception { + System.out.println(account); + } - @Test(expected = DslPropertyException.class) - public void test() throws Exception { - account.id(); - } + @Test(expected = DslPropertyException.class) + public void test() throws Exception { + account.id(); + } } diff --git a/src/test/java/net/helenus/test/unit/core/dsl/Rocket.java b/src/test/java/net/helenus/test/unit/core/dsl/Rocket.java index dcd9a43..e0e44c0 100644 --- a/src/test/java/net/helenus/test/unit/core/dsl/Rocket.java +++ b/src/test/java/net/helenus/test/unit/core/dsl/Rocket.java @@ -5,7 +5,7 @@ import net.helenus.mapping.annotation.UDT; @UDT public interface Rocket { - int length(); + int length(); - double price(); + double price(); } diff --git a/src/test/java/net/helenus/test/unit/core/dsl/UDTCollectionsDlsTest.java b/src/test/java/net/helenus/test/unit/core/dsl/UDTCollectionsDlsTest.java index 4beccef..65ee050 100644 --- a/src/test/java/net/helenus/test/unit/core/dsl/UDTCollectionsDlsTest.java +++ b/src/test/java/net/helenus/test/unit/core/dsl/UDTCollectionsDlsTest.java @@ -17,40 +17,42 @@ package net.helenus.test.unit.core.dsl; import java.util.HashMap; import java.util.Map; -import net.helenus.core.Helenus; + import org.junit.Assert; import org.junit.Test; +import net.helenus.core.Helenus; + public class UDTCollectionsDlsTest { - @Test - public void testMap() { + @Test + public void testMap() { - Map comments = new HashMap(); + Map comments = new HashMap(); - Map firstMap = new HashMap(); - firstMap.put("length", 100); - firstMap.put("price", 100.0); + Map firstMap = new HashMap(); + firstMap.put("length", 100); + firstMap.put("price", 100.0); - Rocket first = Helenus.map(Rocket.class, firstMap); + Rocket first = Helenus.map(Rocket.class, firstMap); - Map secondMap = new HashMap(); - secondMap.put("length", 50); - secondMap.put("price", 70.0); + Map secondMap = new HashMap(); + secondMap.put("length", 50); + secondMap.put("price", 70.0); - Rocket second = Helenus.map(Rocket.class, secondMap); + Rocket second = Helenus.map(Rocket.class, secondMap); - Assert.assertEquals(first.hashCode(), first.hashCode()); - Assert.assertEquals(second.hashCode(), second.hashCode()); + Assert.assertEquals(first.hashCode(), first.hashCode()); + Assert.assertEquals(second.hashCode(), second.hashCode()); - Assert.assertFalse(first.equals(second)); - Assert.assertTrue(first.equals(first)); - Assert.assertTrue(second.equals(second)); + Assert.assertFalse(first.equals(second)); + Assert.assertTrue(first.equals(first)); + Assert.assertTrue(second.equals(second)); - comments.put(first, "fast"); - comments.put(second, "nice"); + comments.put(first, "fast"); + comments.put(second, "nice"); - Assert.assertEquals("fast", comments.get(first)); - Assert.assertEquals("nice", comments.get(second)); - } + Assert.assertEquals("fast", comments.get(first)); + Assert.assertEquals("nice", comments.get(second)); + } } diff --git a/src/test/java/net/helenus/test/unit/core/dsl/WrapperTest.java b/src/test/java/net/helenus/test/unit/core/dsl/WrapperTest.java index 321e01c..74ac6e7 100644 --- a/src/test/java/net/helenus/test/unit/core/dsl/WrapperTest.java +++ b/src/test/java/net/helenus/test/unit/core/dsl/WrapperTest.java @@ -17,51 +17,57 @@ package net.helenus.test.unit.core.dsl; import java.util.HashMap; import java.util.Map; -import net.helenus.core.Helenus; -import net.helenus.support.HelenusException; + import org.junit.Assert; import org.junit.Test; +import net.helenus.core.Helenus; +import net.helenus.support.HelenusException; + public class WrapperTest { - @Test - public void testWrap() throws Exception { + @Test + public void testWrap() throws Exception { - Map map = new HashMap(); + Map map = new HashMap(); - map.put("id", 123L); - map.put("active", Boolean.TRUE); - map.put("unknownField", "he-he"); + map.put("id", 123L); + map.put("active", Boolean.TRUE); + map.put("unknownField", "he-he"); - Account account = Helenus.map(Account.class, map); + Account account = Helenus.map(Account.class, map); - Assert.assertEquals(Long.valueOf(123L), account.id()); - Assert.assertTrue(account.active()); - } + Assert.assertEquals(Long.valueOf(123L), account.id()); + Assert.assertTrue(account.active()); + } - @Test - public void testPrimitive() throws Exception { + @Test + public void testPrimitive() throws Exception { - // NOTE: noramlly a ValueProviderMap for the entity would include all keys for an entity - // at creation time. This test need to validate that MapperInvocationHander will return - // the correct default value for an entity, the twist is that if the key doesn't exist - // in the map then it returns null (so as to support the partial update feature). Here we - // need to setup the test with a null value for the key we'd like to test. - Map map = new HashMap(); + // NOTE: noramlly a ValueProviderMap for the entity would include all keys for + // an entity + // at creation time. This test need to validate that MapperInvocationHander will + // return + // the correct default value for an entity, the twist is that if the key doesn't + // exist + // in the map then it returns null (so as to support the partial update + // feature). Here we + // need to setup the test with a null value for the key we'd like to test. + Map map = new HashMap(); - map.put("id", 123L); - map.put("active", null); + map.put("id", 123L); + map.put("active", null); - Account account = Helenus.map(Account.class, map); + Account account = Helenus.map(Account.class, map); - Assert.assertFalse(account.active()); - } + Assert.assertFalse(account.active()); + } - @Test(expected = HelenusException.class) - public void testWrongMethods() throws Exception { + @Test(expected = HelenusException.class) + public void testWrongMethods() throws Exception { - WrongAccount wrongAccount = Helenus.map(WrongAccount.class, new HashMap()); + WrongAccount wrongAccount = Helenus.map(WrongAccount.class, new HashMap()); - wrongAccount.id(); - } + wrongAccount.id(); + } } diff --git a/src/test/java/net/helenus/test/unit/core/dsl/WrongAccount.java b/src/test/java/net/helenus/test/unit/core/dsl/WrongAccount.java index 77f6971..b7cd833 100644 --- a/src/test/java/net/helenus/test/unit/core/dsl/WrongAccount.java +++ b/src/test/java/net/helenus/test/unit/core/dsl/WrongAccount.java @@ -17,5 +17,5 @@ package net.helenus.test.unit.core.dsl; public interface WrongAccount { - void id(); + void id(); } diff --git a/src/test/java/net/helenus/test/unit/support/ImmutablesTest.java b/src/test/java/net/helenus/test/unit/support/ImmutablesTest.java index c7cd5a4..ee29193 100644 --- a/src/test/java/net/helenus/test/unit/support/ImmutablesTest.java +++ b/src/test/java/net/helenus/test/unit/support/ImmutablesTest.java @@ -18,86 +18,88 @@ package net.helenus.test.unit.support; import java.util.List; import java.util.Map; import java.util.Set; -import net.helenus.support.Immutables; + import org.junit.Assert; import org.junit.Test; +import net.helenus.support.Immutables; + public class ImmutablesTest { - @Test - public void testSet() { + @Test + public void testSet() { - Set set = Immutables.setOf(123); + Set set = Immutables.setOf(123); - Assert.assertEquals(1, set.size()); - Assert.assertFalse(set.isEmpty()); + Assert.assertEquals(1, set.size()); + Assert.assertFalse(set.isEmpty()); - Assert.assertTrue(set.contains(123)); - Assert.assertFalse(set.contains(125)); + Assert.assertTrue(set.contains(123)); + Assert.assertFalse(set.contains(125)); - int c = 0; - for (Integer v : set) { - Assert.assertEquals(Integer.valueOf(123), v); - c++; - } + int c = 0; + for (Integer v : set) { + Assert.assertEquals(Integer.valueOf(123), v); + c++; + } - Assert.assertEquals(1, c); - } + Assert.assertEquals(1, c); + } - @Test - public void testList() { + @Test + public void testList() { - List list = Immutables.listOf(123); + List list = Immutables.listOf(123); - Assert.assertEquals(1, list.size()); - Assert.assertFalse(list.isEmpty()); + Assert.assertEquals(1, list.size()); + Assert.assertFalse(list.isEmpty()); - Assert.assertTrue(list.contains(123)); - Assert.assertFalse(list.contains(125)); + Assert.assertTrue(list.contains(123)); + Assert.assertFalse(list.contains(125)); - int c = 0; - for (Integer v : list) { - Assert.assertEquals(Integer.valueOf(123), v); - c++; - } + int c = 0; + for (Integer v : list) { + Assert.assertEquals(Integer.valueOf(123), v); + c++; + } - Assert.assertEquals(1, c); - } + Assert.assertEquals(1, c); + } - @Test - public void testMap() { + @Test + public void testMap() { - Map map = Immutables.mapOf(123, 555); + Map map = Immutables.mapOf(123, 555); - Assert.assertEquals(1, map.size()); - Assert.assertFalse(map.isEmpty()); + Assert.assertEquals(1, map.size()); + Assert.assertFalse(map.isEmpty()); - Assert.assertTrue(map.containsKey(123)); - Assert.assertFalse(map.containsKey(125)); + Assert.assertTrue(map.containsKey(123)); + Assert.assertFalse(map.containsKey(125)); - int c = 0; - for (Integer v : map.keySet()) { - Assert.assertEquals(Integer.valueOf(123), v); - c++; - } + int c = 0; + for (Integer v : map.keySet()) { + Assert.assertEquals(Integer.valueOf(123), v); + c++; + } - Assert.assertEquals(1, c); + Assert.assertEquals(1, c); - c = 0; - for (Integer v : map.values()) { - Assert.assertEquals(Integer.valueOf(555), v); - c++; - } + c = 0; + for (Integer v : map.values()) { + Assert.assertEquals(Integer.valueOf(555), v); + c++; + } - Assert.assertEquals(1, c); + Assert.assertEquals(1, c); - c = 0; - for (Map.Entry e : map.entrySet()) { - Assert.assertEquals(Integer.valueOf(123), e.getKey()); - Assert.assertEquals(Integer.valueOf(555), e.getValue()); - c++; - } + c = 0; + for (Map.Entry e : map.entrySet()) { + Assert.assertEquals(Integer.valueOf(123), e.getKey()); + Assert.assertEquals(Integer.valueOf(555), e.getValue()); + c++; + } - Assert.assertEquals(1, c); - } + Assert.assertEquals(1, c); + } } diff --git a/src/test/java/net/helenus/test/unit/support/TransformersTest.java b/src/test/java/net/helenus/test/unit/support/TransformersTest.java index fd787f9..7f0868a 100644 --- a/src/test/java/net/helenus/test/unit/support/TransformersTest.java +++ b/src/test/java/net/helenus/test/unit/support/TransformersTest.java @@ -19,66 +19,68 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.ListIterator; -import net.helenus.support.Transformers; + import org.junit.Assert; import org.junit.Test; +import net.helenus.support.Transformers; + public class TransformersTest { - @Test - public void testList() { + @Test + public void testList() { - List source = new ArrayList(); - source.add(555); - source.add(777); - source.add(999); + List source = new ArrayList(); + source.add(555); + source.add(777); + source.add(999); - List out = Transformers.transformList(source, x -> "_" + x); + List out = Transformers.transformList(source, x -> "_" + x); - Assert.assertEquals(3, out.size()); - Assert.assertEquals(false, out.isEmpty()); - Assert.assertEquals("_555", out.get(0)); - Assert.assertEquals("_777", out.get(1)); - Assert.assertEquals("_999", out.get(2)); + Assert.assertEquals(3, out.size()); + Assert.assertEquals(false, out.isEmpty()); + Assert.assertEquals("_555", out.get(0)); + Assert.assertEquals("_777", out.get(1)); + Assert.assertEquals("_999", out.get(2)); - Iterator i = out.iterator(); - Assert.assertTrue(i.hasNext()); - Assert.assertEquals("_555", i.next()); - Assert.assertTrue(i.hasNext()); - Assert.assertEquals("_777", i.next()); - Assert.assertTrue(i.hasNext()); - Assert.assertEquals("_999", i.next()); - Assert.assertFalse(i.hasNext()); + Iterator i = out.iterator(); + Assert.assertTrue(i.hasNext()); + Assert.assertEquals("_555", i.next()); + Assert.assertTrue(i.hasNext()); + Assert.assertEquals("_777", i.next()); + Assert.assertTrue(i.hasNext()); + Assert.assertEquals("_999", i.next()); + Assert.assertFalse(i.hasNext()); - ListIterator li = out.listIterator(); - Assert.assertTrue(li.hasNext()); - Assert.assertEquals(0, li.nextIndex()); - Assert.assertEquals(-1, li.previousIndex()); - Assert.assertEquals("_555", li.next()); - Assert.assertTrue(li.hasNext()); - Assert.assertEquals(1, li.nextIndex()); - Assert.assertEquals(0, li.previousIndex()); - Assert.assertEquals("_777", li.next()); - Assert.assertTrue(li.hasNext()); - Assert.assertEquals(2, li.nextIndex()); - Assert.assertEquals(1, li.previousIndex()); - Assert.assertEquals("_999", li.next()); - Assert.assertFalse(li.hasNext()); - Assert.assertEquals(3, li.nextIndex()); - Assert.assertEquals(2, li.previousIndex()); - } + ListIterator li = out.listIterator(); + Assert.assertTrue(li.hasNext()); + Assert.assertEquals(0, li.nextIndex()); + Assert.assertEquals(-1, li.previousIndex()); + Assert.assertEquals("_555", li.next()); + Assert.assertTrue(li.hasNext()); + Assert.assertEquals(1, li.nextIndex()); + Assert.assertEquals(0, li.previousIndex()); + Assert.assertEquals("_777", li.next()); + Assert.assertTrue(li.hasNext()); + Assert.assertEquals(2, li.nextIndex()); + Assert.assertEquals(1, li.previousIndex()); + Assert.assertEquals("_999", li.next()); + Assert.assertFalse(li.hasNext()); + Assert.assertEquals(3, li.nextIndex()); + Assert.assertEquals(2, li.previousIndex()); + } - @Test - public void testNullsInList() { + @Test + public void testNullsInList() { - List source = new ArrayList(); - source.add(555); - source.add(null); - source.add(999); + List source = new ArrayList(); + source.add(555); + source.add(null); + source.add(999); - List out = Transformers.transformList(source, x -> "_" + x); + List out = Transformers.transformList(source, x -> "_" + x); - Assert.assertEquals(3, out.size()); - Assert.assertEquals("_null", out.get(1)); - } + Assert.assertEquals(3, out.size()); + Assert.assertEquals("_null", out.get(1)); + } } diff --git a/src/test/resources/log4j-embedded-cassandra.properties b/src/test/resources/log4j-embedded-cassandra.properties index 1571670..7e6e5b3 100644 --- a/src/test/resources/log4j-embedded-cassandra.properties +++ b/src/test/resources/log4j-embedded-cassandra.properties @@ -13,18 +13,14 @@ # 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. - # for production, you should probably set the root to INFO # and the pattern to %c instead of %l. (%l is slower.) - # output messages into a rolling log file as well as stdout log4j.rootLogger=ERROR,stdout - # stdout log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d [%t] %-5p %c{3} - %m%n log4j.appender.stdout.follow=true - log4j.logger.org.apache=WARN -log4j.logger.org.cassandraunit=ERROR \ No newline at end of file +log4j.logger.org.cassandraunit=ERROR diff --git a/src/test/resources/logging.properties b/src/test/resources/logging.properties index 2f5ec24..3642483 100644 --- a/src/test/resources/logging.properties +++ b/src/test/resources/logging.properties @@ -1 +1 @@ -handlers = org.slf4j.bridge.SLF4JBridgeHandler \ No newline at end of file +handlers=org.slf4j.bridge.SLF4JBridgeHandler From e5918cd1e8f164247ecb0f9b49abcbc9e9e4ed05 Mon Sep 17 00:00:00 2001 From: Greg Burd Date: Wed, 25 Oct 2017 20:53:58 -0400 Subject: [PATCH 08/18] Formatting. --- .../core/AbstractSessionOperations.java | 20 +-- .../net/helenus/core/AbstractUnitOfWork.java | 129 +++++++++--------- .../java/net/helenus/core/HelenusSession.java | 93 +++++++------ .../operation/AbstractOptionalOperation.java | 84 ++++++------ .../operation/AbstractStreamOperation.java | 88 ++++++------ .../core/operation/DeleteOperation.java | 16 +-- .../net/helenus/core/operation/Operation.java | 79 ++++++----- .../core/operation/SelectOperation.java | 3 +- .../core/reflect/DslInvocationHandler.java | 43 +++--- 9 files changed, 274 insertions(+), 281 deletions(-) diff --git a/src/main/java/net/helenus/core/AbstractSessionOperations.java b/src/main/java/net/helenus/core/AbstractSessionOperations.java index 80c3fbf..3f8eba2 100644 --- a/src/main/java/net/helenus/core/AbstractSessionOperations.java +++ b/src/main/java/net/helenus/core/AbstractSessionOperations.java @@ -17,10 +17,8 @@ package net.helenus.core; import java.io.PrintStream; import java.util.List; -import java.util.Set; import java.util.concurrent.Executor; -import net.helenus.support.Either; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -35,6 +33,7 @@ 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; import net.helenus.support.HelenusException; public abstract class AbstractSessionOperations { @@ -116,13 +115,13 @@ public abstract class AbstractSessionOperations { } } - private void logStatement(Statement statement, boolean showValues) { - if (isShowCql()) { - printCql(Operation.queryString(statement, showValues)); - } else if (LOG.isInfoEnabled()) { - LOG.info("CQL> " + Operation.queryString(statement, showValues)); - } - } + private void logStatement(Statement statement, boolean showValues) { + if (isShowCql()) { + printCql(Operation.queryString(statement, showValues)); + } else if (LOG.isInfoEnabled()) { + LOG.info("CQL> " + Operation.queryString(statement, showValues)); + } + } public Tracer getZipkinTracer() { return null; @@ -132,7 +131,8 @@ public abstract class AbstractSessionOperations { return null; } - public void mergeCache(Table>> uowCache) { } + public void mergeCache(Table>> uowCache) { + } RuntimeException translateException(RuntimeException e) { if (e instanceof HelenusException) { diff --git a/src/main/java/net/helenus/core/AbstractUnitOfWork.java b/src/main/java/net/helenus/core/AbstractUnitOfWork.java index 3690bf5..c2d7013 100644 --- a/src/main/java/net/helenus/core/AbstractUnitOfWork.java +++ b/src/main/java/net/helenus/core/AbstractUnitOfWork.java @@ -15,14 +15,12 @@ */ package net.helenus.core; +import static net.helenus.core.HelenusSession.deleted; + import java.util.*; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; -import net.helenus.core.cache.UnboundFacet; -import net.helenus.core.reflect.HelenusNamedProperty; -import net.helenus.mapping.HelenusProperty; -import net.helenus.support.Either; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -34,8 +32,7 @@ import com.google.common.collect.TreeTraverser; import net.helenus.core.cache.CacheUtil; import net.helenus.core.cache.Facet; - -import static net.helenus.core.HelenusSession.deleted; +import net.helenus.support.Either; /** Encapsulates the concept of a "transaction" as a unit-of-work. */ public abstract class AbstractUnitOfWork implements UnitOfWork, AutoCloseable { @@ -45,11 +42,7 @@ public abstract class AbstractUnitOfWork implements UnitOfW private final List> nested = new ArrayList<>(); private final HelenusSession session; private final AbstractUnitOfWork parent; - private List postCommit = new ArrayList(); - private boolean aborted = false; - private boolean committed = false; - - private final Table>> cache = HashBasedTable.create(); + private final Table>> cache = HashBasedTable.create(); protected String purpose; protected int cacheHits = 0; protected int cacheMisses = 0; @@ -57,6 +50,9 @@ public abstract class AbstractUnitOfWork implements UnitOfW protected Stopwatch elapsedTime; protected Map databaseTime = new HashMap<>(); protected double cacheLookupTime = 0.0; + private List postCommit = new ArrayList(); + private boolean aborted = false; + private boolean committed = false; protected AbstractUnitOfWork(HelenusSession session, AbstractUnitOfWork parent) { Objects.requireNonNull(session, "containing session cannot be null"); @@ -168,10 +164,10 @@ public abstract class AbstractUnitOfWork implements UnitOfW String columnName = facet.name() + "==" + facet.value(); Either> eitherValue = cache.get(tableName, columnName); if (eitherValue != null) { - Object value = deleted; - if (eitherValue.isLeft()) { - value = eitherValue.getLeft(); - } + Object value = deleted; + if (eitherValue.isLeft()) { + value = eitherValue.getLeft(); + } result = Optional.of(value); break; } @@ -188,44 +184,44 @@ public abstract class AbstractUnitOfWork implements UnitOfW @Override public List cacheEvict(List facets) { - Either> deletedObjectFacets = Either.right(facets); + Either> deletedObjectFacets = Either.right(facets); String tableName = CacheUtil.schemaName(facets); Optional optionalValue = cacheLookup(facets); if (optionalValue.isPresent()) { - Object value = optionalValue.get(); + Object value = optionalValue.get(); - for (Facet facet : facets) { - if (!facet.fixed()) { - String columnKey = facet.name() + "==" + facet.value(); - // mark the value identified by the facet to `deleted` - cache.put(tableName, columnKey, deletedObjectFacets); - } - } - // look for other row/col pairs that referenced the same object, mark them - // `deleted` - cache.columnKeySet().forEach(columnKey -> { - Either> eitherCachedValue = cache.get(tableName, columnKey); - if (eitherCachedValue.isLeft()) { - Object cachedValue = eitherCachedValue.getLeft(); - if (cachedValue == value) { - cache.put(tableName, columnKey, deletedObjectFacets); - String[] parts = columnKey.split("=="); - facets.add(new Facet(parts[0], parts[1])); - } - } - }); - } - return facets; + for (Facet facet : facets) { + if (!facet.fixed()) { + String columnKey = facet.name() + "==" + facet.value(); + // mark the value identified by the facet to `deleted` + cache.put(tableName, columnKey, deletedObjectFacets); + } + } + // look for other row/col pairs that referenced the same object, mark them + // `deleted` + cache.columnKeySet().forEach(columnKey -> { + Either> eitherCachedValue = cache.get(tableName, columnKey); + if (eitherCachedValue.isLeft()) { + Object cachedValue = eitherCachedValue.getLeft(); + if (cachedValue == value) { + cache.put(tableName, columnKey, deletedObjectFacets); + String[] parts = columnKey.split("=="); + facets.add(new Facet(parts[0], parts[1])); + } + } + }); + } + return facets; } @Override public void cacheUpdate(Object value, List facets) { String tableName = CacheUtil.schemaName(facets); for (Facet facet : facets) { - if (!facet.fixed()) { - String columnName = facet.name() + "==" + facet.value(); - cache.put(tableName, columnName, Either.left(value)); - } + if (!facet.fixed()) { + String columnName = facet.name() + "==" + facet.value(); + cache.put(tableName, columnName, Either.left(value)); + } } } @@ -265,42 +261,42 @@ public abstract class AbstractUnitOfWork implements UnitOfW aborted = false; nested.forEach((uow) -> Errors.rethrow().wrap(uow::commit)); - elapsedTime.stop(); + elapsedTime.stop(); if (parent == null) { - // Apply all post-commit functions, this is the outter-most UnitOfWork. + // Apply all post-commit functions, this is the outter-most UnitOfWork. traverser.postOrderTraversal(this).forEach(uow -> { uow.applyPostCommitFunctions(); }); // Merge our cache into the session cache. - session.mergeCache(cache); + session.mergeCache(cache); - return new PostCommitFunction(this, null); + return new PostCommitFunction(this, null); } else { - // Merge cache and statistics into parent if there is one. - parent.mergeCache(cache); + // Merge cache and statistics into parent if there is one. + parent.mergeCache(cache); - parent.cacheHits += cacheHits; - parent.cacheMisses += cacheMisses; - parent.databaseLookups += databaseLookups; - parent.cacheLookupTime += cacheLookupTime; - for (String name : databaseTime.keySet()) { - if (parent.databaseTime.containsKey(name)) { - double t = parent.databaseTime.get(name); - parent.databaseTime.put(name, t + databaseTime.get(name)); - } else { - parent.databaseTime.put(name, databaseTime.get(name)); - } - } - } - } + parent.cacheHits += cacheHits; + parent.cacheMisses += cacheMisses; + parent.databaseLookups += databaseLookups; + parent.cacheLookupTime += cacheLookupTime; + for (String name : databaseTime.keySet()) { + if (parent.databaseTime.containsKey(name)) { + double t = parent.databaseTime.get(name); + parent.databaseTime.put(name, t + databaseTime.get(name)); + } else { + parent.databaseTime.put(name, databaseTime.get(name)); + } + } + } + } // else { // Constructor ctor = clazz.getConstructor(conflictExceptionClass); // T object = ctor.newInstance(new Object[] { String message }); // } - return new PostCommitFunction(this, postCommit); + return new PostCommitFunction(this, postCommit); } /* Explicitly discard the work and mark it as as such in the log. */ @@ -325,8 +321,9 @@ public abstract class AbstractUnitOfWork implements UnitOfW from.rowMap().forEach((rowKey, columnMap) -> { columnMap.forEach((columnKey, value) -> { if (to.contains(rowKey, columnKey)) { - //TODO(gburd):... - to.put(rowKey, columnKey, Either.left(CacheUtil.merge(to.get(rowKey, columnKey).getLeft(), from.get(rowKey, columnKey).getLeft()))); + // TODO(gburd):... + to.put(rowKey, columnKey, Either.left(CacheUtil.merge(to.get(rowKey, columnKey).getLeft(), + from.get(rowKey, columnKey).getLeft()))); } else { to.put(rowKey, columnKey, from.get(rowKey, columnKey)); } diff --git a/src/main/java/net/helenus/core/HelenusSession.java b/src/main/java/net/helenus/core/HelenusSession.java index e169a86..58549ad 100644 --- a/src/main/java/net/helenus/core/HelenusSession.java +++ b/src/main/java/net/helenus/core/HelenusSession.java @@ -27,7 +27,6 @@ import java.util.concurrent.TimeUnit; import java.util.function.Function; import java.util.stream.Collectors; -import net.helenus.support.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -49,15 +48,15 @@ import net.helenus.mapping.HelenusEntity; import net.helenus.mapping.HelenusProperty; import net.helenus.mapping.MappingUtil; import net.helenus.mapping.value.*; +import net.helenus.support.*; import net.helenus.support.Fun.Tuple1; import net.helenus.support.Fun.Tuple2; import net.helenus.support.Fun.Tuple6; public final class HelenusSession extends AbstractSessionOperations implements Closeable { + public static final Object deleted = new Object(); private static final Logger LOG = LoggerFactory.getLogger(HelenusSession.class); - public static final Object deleted = new Object(); - private final int MAX_CACHE_SIZE = 10000; private final int MAX_CACHE_EXPIRE_SECONDS = 600; @@ -234,62 +233,62 @@ public final class HelenusSession extends AbstractSessionOperations implements C boundFacets.add(facet); } } - String tableName = CacheUtil.schemaName(facets); - List facetCombinations = CacheUtil.flattenFacets(boundFacets); + String tableName = CacheUtil.schemaName(facets); + List facetCombinations = CacheUtil.flattenFacets(boundFacets); mergeAndUpdateCacheValues(pojo, tableName, facetCombinations); } @Override - public void mergeCache(Table>> uowCache) { + public void mergeCache(Table>> uowCache) { List>> items = uowCache.values().stream().distinct().collect(Collectors.toList()); for (Either> item : items) { - if (item.isRight()) { - List facets = item.getRight(); - String tableName = CacheUtil.schemaName(facets); - List combinations = CacheUtil.flattenFacets(facets); - for (String[] combination : combinations) { - String cacheKey = tableName + "." + Arrays.toString(combination); - sessionCache.invalidate(cacheKey); - } - } else { - Object pojo = item.getLeft(); - HelenusEntity entity = Helenus.resolve(MappingUtil.getMappingInterface(pojo)); - Map valueMap = pojo instanceof MapExportable ? ((MapExportable) pojo).toMap() : null; - if (entity.isCacheable()) { - List boundFacets = new ArrayList<>(); - for (Facet facet : entity.getFacets()) { - if (facet instanceof UnboundFacet) { - UnboundFacet unboundFacet = (UnboundFacet) facet; - UnboundFacet.Binder binder = unboundFacet.binder(); - unboundFacet.getProperties().forEach(prop -> { - if (valueMap == null) { - Object value = BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop, - false); - binder.setValueForProperty(prop, value.toString()); - } else { - binder.setValueForProperty(prop, valueMap.get(prop.getPropertyName()).toString()); - } - }); - if (binder.isBound()) { - boundFacets.add(binder.bind()); - } - } else { - boundFacets.add(facet); - } - } - // NOTE: should equal `String tableName = CacheUtil.schemaName(facets);` - List facetCombinations = CacheUtil.flattenFacets(boundFacets); - String tableName = CacheUtil.schemaName(boundFacets); - mergeAndUpdateCacheValues(pojo, tableName, facetCombinations); - } - } + if (item.isRight()) { + List facets = item.getRight(); + String tableName = CacheUtil.schemaName(facets); + List combinations = CacheUtil.flattenFacets(facets); + for (String[] combination : combinations) { + String cacheKey = tableName + "." + Arrays.toString(combination); + sessionCache.invalidate(cacheKey); + } + } else { + Object pojo = item.getLeft(); + HelenusEntity entity = Helenus.resolve(MappingUtil.getMappingInterface(pojo)); + Map valueMap = pojo instanceof MapExportable ? ((MapExportable) pojo).toMap() : null; + if (entity.isCacheable()) { + List boundFacets = new ArrayList<>(); + for (Facet facet : entity.getFacets()) { + if (facet instanceof UnboundFacet) { + UnboundFacet unboundFacet = (UnboundFacet) facet; + UnboundFacet.Binder binder = unboundFacet.binder(); + unboundFacet.getProperties().forEach(prop -> { + if (valueMap == null) { + Object value = BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop, + false); + binder.setValueForProperty(prop, value.toString()); + } else { + binder.setValueForProperty(prop, valueMap.get(prop.getPropertyName()).toString()); + } + }); + if (binder.isBound()) { + boundFacets.add(binder.bind()); + } + } else { + boundFacets.add(facet); + } + } + // NOTE: should equal `String tableName = CacheUtil.schemaName(facets);` + List facetCombinations = CacheUtil.flattenFacets(boundFacets); + String tableName = CacheUtil.schemaName(boundFacets); + mergeAndUpdateCacheValues(pojo, tableName, facetCombinations); + } + } } } private void mergeAndUpdateCacheValues(Object pojo, String tableName, List facetCombinations) { Object merged = null; for (String[] combination : facetCombinations) { - String cacheKey = tableName + "." + Arrays.toString(combination); + String cacheKey = tableName + "." + Arrays.toString(combination); Object value = sessionCache.getIfPresent(cacheKey); if (value == null) { sessionCache.put(cacheKey, pojo); diff --git a/src/main/java/net/helenus/core/operation/AbstractOptionalOperation.java b/src/main/java/net/helenus/core/operation/AbstractOptionalOperation.java index 5850f37..fe27197 100644 --- a/src/main/java/net/helenus/core/operation/AbstractOptionalOperation.java +++ b/src/main/java/net/helenus/core/operation/AbstractOptionalOperation.java @@ -15,6 +15,8 @@ */ package net.helenus.core.operation; +import static net.helenus.core.HelenusSession.deleted; + import java.util.List; import java.util.Optional; import java.util.concurrent.CompletableFuture; @@ -32,8 +34,6 @@ import net.helenus.core.UnitOfWork; import net.helenus.core.cache.CacheUtil; import net.helenus.core.cache.Facet; -import static net.helenus.core.HelenusSession.deleted; - public abstract class AbstractOptionalOperation> extends AbstractStatementOperation { @@ -118,41 +118,41 @@ public abstract class AbstractOptionalOperation facets = bindFacetValues(); if (facets != null) { - cachedResult = checkCache(uow, facets); - if (cachedResult != null) { - updateCache = false; - result = Optional.of(cachedResult); - uowCacheHits.mark(); - cacheHits.mark(); - uow.recordCacheAndDatabaseOperationCount(1, 0); - } else { - updateCache = true; - uowCacheMiss.mark(); - if (isSessionCacheable()) { - String tableName = CacheUtil.schemaName(facets); - cachedResult = (E) sessionOps.checkCache(tableName, facets); - if (cachedResult != null) { - result = Optional.of(cachedResult); - sessionCacheHits.mark(); - cacheHits.mark(); - uow.recordCacheAndDatabaseOperationCount(1, 0); - } else { - sessionCacheMiss.mark(); - cacheMiss.mark(); - uow.recordCacheAndDatabaseOperationCount(-1, 0); - } - } - } - } else { - updateCache = false; - } + cachedResult = checkCache(uow, facets); + if (cachedResult != null) { + updateCache = false; + result = Optional.of(cachedResult); + uowCacheHits.mark(); + cacheHits.mark(); + uow.recordCacheAndDatabaseOperationCount(1, 0); + } else { + updateCache = true; + uowCacheMiss.mark(); + if (isSessionCacheable()) { + String tableName = CacheUtil.schemaName(facets); + cachedResult = (E) sessionOps.checkCache(tableName, facets); + if (cachedResult != null) { + result = Optional.of(cachedResult); + sessionCacheHits.mark(); + cacheHits.mark(); + uow.recordCacheAndDatabaseOperationCount(1, 0); + } else { + sessionCacheMiss.mark(); + cacheMiss.mark(); + uow.recordCacheAndDatabaseOperationCount(-1, 0); + } + } + } + } else { + updateCache = false; + } } finally { timer.stop(); uow.addCacheLookupTime(timer); } } else { - updateCache = false; - } + updateCache = false; + } if (!result.isPresent()) { // Formulate the query and execute it against the Cassandra cluster. @@ -163,16 +163,16 @@ public abstract class AbstractOptionalOperation> extends AbstractStatementOperation { @@ -124,41 +124,41 @@ public abstract class AbstractStreamOperation facets = bindFacetValues(); if (facets != null) { - cachedResult = checkCache(uow, facets); - if (cachedResult != null) { - updateCache = false; - resultStream = Stream.of(cachedResult); - uowCacheHits.mark(); - cacheHits.mark(); - uow.recordCacheAndDatabaseOperationCount(1, 0); - } else { - updateCache = true; - uowCacheMiss.mark(); - if (isSessionCacheable()) { - String tableName = CacheUtil.schemaName(facets); - cachedResult = (E) sessionOps.checkCache(tableName, facets); - if (cachedResult != null) { - resultStream = Stream.of(cachedResult); - sessionCacheHits.mark(); - cacheHits.mark(); - uow.recordCacheAndDatabaseOperationCount(1, 0); - } else { - sessionCacheMiss.mark(); - cacheMiss.mark(); - uow.recordCacheAndDatabaseOperationCount(-1, 0); - } - } - } - } else { - updateCache = false; - } + cachedResult = checkCache(uow, facets); + if (cachedResult != null) { + updateCache = false; + resultStream = Stream.of(cachedResult); + uowCacheHits.mark(); + cacheHits.mark(); + uow.recordCacheAndDatabaseOperationCount(1, 0); + } else { + updateCache = true; + uowCacheMiss.mark(); + if (isSessionCacheable()) { + String tableName = CacheUtil.schemaName(facets); + cachedResult = (E) sessionOps.checkCache(tableName, facets); + if (cachedResult != null) { + resultStream = Stream.of(cachedResult); + sessionCacheHits.mark(); + cacheHits.mark(); + uow.recordCacheAndDatabaseOperationCount(1, 0); + } else { + sessionCacheMiss.mark(); + cacheMiss.mark(); + uow.recordCacheAndDatabaseOperationCount(-1, 0); + } + } + } + } else { + updateCache = false; + } } finally { timer.stop(); uow.addCacheLookupTime(timer); } } else { - updateCache = false; - } + updateCache = false; + } if (resultStream == null) { ResultSet resultSet = execute(sessionOps, uow, traceContext, queryExecutionTimeout, queryTimeoutUnits, @@ -169,19 +169,19 @@ public abstract class AbstractStreamOperation again = new ArrayList<>(); - List facets = getFacets(); - resultStream.forEach(result -> { - if (result != deleted) { - if (updateCache) { - cacheUpdate(uow, result, facets); - } - again.add(result); - } - }); - resultStream = again.stream(); + List again = new ArrayList<>(); + List facets = getFacets(); + resultStream.forEach(result -> { + if (result != deleted) { + if (updateCache) { + cacheUpdate(uow, result, facets); + } + again.add(result); + } + }); + resultStream = again.stream(); } - return resultStream; + return resultStream; } finally { context.stop(); } diff --git a/src/main/java/net/helenus/core/operation/DeleteOperation.java b/src/main/java/net/helenus/core/operation/DeleteOperation.java index d3abf19..5490bf2 100644 --- a/src/main/java/net/helenus/core/operation/DeleteOperation.java +++ b/src/main/java/net/helenus/core/operation/DeleteOperation.java @@ -133,9 +133,9 @@ public final class DeleteOperation extends AbstractFilterOperation bindFacetValues(List facets) { - if (facets == null) { - return new ArrayList(); - } + if (facets == null) { + return new ArrayList(); + } List boundFacets = new ArrayList<>(); Map filterMap = new HashMap<>(filters.size()); filters.forEach(f -> filterMap.put(f.getNode().getProperty(), f)); @@ -177,9 +177,9 @@ public final class DeleteOperation extends AbstractFilterOperation getFacets() { - return entity.getFacets(); - } + public List getFacets() { + return entity.getFacets(); + } @Override public ResultSet sync(UnitOfWork uow) {// throws TimeoutException { @@ -187,8 +187,8 @@ public final class DeleteOperation extends AbstractFilterOperation facets = getFacets(); - uow.cacheEvict(bindFacetValues(facets)); + List facets = getFacets(); + uow.cacheEvict(bindFacetValues(facets)); return result; } diff --git a/src/main/java/net/helenus/core/operation/Operation.java b/src/main/java/net/helenus/core/operation/Operation.java index e451926..e63180a 100644 --- a/src/main/java/net/helenus/core/operation/Operation.java +++ b/src/main/java/net/helenus/core/operation/Operation.java @@ -19,17 +19,17 @@ import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; -import com.datastax.driver.core.RegularStatement; -import com.datastax.driver.core.querybuilder.BuiltStatement; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.codahale.metrics.Meter; import com.codahale.metrics.MetricRegistry; import com.codahale.metrics.Timer; +import com.datastax.driver.core.RegularStatement; import com.datastax.driver.core.ResultSet; import com.datastax.driver.core.ResultSetFuture; import com.datastax.driver.core.Statement; +import com.datastax.driver.core.querybuilder.BuiltStatement; import com.google.common.base.Stopwatch; import brave.Span; @@ -53,19 +53,39 @@ public abstract class Operation { protected final Timer requestLatency; Operation(AbstractSessionOperations sessionOperations) { - this.sessionOps = sessionOperations; - MetricRegistry metrics = sessionOperations.getMetricRegistry(); - if (metrics == null) { - metrics = new MetricRegistry(); - } - this.uowCacheHits = metrics.meter("net.helenus.UOW-cache-hits"); - this.uowCacheMiss = metrics.meter("net.helenus.UOW-cache-miss"); - this.sessionCacheHits = metrics.meter("net.helenus.session-cache-hits"); - this.sessionCacheMiss = metrics.meter("net.helenus.session-cache-miss"); - this.cacheHits = metrics.meter("net.helenus.cache-hits"); - this.cacheMiss = metrics.meter("net.helenus.cache-miss"); - this.requestLatency = metrics.timer("net.helenus.request-latency"); - } + this.sessionOps = sessionOperations; + MetricRegistry metrics = sessionOperations.getMetricRegistry(); + if (metrics == null) { + metrics = new MetricRegistry(); + } + this.uowCacheHits = metrics.meter("net.helenus.UOW-cache-hits"); + this.uowCacheMiss = metrics.meter("net.helenus.UOW-cache-miss"); + this.sessionCacheHits = metrics.meter("net.helenus.session-cache-hits"); + this.sessionCacheMiss = metrics.meter("net.helenus.session-cache-miss"); + this.cacheHits = metrics.meter("net.helenus.cache-hits"); + this.cacheMiss = metrics.meter("net.helenus.cache-miss"); + this.requestLatency = metrics.timer("net.helenus.request-latency"); + } + + public static String queryString(Statement statement, boolean includeValues) { + String query = null; + if (statement instanceof BuiltStatement) { + BuiltStatement builtStatement = (BuiltStatement) statement; + if (includeValues) { + RegularStatement regularStatement = builtStatement.setForceNoValues(true); + query = regularStatement.getQueryString(); + } else { + query = builtStatement.getQueryString(); + } + } else if (statement instanceof RegularStatement) { + RegularStatement regularStatement = (RegularStatement) statement; + query = regularStatement.getQueryString(); + } else { + query = statement.toString(); + + } + return query; + } public ResultSet execute(AbstractSessionOperations session, UnitOfWork uow, TraceContext traceContext, long timeout, TimeUnit units, boolean showValues, boolean cached) { // throws TimeoutException { @@ -109,40 +129,17 @@ public abstract class Operation { } } - public static String queryString(Statement statement, boolean includeValues) { - String query = null; - if (statement instanceof BuiltStatement) { - BuiltStatement builtStatement = (BuiltStatement) statement; - if (includeValues) { - RegularStatement regularStatement = builtStatement.setForceNoValues(true); - query = regularStatement.getQueryString(); - } else { - query = builtStatement.getQueryString(); - } - } else if (statement instanceof RegularStatement) { - RegularStatement regularStatement = (RegularStatement) statement; - query = regularStatement.getQueryString(); - } else { - query = statement.toString(); - - } - return query; - } - - void log(Statement statement, UnitOfWork uow, Stopwatch timer, boolean showValues) { + void log(Statement statement, UnitOfWork uow, Stopwatch timer, boolean showValues) { if (LOG.isInfoEnabled()) { String uowString = ""; if (uow != null) { uowString = "UOW(" + uow.hashCode() + ")"; } - String timerString = ""; + String timerString = ""; if (timer != null) { timerString = String.format(" %s ", timer.toString()); } - LOG.info(String.format("%s%s%s", - uowString, - timerString, - Operation.queryString(statement, false))); + LOG.info(String.format("%s%s%s", uowString, timerString, Operation.queryString(statement, false))); } } diff --git a/src/main/java/net/helenus/core/operation/SelectOperation.java b/src/main/java/net/helenus/core/operation/SelectOperation.java index b4470dd..497868b 100644 --- a/src/main/java/net/helenus/core/operation/SelectOperation.java +++ b/src/main/java/net/helenus/core/operation/SelectOperation.java @@ -250,7 +250,8 @@ public final class SelectOperation extends AbstractFilterStreamOperation implements InvocationHandler { private HelenusEntity init(Metadata metadata) { HelenusEntity entity = new HelenusMappingEntity(iface, metadata); - Collection properties = entity.getOrderedProperties(); - if (properties != null) { - for (HelenusProperty prop : properties) { + Collection properties = entity.getOrderedProperties(); + if (properties != null) { + for (HelenusProperty prop : properties) { - map.put(prop.getGetterMethod(), prop); + map.put(prop.getGetterMethod(), prop); - AbstractDataType type = prop.getDataType(); - Class javaType = prop.getJavaType(); + AbstractDataType type = prop.getDataType(); + Class javaType = prop.getJavaType(); - if (type instanceof UDTDataType && !UDTValue.class.isAssignableFrom(javaType)) { + if (type instanceof UDTDataType && !UDTValue.class.isAssignableFrom(javaType)) { - Object childDsl = Helenus.dsl(javaType, classLoader, - Optional.of(new HelenusPropertyNode(prop, parent)), - metadata); + Object childDsl = Helenus.dsl(javaType, classLoader, + Optional.of(new HelenusPropertyNode(prop, parent)), metadata); - udtMap.put(prop.getGetterMethod(), childDsl); - } + udtMap.put(prop.getGetterMethod(), childDsl); + } - if (type instanceof DTDataType) { - DTDataType dataType = (DTDataType) type; + if (type instanceof DTDataType) { + DTDataType dataType = (DTDataType) type; - if (dataType.getDataType() instanceof TupleType && !TupleValue.class.isAssignableFrom(javaType)) { + if (dataType.getDataType() instanceof TupleType && !TupleValue.class.isAssignableFrom(javaType)) { - Object childDsl = Helenus.dsl(javaType, classLoader, - Optional.of(new HelenusPropertyNode(prop, parent)), metadata); + Object childDsl = Helenus.dsl(javaType, classLoader, + Optional.of(new HelenusPropertyNode(prop, parent)), metadata); - tupleMap.put(prop.getGetterMethod(), childDsl); - } - } - } - } + tupleMap.put(prop.getGetterMethod(), childDsl); + } + } + } + } return entity; } From c7e37acc5a1dcb16127d7fe2d77f227d158f2ed2 Mon Sep 17 00:00:00 2001 From: Greg Burd Date: Wed, 25 Oct 2017 21:59:12 -0400 Subject: [PATCH 09/18] Add generic type where overlooked. Fix some cache logic. --- .../core/AbstractSessionOperations.java | 8 ++-- .../core/ConflictingUnitOfWorkException.java | 4 +- .../net/helenus/core/PostCommitFunction.java | 4 +- .../core/operation/AbstractOperation.java | 4 +- .../operation/AbstractOptionalOperation.java | 41 +++++++++++-------- .../operation/AbstractStreamOperation.java | 40 +++++++++--------- .../core/operation/DeleteOperation.java | 2 +- .../core/operation/InsertOperation.java | 2 +- .../net/helenus/core/operation/Operation.java | 6 +-- .../core/operation/UpdateOperation.java | 2 +- 10 files changed, 60 insertions(+), 53 deletions(-) diff --git a/src/main/java/net/helenus/core/AbstractSessionOperations.java b/src/main/java/net/helenus/core/AbstractSessionOperations.java index 3f8eba2..912f12f 100644 --- a/src/main/java/net/helenus/core/AbstractSessionOperations.java +++ b/src/main/java/net/helenus/core/AbstractSessionOperations.java @@ -86,11 +86,11 @@ public abstract class AbstractSessionOperations { return execute(statement, null, timer, showValues); } - public ResultSet execute(Statement statement, UnitOfWork uow, boolean showValues) { + public ResultSet execute(Statement statement, UnitOfWork uow, boolean showValues) { return execute(statement, uow, null, showValues); } - public ResultSet execute(Statement statement, UnitOfWork uow, Stopwatch timer, boolean showValues) { + public ResultSet execute(Statement statement, UnitOfWork uow, Stopwatch timer, boolean showValues) { return executeAsync(statement, uow, timer, showValues).getUninterruptibly(); } @@ -102,11 +102,11 @@ public abstract class AbstractSessionOperations { return executeAsync(statement, null, timer, showValues); } - public ResultSetFuture executeAsync(Statement statement, UnitOfWork uow, boolean showValues) { + public ResultSetFuture executeAsync(Statement statement, UnitOfWork uow, boolean showValues) { return executeAsync(statement, uow, null, showValues); } - public ResultSetFuture executeAsync(Statement statement, UnitOfWork uow, Stopwatch timer, boolean showValues) { + public ResultSetFuture executeAsync(Statement statement, UnitOfWork uow, Stopwatch timer, boolean showValues) { try { logStatement(statement, showValues); return currentSession().executeAsync(statement); diff --git a/src/main/java/net/helenus/core/ConflictingUnitOfWorkException.java b/src/main/java/net/helenus/core/ConflictingUnitOfWorkException.java index a20aad4..bd52799 100644 --- a/src/main/java/net/helenus/core/ConflictingUnitOfWorkException.java +++ b/src/main/java/net/helenus/core/ConflictingUnitOfWorkException.java @@ -2,9 +2,9 @@ package net.helenus.core; public class ConflictingUnitOfWorkException extends Exception { - final UnitOfWork uow; + final UnitOfWork uow; - ConflictingUnitOfWorkException(UnitOfWork uow) { + ConflictingUnitOfWorkException(UnitOfWork uow) { this.uow = uow; } } diff --git a/src/main/java/net/helenus/core/PostCommitFunction.java b/src/main/java/net/helenus/core/PostCommitFunction.java index a859608..f45f033 100644 --- a/src/main/java/net/helenus/core/PostCommitFunction.java +++ b/src/main/java/net/helenus/core/PostCommitFunction.java @@ -5,10 +5,10 @@ import java.util.Objects; public class PostCommitFunction implements java.util.function.Function { - private final UnitOfWork uow; + private final UnitOfWork uow; private final List postCommit; - PostCommitFunction(UnitOfWork uow, List postCommit) { + PostCommitFunction(UnitOfWork uow, List postCommit) { this.uow = uow; this.postCommit = postCommit; } diff --git a/src/main/java/net/helenus/core/operation/AbstractOperation.java b/src/main/java/net/helenus/core/operation/AbstractOperation.java index 82e8fb2..9d834d8 100644 --- a/src/main/java/net/helenus/core/operation/AbstractOperation.java +++ b/src/main/java/net/helenus/core/operation/AbstractOperation.java @@ -46,7 +46,7 @@ public abstract class AbstractOperation> ex } } - public E sync(UnitOfWork uow) {// throws TimeoutException { + public E sync(UnitOfWork uow) {// throws TimeoutException { if (uow == null) return sync(); @@ -71,7 +71,7 @@ public abstract class AbstractOperation> ex }); } - public CompletableFuture async(UnitOfWork uow) { + public CompletableFuture async(UnitOfWork uow) { if (uow == null) return async(); return CompletableFuture.supplyAsync(() -> { diff --git a/src/main/java/net/helenus/core/operation/AbstractOptionalOperation.java b/src/main/java/net/helenus/core/operation/AbstractOptionalOperation.java index fe27197..dd7907c 100644 --- a/src/main/java/net/helenus/core/operation/AbstractOptionalOperation.java +++ b/src/main/java/net/helenus/core/operation/AbstractOptionalOperation.java @@ -154,25 +154,30 @@ public abstract class AbstractOptionalOperation again = new ArrayList<>(); + List facets = getFacets(); + resultStream.forEach(result -> { + if (result != deleted) { + if (updateCache) { + cacheUpdate(uow, result, facets); + } + again.add(result); + } + }); + resultStream = again.stream(); + } - // If we have a result and we're caching then we need to put it into the cache - // for future requests to find. - if (resultStream != null) { - List again = new ArrayList<>(); - List facets = getFacets(); - resultStream.forEach(result -> { - if (result != deleted) { - if (updateCache) { - cacheUpdate(uow, result, facets); - } - again.add(result); - } - }); - resultStream = again.stream(); - } return resultStream; } finally { context.stop(); diff --git a/src/main/java/net/helenus/core/operation/DeleteOperation.java b/src/main/java/net/helenus/core/operation/DeleteOperation.java index 5490bf2..e180ff0 100644 --- a/src/main/java/net/helenus/core/operation/DeleteOperation.java +++ b/src/main/java/net/helenus/core/operation/DeleteOperation.java @@ -182,7 +182,7 @@ public final class DeleteOperation extends AbstractFilterOperation uow) {// throws TimeoutException { if (uow == null) { return sync(); } diff --git a/src/main/java/net/helenus/core/operation/InsertOperation.java b/src/main/java/net/helenus/core/operation/InsertOperation.java index 510121c..462449c 100644 --- a/src/main/java/net/helenus/core/operation/InsertOperation.java +++ b/src/main/java/net/helenus/core/operation/InsertOperation.java @@ -245,7 +245,7 @@ public final class InsertOperation extends AbstractOperation uow) {// throws TimeoutException { if (uow == null) { return sync(); } diff --git a/src/main/java/net/helenus/core/operation/Operation.java b/src/main/java/net/helenus/core/operation/Operation.java index e63180a..61e12c4 100644 --- a/src/main/java/net/helenus/core/operation/Operation.java +++ b/src/main/java/net/helenus/core/operation/Operation.java @@ -87,8 +87,8 @@ public abstract class Operation { 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. @@ -129,7 +129,7 @@ public abstract class Operation { } } - void log(Statement statement, UnitOfWork uow, Stopwatch timer, boolean showValues) { + void log(Statement statement, UnitOfWork uow, Stopwatch timer, boolean showValues) { if (LOG.isInfoEnabled()) { String uowString = ""; if (uow != null) { diff --git a/src/main/java/net/helenus/core/operation/UpdateOperation.java b/src/main/java/net/helenus/core/operation/UpdateOperation.java index f21133f..dfdc955 100644 --- a/src/main/java/net/helenus/core/operation/UpdateOperation.java +++ b/src/main/java/net/helenus/core/operation/UpdateOperation.java @@ -577,7 +577,7 @@ public final class UpdateOperation extends AbstractFilterOperation uow) {// throws TimeoutException { if (uow == null) { return sync(); } From b04e033bf474d8e8f7eaad5443b5e17e53b42055 Mon Sep 17 00:00:00 2001 From: Greg Burd Date: Thu, 26 Oct 2017 10:37:08 -0400 Subject: [PATCH 10/18] Re-enable TimeoutException. Revert changes to add type to UnitOfWork as it breaks the use of subclasses. --- .../core/AbstractSessionOperations.java | 8 +-- .../core/ConflictingUnitOfWorkException.java | 20 +++++- .../net/helenus/core/PostCommitFunction.java | 4 +- .../net/helenus/core/annotation/Retry.java | 19 +++++- .../net/helenus/core/aspect/RetryAspect.java | 16 +++++ .../core/operation/AbstractOperation.java | 28 ++++---- .../operation/AbstractOptionalOperation.java | 48 +++++++------- .../operation/AbstractStreamOperation.java | 66 ++++++++++--------- .../core/operation/DeleteOperation.java | 5 +- .../core/operation/InsertOperation.java | 5 +- .../net/helenus/core/operation/Operation.java | 9 +-- .../core/operation/UpdateOperation.java | 5 +- .../core/views/MaterializedViewTest.java | 6 +- 13 files changed, 149 insertions(+), 90 deletions(-) diff --git a/src/main/java/net/helenus/core/AbstractSessionOperations.java b/src/main/java/net/helenus/core/AbstractSessionOperations.java index 912f12f..3f8eba2 100644 --- a/src/main/java/net/helenus/core/AbstractSessionOperations.java +++ b/src/main/java/net/helenus/core/AbstractSessionOperations.java @@ -86,11 +86,11 @@ public abstract class AbstractSessionOperations { return execute(statement, null, timer, showValues); } - public ResultSet execute(Statement statement, UnitOfWork uow, boolean showValues) { + public ResultSet execute(Statement statement, UnitOfWork uow, boolean showValues) { return execute(statement, uow, null, showValues); } - public ResultSet execute(Statement statement, UnitOfWork uow, Stopwatch timer, boolean showValues) { + public ResultSet execute(Statement statement, UnitOfWork uow, Stopwatch timer, boolean showValues) { return executeAsync(statement, uow, timer, showValues).getUninterruptibly(); } @@ -102,11 +102,11 @@ public abstract class AbstractSessionOperations { return executeAsync(statement, null, timer, showValues); } - public ResultSetFuture executeAsync(Statement statement, UnitOfWork uow, boolean showValues) { + public ResultSetFuture executeAsync(Statement statement, UnitOfWork uow, boolean showValues) { return executeAsync(statement, uow, null, showValues); } - public ResultSetFuture executeAsync(Statement statement, UnitOfWork uow, Stopwatch timer, boolean showValues) { + public ResultSetFuture executeAsync(Statement statement, UnitOfWork uow, Stopwatch timer, boolean showValues) { try { logStatement(statement, showValues); return currentSession().executeAsync(statement); diff --git a/src/main/java/net/helenus/core/ConflictingUnitOfWorkException.java b/src/main/java/net/helenus/core/ConflictingUnitOfWorkException.java index bd52799..e8ab229 100644 --- a/src/main/java/net/helenus/core/ConflictingUnitOfWorkException.java +++ b/src/main/java/net/helenus/core/ConflictingUnitOfWorkException.java @@ -1,10 +1,26 @@ +/* + * Copyright (C) 2015 The Helenus Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package net.helenus.core; public class ConflictingUnitOfWorkException extends Exception { - final UnitOfWork uow; + final UnitOfWork uow; - ConflictingUnitOfWorkException(UnitOfWork uow) { + ConflictingUnitOfWorkException(UnitOfWork uow) { this.uow = uow; } } diff --git a/src/main/java/net/helenus/core/PostCommitFunction.java b/src/main/java/net/helenus/core/PostCommitFunction.java index f45f033..a859608 100644 --- a/src/main/java/net/helenus/core/PostCommitFunction.java +++ b/src/main/java/net/helenus/core/PostCommitFunction.java @@ -5,10 +5,10 @@ import java.util.Objects; public class PostCommitFunction implements java.util.function.Function { - private final UnitOfWork uow; + private final UnitOfWork uow; private final List postCommit; - PostCommitFunction(UnitOfWork uow, List postCommit) { + PostCommitFunction(UnitOfWork uow, List postCommit) { this.uow = uow; this.postCommit = postCommit; } diff --git a/src/main/java/net/helenus/core/annotation/Retry.java b/src/main/java/net/helenus/core/annotation/Retry.java index 7db5b20..6ca6308 100644 --- a/src/main/java/net/helenus/core/annotation/Retry.java +++ b/src/main/java/net/helenus/core/annotation/Retry.java @@ -1,9 +1,26 @@ +/* + * Copyright (C) 2015 The Helenus Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package net.helenus.core.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import java.util.concurrent.TimeoutException; import net.helenus.core.ConflictingUnitOfWorkException; @@ -11,7 +28,7 @@ import net.helenus.core.ConflictingUnitOfWorkException; @Target(ElementType.METHOD) public @interface Retry { - Class[] on() default ConflictingUnitOfWorkException.class; + Class[] on() default {ConflictingUnitOfWorkException.class, TimeoutException.class}; int times() default 3; } diff --git a/src/main/java/net/helenus/core/aspect/RetryAspect.java b/src/main/java/net/helenus/core/aspect/RetryAspect.java index 587d087..ed7d50e 100644 --- a/src/main/java/net/helenus/core/aspect/RetryAspect.java +++ b/src/main/java/net/helenus/core/aspect/RetryAspect.java @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2015 The Helenus Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package net.helenus.core.aspect; import java.lang.reflect.Method; diff --git a/src/main/java/net/helenus/core/operation/AbstractOperation.java b/src/main/java/net/helenus/core/operation/AbstractOperation.java index 9d834d8..27d7eaf 100644 --- a/src/main/java/net/helenus/core/operation/AbstractOperation.java +++ b/src/main/java/net/helenus/core/operation/AbstractOperation.java @@ -16,6 +16,8 @@ package net.helenus.core.operation; import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; +import java.util.concurrent.TimeoutException; import com.codahale.metrics.Timer; import com.datastax.driver.core.ResultSet; @@ -35,7 +37,7 @@ public abstract class AbstractOperation> ex return new PreparedOperation(prepareStatement(), this); } - public E sync() {// throws TimeoutException { + public E sync() throws TimeoutException { final Timer.Context context = requestLatency.time(); try { ResultSet resultSet = this.execute(sessionOps, null, traceContext, queryExecutionTimeout, queryTimeoutUnits, @@ -46,7 +48,7 @@ public abstract class AbstractOperation> ex } } - public E sync(UnitOfWork uow) {// throws TimeoutException { + public E sync(UnitOfWork uow) throws TimeoutException { if (uow == null) return sync(); @@ -63,23 +65,23 @@ public abstract class AbstractOperation> ex public CompletableFuture async() { return CompletableFuture.supplyAsync(() -> { - // try { - return sync(); - // } catch (TimeoutException ex) { - // throw new CompletionException(ex); - // } + try { + return sync(); + } catch (TimeoutException ex) { + throw new CompletionException(ex); + } }); } - public CompletableFuture async(UnitOfWork uow) { + public CompletableFuture async(UnitOfWork uow) { if (uow == null) return async(); return CompletableFuture.supplyAsync(() -> { - // try { - return sync(); - // } catch (TimeoutException ex) { - // throw new CompletionException(ex); - // } + try { + return sync(); + } catch (TimeoutException ex) { + throw new CompletionException(ex); + } }); } } diff --git a/src/main/java/net/helenus/core/operation/AbstractOptionalOperation.java b/src/main/java/net/helenus/core/operation/AbstractOptionalOperation.java index dd7907c..1591404 100644 --- a/src/main/java/net/helenus/core/operation/AbstractOptionalOperation.java +++ b/src/main/java/net/helenus/core/operation/AbstractOptionalOperation.java @@ -20,6 +20,8 @@ import static net.helenus.core.HelenusSession.deleted; import java.util.List; import java.util.Optional; import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; +import java.util.concurrent.TimeoutException; import com.codahale.metrics.Timer; import com.datastax.driver.core.PreparedStatement; @@ -59,7 +61,7 @@ public abstract class AbstractOptionalOperation sync() {// throws TimeoutException { + public Optional sync() throws TimeoutException { final Timer.Context context = requestLatency.time(); try { Optional result = Optional.empty(); @@ -102,7 +104,7 @@ public abstract class AbstractOptionalOperation sync(UnitOfWork uow) {// throws TimeoutException { + public Optional sync(UnitOfWork uow) throws TimeoutException { if (uow == null) return sync(); @@ -163,19 +165,19 @@ public abstract class AbstractOptionalOperation> async() { return CompletableFuture.>supplyAsync(() -> { - // try { - return sync(); - // } catch (TimeoutException ex) { - // throw new CompletionException(ex); - // } + try { + return sync(); + } catch (TimeoutException ex) { + throw new CompletionException(ex); + } }); } @@ -197,11 +199,11 @@ public abstract class AbstractOptionalOperation>supplyAsync(() -> { - // try { - return sync(); - // } catch (TimeoutException ex) { - // throw new CompletionException(ex); - // } + try { + return sync(); + } catch (TimeoutException ex) { + throw new CompletionException(ex); + } }); } } diff --git a/src/main/java/net/helenus/core/operation/AbstractStreamOperation.java b/src/main/java/net/helenus/core/operation/AbstractStreamOperation.java index ad66dbb..749f0ff 100644 --- a/src/main/java/net/helenus/core/operation/AbstractStreamOperation.java +++ b/src/main/java/net/helenus/core/operation/AbstractStreamOperation.java @@ -20,6 +20,8 @@ import static net.helenus.core.HelenusSession.deleted; import java.util.ArrayList; import java.util.List; import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; +import java.util.concurrent.TimeoutException; import java.util.stream.Stream; import com.codahale.metrics.Timer; @@ -60,7 +62,7 @@ public abstract class AbstractStreamOperation sync() {// throws TimeoutException { + public Stream sync() throws TimeoutException { final Timer.Context context = requestLatency.time(); try { Stream resultStream = null; @@ -109,7 +111,7 @@ public abstract class AbstractStreamOperation sync(UnitOfWork uow) {// throws TimeoutException { + public Stream sync(UnitOfWork uow) throws TimeoutException { if (uow == null) return sync(); @@ -162,26 +164,26 @@ public abstract class AbstractStreamOperation again = new ArrayList<>(); - List facets = getFacets(); - resultStream.forEach(result -> { - if (result != deleted) { - if (updateCache) { - cacheUpdate(uow, result, facets); - } - again.add(result); - } - }); - resultStream = again.stream(); - } + // If we have a result and we're caching then we need to put it into the cache + // for future requests to find. + if (resultStream != null) { + List again = new ArrayList<>(); + List facets = getFacets(); + resultStream.forEach(result -> { + if (result != deleted) { + if (updateCache) { + cacheUpdate(uow, result, facets); + } + again.add(result); + } + }); + resultStream = again.stream(); + } return resultStream; } finally { @@ -191,23 +193,23 @@ public abstract class AbstractStreamOperation> async() { return CompletableFuture.>supplyAsync(() -> { - // try { - return sync(); - // } catch (TimeoutException ex) { - // throw new CompletionException(ex); - // } + try { + return sync(); + } catch (TimeoutException ex) { + throw new CompletionException(ex); + } }); } - public CompletableFuture> async(UnitOfWork uow) { + public CompletableFuture> async(UnitOfWork uow) { if (uow == null) return async(); return CompletableFuture.>supplyAsync(() -> { - // try { - return sync(); - // } catch (TimeoutException ex) { - // throw new CompletionException(ex); - // } + try { + return sync(); + } catch (TimeoutException ex) { + throw new CompletionException(ex); + } }); } } diff --git a/src/main/java/net/helenus/core/operation/DeleteOperation.java b/src/main/java/net/helenus/core/operation/DeleteOperation.java index e180ff0..9375a30 100644 --- a/src/main/java/net/helenus/core/operation/DeleteOperation.java +++ b/src/main/java/net/helenus/core/operation/DeleteOperation.java @@ -19,6 +19,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.TimeoutException; import com.datastax.driver.core.ResultSet; import com.datastax.driver.core.querybuilder.BuiltStatement; @@ -168,7 +169,7 @@ public final class DeleteOperation extends AbstractFilterOperation uow) {// throws TimeoutException { + public ResultSet sync(UnitOfWork uow) throws TimeoutException { if (uow == null) { return sync(); } diff --git a/src/main/java/net/helenus/core/operation/InsertOperation.java b/src/main/java/net/helenus/core/operation/InsertOperation.java index 462449c..89fb3c3 100644 --- a/src/main/java/net/helenus/core/operation/InsertOperation.java +++ b/src/main/java/net/helenus/core/operation/InsertOperation.java @@ -16,6 +16,7 @@ package net.helenus.core.operation; import java.util.*; +import java.util.concurrent.TimeoutException; import java.util.function.Function; import com.datastax.driver.core.ResultSet; @@ -236,7 +237,7 @@ public final class InsertOperation extends AbstractOperation extends AbstractOperation uow) {// throws TimeoutException { + public T sync(UnitOfWork uow) throws TimeoutException { if (uow == null) { return sync(); } diff --git a/src/main/java/net/helenus/core/operation/Operation.java b/src/main/java/net/helenus/core/operation/Operation.java index 61e12c4..00262bb 100644 --- a/src/main/java/net/helenus/core/operation/Operation.java +++ b/src/main/java/net/helenus/core/operation/Operation.java @@ -18,6 +18,7 @@ package net.helenus.core.operation; import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -87,8 +88,8 @@ public abstract class Operation { 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. @@ -111,7 +112,7 @@ public abstract class Operation { ResultSetFuture futureResultSet = session.executeAsync(statement, uow, timer, showValues); if (uow != null) uow.recordCacheAndDatabaseOperationCount(0, 1); - ResultSet resultSet = futureResultSet.getUninterruptibly(); // TODO(gburd): (timeout, units); + ResultSet resultSet = futureResultSet.getUninterruptibly(timeout, units); return resultSet; } finally { @@ -129,7 +130,7 @@ public abstract class Operation { } } - void log(Statement statement, UnitOfWork uow, Stopwatch timer, boolean showValues) { + void log(Statement statement, UnitOfWork uow, Stopwatch timer, boolean showValues) { if (LOG.isInfoEnabled()) { String uowString = ""; if (uow != null) { diff --git a/src/main/java/net/helenus/core/operation/UpdateOperation.java b/src/main/java/net/helenus/core/operation/UpdateOperation.java index dfdc955..67d4e34 100644 --- a/src/main/java/net/helenus/core/operation/UpdateOperation.java +++ b/src/main/java/net/helenus/core/operation/UpdateOperation.java @@ -16,6 +16,7 @@ package net.helenus.core.operation; import java.util.*; +import java.util.concurrent.TimeoutException; import java.util.function.Function; import com.datastax.driver.core.ResultSet; @@ -568,7 +569,7 @@ public final class UpdateOperation extends AbstractFilterOperation extends AbstractFilterOperation uow) {// throws TimeoutException { + public E sync(UnitOfWork uow) throws TimeoutException { if (uow == null) { return sync(); } diff --git a/src/test/java/net/helenus/test/integration/core/views/MaterializedViewTest.java b/src/test/java/net/helenus/test/integration/core/views/MaterializedViewTest.java index 7cbc247..8d4a431 100644 --- a/src/test/java/net/helenus/test/integration/core/views/MaterializedViewTest.java +++ b/src/test/java/net/helenus/test/integration/core/views/MaterializedViewTest.java @@ -55,12 +55,12 @@ public class MaterializedViewTest extends AbstractEmbeddedCassandraTest { .get(); cyclist = session.dsl(Cyclist.class); - // try { + try { session.insert(cyclist).value(cyclist::cid, UUID.randomUUID()).value(cyclist::age, 18) .value(cyclist::birthday, dateFromString("1997-02-08")).value(cyclist::country, "Netherlands") .value(cyclist::name, "Pascal EENKHOORN").sync(); - // } catch (TimeoutException e) { - // } + } catch (TimeoutException e) { + } } @Test From 92f74e41e167e9de77e361206ef9c4323a3a383c Mon Sep 17 00:00:00 2001 From: Greg Burd Date: Fri, 27 Oct 2017 08:48:42 -0400 Subject: [PATCH 11/18] WIP: support other caches --- helenus-core.iml | 5 +++ pom.xml | 14 ++++++ .../java/net/helenus/core/HelenusSession.java | 18 ++++---- .../net/helenus/core/aspect/RetryAspect.java | 2 +- .../net/helenus/core/cache/CaffeineCache.java | 43 ++++++++++++++++++ .../net/helenus/core/cache/GuavaCache.java | 44 +++++++++++++++++++ .../helenus/core/cache/MemcacheDbCache.java | 41 +++++++++++++++++ .../net/helenus/core/cache/RedisCache.java | 41 +++++++++++++++++ .../net/helenus/core/cache/SessionCache.java | 36 +++++++++++++++ 9 files changed, 235 insertions(+), 9 deletions(-) create mode 100644 src/main/java/net/helenus/core/cache/CaffeineCache.java create mode 100644 src/main/java/net/helenus/core/cache/GuavaCache.java create mode 100644 src/main/java/net/helenus/core/cache/MemcacheDbCache.java create mode 100644 src/main/java/net/helenus/core/cache/RedisCache.java create mode 100644 src/main/java/net/helenus/core/cache/SessionCache.java diff --git a/helenus-core.iml b/helenus-core.iml index be96637..fdf1252 100644 --- a/helenus-core.iml +++ b/helenus-core.iml @@ -125,6 +125,11 @@ + + + + + diff --git a/pom.xml b/pom.xml index 71feca8..4579ff7 100644 --- a/pom.xml +++ b/pom.xml @@ -259,6 +259,20 @@ test + + + com.github.ben-manes.caffeine + jcache + 2.5.6 + test + + + + net.spy + spymemcached + 2.12.3 + + org.slf4j diff --git a/src/main/java/net/helenus/core/HelenusSession.java b/src/main/java/net/helenus/core/HelenusSession.java index 58549ad..7bb1199 100644 --- a/src/main/java/net/helenus/core/HelenusSession.java +++ b/src/main/java/net/helenus/core/HelenusSession.java @@ -27,6 +27,7 @@ import java.util.concurrent.TimeUnit; import java.util.function.Function; import java.util.stream.Collectors; +import net.helenus.core.cache.SessionCache; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -57,8 +58,6 @@ public final class HelenusSession extends AbstractSessionOperations implements C public static final Object deleted = new Object(); private static final Logger LOG = LoggerFactory.getLogger(HelenusSession.class); - private final int MAX_CACHE_SIZE = 10000; - private final int MAX_CACHE_EXPIRE_SECONDS = 600; private final Session session; private final CodecRegistry registry; @@ -71,7 +70,7 @@ public final class HelenusSession extends AbstractSessionOperations implements C private final SessionRepository sessionRepository; private final Executor executor; private final boolean dropSchemaOnClose; - private final Cache sessionCache; + private final SessionCache sessionCache; private final RowColumnValueProvider valueProvider; private final StatementColumnValuePreparer valuePreparer; private final Metadata metadata; @@ -81,7 +80,8 @@ public final class HelenusSession extends AbstractSessionOperations implements C HelenusSession(Session session, String usingKeyspace, CodecRegistry registry, boolean showCql, PrintStream printStream, SessionRepositoryBuilder sessionRepositoryBuilder, Executor executor, boolean dropSchemaOnClose, ConsistencyLevel consistencyLevel, boolean defaultQueryIdempotency, - Class unitOfWorkClass, MetricRegistry metricRegistry, Tracer tracer) { + Class unitOfWorkClass, SessionCache sessionCache, + MetricRegistry metricRegistry, Tracer tracer) { this.session = session; this.registry = registry == null ? CodecRegistry.DEFAULT_INSTANCE : registry; this.usingKeyspace = Objects.requireNonNull(usingKeyspace, @@ -97,9 +97,11 @@ public final class HelenusSession extends AbstractSessionOperations implements C this.metricRegistry = metricRegistry; this.zipkinTracer = tracer; - this.sessionCache = CacheBuilder.newBuilder().maximumSize(MAX_CACHE_SIZE) - .expireAfterAccess(MAX_CACHE_EXPIRE_SECONDS, TimeUnit.SECONDS) - .expireAfterWrite(MAX_CACHE_EXPIRE_SECONDS, TimeUnit.SECONDS).recordStats().build(); + if (sessionCache == null) { + this.sessionCache = SessionCache.defaultCache(); + } else { + this.sessionCache = sessionCache; + } this.valueProvider = new RowColumnValueProvider(this.sessionRepository); this.valuePreparer = new StatementColumnValuePreparer(this.sessionRepository); @@ -289,7 +291,7 @@ public final class HelenusSession extends AbstractSessionOperations implements C Object merged = null; for (String[] combination : facetCombinations) { String cacheKey = tableName + "." + Arrays.toString(combination); - Object value = sessionCache.getIfPresent(cacheKey); + Object value = sessionCache.get(cacheKey); if (value == null) { sessionCache.put(cacheKey, pojo); } else { diff --git a/src/main/java/net/helenus/core/aspect/RetryAspect.java b/src/main/java/net/helenus/core/aspect/RetryAspect.java index ed7d50e..58d1f1d 100644 --- a/src/main/java/net/helenus/core/aspect/RetryAspect.java +++ b/src/main/java/net/helenus/core/aspect/RetryAspect.java @@ -89,7 +89,7 @@ public class RetryAspect { return retryAnnotation; } - Class[] argClasses = new Class[pjp.getArgs().length]; + Class[] argClasses = new Class[pjp.getArgs().length]; for (int i = 0; i < pjp.getArgs().length; i++) { argClasses[i] = pjp.getArgs()[i].getClass(); } diff --git a/src/main/java/net/helenus/core/cache/CaffeineCache.java b/src/main/java/net/helenus/core/cache/CaffeineCache.java new file mode 100644 index 0000000..0f5a9a4 --- /dev/null +++ b/src/main/java/net/helenus/core/cache/CaffeineCache.java @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2015 The Helenus Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.helenus.core.cache; + +public class CaffeineCache implements SessionCache { + + + final Cache cache; + + CaffeineCache(Cache cache) { + this.cache = cache; + } + + @Override + public void invalidate(K key) { + cache.invalidate(key); + } + + @Override + public V get(K key) { + return cache.getIfPresent(key); + } + + @Override + public void put(K key, V value) { + cache.put(key, value); + } + +} diff --git a/src/main/java/net/helenus/core/cache/GuavaCache.java b/src/main/java/net/helenus/core/cache/GuavaCache.java new file mode 100644 index 0000000..7438c63 --- /dev/null +++ b/src/main/java/net/helenus/core/cache/GuavaCache.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2015 The Helenus Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.helenus.core.cache; + +import com.google.common.cache.Cache; + +public class GuavaCache implements SessionCache { + + final Cache cache; + + GuavaCache(Cache cache) { + this.cache = cache; + } + + @Override + public void invalidate(K key) { + cache.invalidate(key); + } + + @Override + public V get(K key) { + return cache.getIfPresent(key); + } + + @Override + public void put(K key, V value) { + cache.put(key, value); + } + +} diff --git a/src/main/java/net/helenus/core/cache/MemcacheDbCache.java b/src/main/java/net/helenus/core/cache/MemcacheDbCache.java new file mode 100644 index 0000000..4f9a09c --- /dev/null +++ b/src/main/java/net/helenus/core/cache/MemcacheDbCache.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2015 The Helenus Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.helenus.core.cache; + +public class MemcacheDbCache implements SessionCache { + //final Cache cache; + + MemcacheDbCache() { + //this.cache = cache; + } + + @Override + public void invalidate(K key) { + //cache.invalidate(key); + } + + @Override + public V get(K key) { + return null; + } + + @Override + public void put(K key, V value) { + //cache.put(key, value); + } + +} diff --git a/src/main/java/net/helenus/core/cache/RedisCache.java b/src/main/java/net/helenus/core/cache/RedisCache.java new file mode 100644 index 0000000..6d11aa5 --- /dev/null +++ b/src/main/java/net/helenus/core/cache/RedisCache.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2015 The Helenus Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.helenus.core.cache; + +public class RedisCache implements SessionCache { + //final Cache cache; + + RedisCache() { + //this.cache = cache; + } + + @Override + public void invalidate(K key) { + //cache.invalidate(key); + } + + @Override + public V get(K key) { + return null; + } + + @Override + public void put(K key, V value) { + //cache.put(key, value); + } + +} diff --git a/src/main/java/net/helenus/core/cache/SessionCache.java b/src/main/java/net/helenus/core/cache/SessionCache.java new file mode 100644 index 0000000..02b15c6 --- /dev/null +++ b/src/main/java/net/helenus/core/cache/SessionCache.java @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2015 The Helenus Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.helenus.core.cache; + +import com.google.common.cache.CacheBuilder; + +import java.util.concurrent.TimeUnit; + +public interface SessionCache { + + static SessionCache defaultCache() { + int MAX_CACHE_SIZE = 10000; + int MAX_CACHE_EXPIRE_SECONDS = 600; + return new GuavaCache(CacheBuilder.newBuilder().maximumSize(MAX_CACHE_SIZE) + .expireAfterAccess(MAX_CACHE_EXPIRE_SECONDS, TimeUnit.SECONDS) + .expireAfterWrite(MAX_CACHE_EXPIRE_SECONDS, TimeUnit.SECONDS).recordStats().build()); + } + + void invalidate(K key); + V get(K key); + void put(K key, V value); +} From 7b14eda9b33f832ef4f2e98bda813b97a47e9d27 Mon Sep 17 00:00:00 2001 From: Greg Burd Date: Fri, 27 Oct 2017 14:00:24 -0400 Subject: [PATCH 12/18] More caching fixes. --- .../net/helenus/core/AbstractEntityDraft.java | 52 ++- .../java/net/helenus/core/HelenusSession.java | 103 ++--- .../net/helenus/core/cache/BoundFacet.java | 9 +- .../net/helenus/core/cache/CacheUtil.java | 24 +- .../operation/AbstractFilterOperation.java | 41 +- .../operation/AbstractOptionalOperation.java | 6 +- .../operation/AbstractStatementOperation.java | 18 +- .../operation/AbstractStreamOperation.java | 4 +- .../core/operation/DeleteOperation.java | 50 +-- .../core/operation/InsertOperation.java | 14 +- .../core/operation/SelectOperation.java | 2 +- .../core/operation/UpdateOperation.java | 376 ++++++++++++------ .../core/reflect/MapperInvocationHandler.java | 3 +- .../java/net/helenus/mapping/MappingUtil.java | 40 ++ .../core/unitofwork/UnitOfWorkTest.java | 97 +++-- 15 files changed, 555 insertions(+), 284 deletions(-) diff --git a/src/main/java/net/helenus/core/AbstractEntityDraft.java b/src/main/java/net/helenus/core/AbstractEntityDraft.java index 6c9bf9f..8479223 100644 --- a/src/main/java/net/helenus/core/AbstractEntityDraft.java +++ b/src/main/java/net/helenus/core/AbstractEntityDraft.java @@ -1,9 +1,7 @@ package net.helenus.core; -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; -import java.util.Set; +import java.io.Serializable; +import java.util.*; import com.google.common.primitives.Primitives; @@ -11,6 +9,7 @@ import net.helenus.core.reflect.DefaultPrimitiveTypes; import net.helenus.core.reflect.Drafted; import net.helenus.core.reflect.MapExportable; import net.helenus.mapping.MappingUtil; +import org.apache.commons.lang3.SerializationUtils; public abstract class AbstractEntityDraft implements Drafted { @@ -30,38 +29,49 @@ public abstract class AbstractEntityDraft implements Drafted { } @SuppressWarnings("unchecked") - protected T get(Getter getter, Class returnType) { + public T get(Getter getter, Class returnType) { return (T) get(this.methodNameFor(getter), returnType); } @SuppressWarnings("unchecked") - protected T get(String key, Class returnType) { + public T get(String key, Class returnType) { T value = (T) backingMap.get(key); if (value == null) { - value = (T) entityMap.get(key); - if (value == null) { + value = (T) entityMap.get(key); + if (value == null) { - if (Primitives.allPrimitiveTypes().contains(returnType)) { + if (Primitives.allPrimitiveTypes().contains(returnType)) { - DefaultPrimitiveTypes type = DefaultPrimitiveTypes.lookup(returnType); - if (type == null) { - throw new RuntimeException("unknown primitive type " + returnType); - } + DefaultPrimitiveTypes type = DefaultPrimitiveTypes.lookup(returnType); + if (type == null) { + throw new RuntimeException("unknown primitive type " + returnType); + } - return (T) type.getDefaultValue(); - } - } - } + return (T) type.getDefaultValue(); + } + } else { + // Collections fetched from the entityMap + if (value instanceof Collection) { + try { + value = MappingUtil.clone(value); + } + catch (CloneNotSupportedException e) { + //TODO(gburd): deep?shallow? copy of List, Map, Set to a mutable collection. + value = (T)SerializationUtils.clone((Serializable)value); + } + } + } + } return value; } - protected Object set(Getter getter, Object value) { + public Object set(Getter getter, Object value) { return set(this.methodNameFor(getter), value); } - protected Object set(String key, Object value) { + public Object set(String key, Object value) { if (key == null || value == null) { return null; } @@ -71,11 +81,11 @@ public abstract class AbstractEntityDraft implements Drafted { } @SuppressWarnings("unchecked") - protected T mutate(Getter getter, T value) { + public T mutate(Getter getter, T value) { return (T) mutate(this.methodNameFor(getter), value); } - protected Object mutate(String key, Object value) { + public Object mutate(String key, Object value) { Objects.requireNonNull(key); if (value == null) { diff --git a/src/main/java/net/helenus/core/HelenusSession.java b/src/main/java/net/helenus/core/HelenusSession.java index 58549ad..f827d6b 100644 --- a/src/main/java/net/helenus/core/HelenusSession.java +++ b/src/main/java/net/helenus/core/HelenusSession.java @@ -240,49 +240,48 @@ public final class HelenusSession extends AbstractSessionOperations implements C @Override public void mergeCache(Table>> uowCache) { - List>> items = uowCache.values().stream().distinct().collect(Collectors.toList()); - for (Either> item : items) { - if (item.isRight()) { - List facets = item.getRight(); - String tableName = CacheUtil.schemaName(facets); - List combinations = CacheUtil.flattenFacets(facets); - for (String[] combination : combinations) { - String cacheKey = tableName + "." + Arrays.toString(combination); - sessionCache.invalidate(cacheKey); - } - } else { - Object pojo = item.getLeft(); - HelenusEntity entity = Helenus.resolve(MappingUtil.getMappingInterface(pojo)); - Map valueMap = pojo instanceof MapExportable ? ((MapExportable) pojo).toMap() : null; - if (entity.isCacheable()) { - List boundFacets = new ArrayList<>(); - for (Facet facet : entity.getFacets()) { - if (facet instanceof UnboundFacet) { - UnboundFacet unboundFacet = (UnboundFacet) facet; - UnboundFacet.Binder binder = unboundFacet.binder(); - unboundFacet.getProperties().forEach(prop -> { - if (valueMap == null) { - Object value = BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop, - false); - binder.setValueForProperty(prop, value.toString()); - } else { - binder.setValueForProperty(prop, valueMap.get(prop.getPropertyName()).toString()); - } - }); - if (binder.isBound()) { - boundFacets.add(binder.bind()); - } - } else { - boundFacets.add(facet); - } - } - // NOTE: should equal `String tableName = CacheUtil.schemaName(facets);` - List facetCombinations = CacheUtil.flattenFacets(boundFacets); - String tableName = CacheUtil.schemaName(boundFacets); - mergeAndUpdateCacheValues(pojo, tableName, facetCombinations); - } - } - } + List items = uowCache.values().stream().filter(Either::isLeft).map(Either::getLeft).distinct().collect(Collectors.toList()); + for (Object pojo : items) { + HelenusEntity entity = Helenus.resolve(MappingUtil.getMappingInterface(pojo)); + Map valueMap = pojo instanceof MapExportable ? ((MapExportable) pojo).toMap() : null; + if (entity.isCacheable()) { + List boundFacets = new ArrayList<>(); + for (Facet facet : entity.getFacets()) { + if (facet instanceof UnboundFacet) { + UnboundFacet unboundFacet = (UnboundFacet) facet; + UnboundFacet.Binder binder = unboundFacet.binder(); + unboundFacet.getProperties().forEach(prop -> { + if (valueMap == null) { + Object value = BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop); + binder.setValueForProperty(prop, value.toString()); + } else { + binder.setValueForProperty(prop, valueMap.get(prop.getPropertyName()).toString()); + } + }); + if (binder.isBound()) { + boundFacets.add(binder.bind()); + } + } else { + boundFacets.add(facet); + } + } + // NOTE: should equal `String tableName = CacheUtil.schemaName(facets);` + List facetCombinations = CacheUtil.flattenFacets(boundFacets); + String tableName = CacheUtil.schemaName(boundFacets); + mergeAndUpdateCacheValues(pojo, tableName, facetCombinations); + } + } + + List> deletedFacetSets = uowCache.values().stream().filter(Either::isRight).map(Either::getRight).collect( + Collectors.toList()); + for (List facets : deletedFacetSets) { + String tableName = CacheUtil.schemaName(facets); + List combinations = CacheUtil.flattenFacets(facets); + for (String[] combination : combinations) { + String cacheKey = tableName + "." + Arrays.toString(combination); + sessionCache.invalidate(cacheKey); + } + } } private void mergeAndUpdateCacheValues(Object pojo, String tableName, List facetCombinations) { @@ -503,13 +502,21 @@ public final class HelenusSession extends AbstractSessionOperations implements C return new UpdateOperation(this); } + public UpdateOperation update(Object pojo) { + if (pojo instanceof MapExportable == false) { + throw new HelenusMappingException( + "update of objects that don't implement MapExportable is not yet supported"); + } + return new UpdateOperation(this, pojo); + } + public UpdateOperation update(Drafted drafted) { - if (drafted instanceof AbstractEntityDraft == false) { - throw new HelenusMappingException( - "update of draft objects that don't inherit from AbstractEntityDraft is not yet supported"); - } + if (drafted instanceof AbstractEntityDraft == false) { + throw new HelenusMappingException( + "update of draft objects that don't inherit from AbstractEntityDraft is not yet supported"); + } AbstractEntityDraft draft = (AbstractEntityDraft) drafted; - UpdateOperation update = new UpdateOperation(this, draft); + UpdateOperation update = new UpdateOperation(this, draft); Map map = draft.toMap(); Set mutatedProperties = draft.mutated(); HelenusEntity entity = Helenus.entity(draft.getEntityClass()); diff --git a/src/main/java/net/helenus/core/cache/BoundFacet.java b/src/main/java/net/helenus/core/cache/BoundFacet.java index 905a67f..48949ea 100644 --- a/src/main/java/net/helenus/core/cache/BoundFacet.java +++ b/src/main/java/net/helenus/core/cache/BoundFacet.java @@ -15,6 +15,7 @@ */ package net.helenus.core.cache; +import java.util.HashMap; import java.util.Map; import java.util.stream.Collectors; @@ -23,7 +24,13 @@ import net.helenus.mapping.HelenusProperty; public class BoundFacet extends Facet { private final Map properties; - BoundFacet(String name, Map properties) { + public BoundFacet(HelenusProperty property, Object value) { + super(property.getPropertyName(), value == null ? null : value.toString()); + this.properties = new HashMap(1); + this.properties.put(property, value); + } + + public BoundFacet(String name, Map properties) { super(name, (properties.keySet().size() > 1) ? "[" + String.join(", ", diff --git a/src/main/java/net/helenus/core/cache/CacheUtil.java b/src/main/java/net/helenus/core/cache/CacheUtil.java index 37dbc30..2b08e87 100644 --- a/src/main/java/net/helenus/core/cache/CacheUtil.java +++ b/src/main/java/net/helenus/core/cache/CacheUtil.java @@ -1,7 +1,14 @@ package net.helenus.core.cache; +import net.helenus.core.Helenus; +import net.helenus.core.reflect.MapExportable; +import net.helenus.mapping.HelenusEntity; +import net.helenus.mapping.MappingUtil; +import net.helenus.mapping.value.BeanColumnValueProvider; + import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.stream.Collectors; public class CacheUtil { @@ -38,7 +45,22 @@ public class CacheUtil { } public static Object merge(Object to, Object from) { - return to; // TODO(gburd): yeah... + if (to == from) { + return to; + } + + //TODO(gburd): take ttl and writeTime into account when merging. + Map toValueMap = to instanceof MapExportable ? ((MapExportable) to).toMap() : null; + Map fromValueMap = to instanceof MapExportable ? ((MapExportable) from).toMap() : null; + + if (toValueMap != null && fromValueMap != null) { + for (String key : fromValueMap.keySet()) { + if (toValueMap.containsKey(key) && toValueMap.get(key) != fromValueMap.get(key)) { + toValueMap.put(key, fromValueMap.get(key)); + } + } + } + return to; } public static String schemaName(List facets) { diff --git a/src/main/java/net/helenus/core/operation/AbstractFilterOperation.java b/src/main/java/net/helenus/core/operation/AbstractFilterOperation.java index 13de23e..6eec08d 100644 --- a/src/main/java/net/helenus/core/operation/AbstractFilterOperation.java +++ b/src/main/java/net/helenus/core/operation/AbstractFilterOperation.java @@ -15,10 +15,13 @@ */ package net.helenus.core.operation; -import java.util.LinkedList; -import java.util.List; +import java.util.*; import net.helenus.core.*; +import net.helenus.core.cache.Facet; +import net.helenus.core.cache.UnboundFacet; +import net.helenus.mapping.HelenusEntity; +import net.helenus.mapping.HelenusProperty; public abstract class AbstractFilterOperation> extends @@ -108,4 +111,38 @@ public abstract class AbstractFilterOperation bindFacetValues(List facets) { + if (facets == null) { + return new ArrayList(); + } + List boundFacets = new ArrayList<>(); + Map filterMap = new HashMap<>(filters.size()); + filters.forEach(f -> filterMap.put(f.getNode().getProperty(), f)); + + for (Facet facet : facets) { + if (facet instanceof UnboundFacet) { + UnboundFacet unboundFacet = (UnboundFacet) facet; + UnboundFacet.Binder binder = unboundFacet.binder(); + if (filters != null) { + for (HelenusProperty prop : unboundFacet.getProperties()) { + + Filter filter = filterMap.get(prop); + if (filter != null) { + Object[] postulates = filter.postulateValues(); + for (Object p : postulates) { + binder.setValueForProperty(prop, p.toString()); + } + } + } + + } + if (binder.isBound()) { + boundFacets.add(binder.bind()); + } + } else { + boundFacets.add(facet); + } + } + return boundFacets; + } } diff --git a/src/main/java/net/helenus/core/operation/AbstractOptionalOperation.java b/src/main/java/net/helenus/core/operation/AbstractOptionalOperation.java index 1591404..87a1bad 100644 --- a/src/main/java/net/helenus/core/operation/AbstractOptionalOperation.java +++ b/src/main/java/net/helenus/core/operation/AbstractOptionalOperation.java @@ -66,9 +66,9 @@ public abstract class AbstractOptionalOperation result = Optional.empty(); E cacheResult = null; - boolean updateCache = isSessionCacheable(); + boolean updateCache = isSessionCacheable() && checkCache; - if (enableCache && isSessionCacheable()) { + if (checkCache && isSessionCacheable()) { List facets = bindFacetValues(); String tableName = CacheUtil.schemaName(facets); cacheResult = (E) sessionOps.checkCache(tableName, facets); @@ -115,7 +115,7 @@ public abstract class AbstractOptionalOperation facets = bindFacetValues(); diff --git a/src/main/java/net/helenus/core/operation/AbstractStatementOperation.java b/src/main/java/net/helenus/core/operation/AbstractStatementOperation.java index 579a136..34a1da3 100644 --- a/src/main/java/net/helenus/core/operation/AbstractStatementOperation.java +++ b/src/main/java/net/helenus/core/operation/AbstractStatementOperation.java @@ -45,7 +45,7 @@ import net.helenus.support.HelenusException; public abstract class AbstractStatementOperation> extends Operation { - protected boolean enableCache = true; + protected boolean checkCache = true; protected boolean showValues = true; protected TraceContext traceContext; long queryExecutionTimeout = 10; @@ -66,13 +66,13 @@ public abstract class AbstractStatementOperation facets = new ArrayList<>(); Map valueMap = pojo instanceof MapExportable ? ((MapExportable) pojo).toMap() : null; - for (Facet facet : identifyingFacets) { - if (facet instanceof UnboundFacet) { - UnboundFacet unboundFacet = (UnboundFacet) facet; - UnboundFacet.Binder binder = unboundFacet.binder(); + for (Facet facet : identifyingFacets) { + if (facet instanceof UnboundFacet) { + UnboundFacet unboundFacet = (UnboundFacet) facet; + UnboundFacet.Binder binder = unboundFacet.binder(); for (HelenusProperty prop : unboundFacet.getProperties()) { Object value; if (valueMap == null) { diff --git a/src/main/java/net/helenus/core/operation/AbstractStreamOperation.java b/src/main/java/net/helenus/core/operation/AbstractStreamOperation.java index 749f0ff..f7dd6aa 100644 --- a/src/main/java/net/helenus/core/operation/AbstractStreamOperation.java +++ b/src/main/java/net/helenus/core/operation/AbstractStreamOperation.java @@ -69,7 +69,7 @@ public abstract class AbstractStreamOperation facets = bindFacetValues(); String tableName = CacheUtil.schemaName(facets); cacheResult = (E) sessionOps.checkCache(tableName, facets); @@ -121,7 +121,7 @@ public abstract class AbstractStreamOperation facets = bindFacetValues(); diff --git a/src/main/java/net/helenus/core/operation/DeleteOperation.java b/src/main/java/net/helenus/core/operation/DeleteOperation.java index 9375a30..e17e0a4 100644 --- a/src/main/java/net/helenus/core/operation/DeleteOperation.java +++ b/src/main/java/net/helenus/core/operation/DeleteOperation.java @@ -133,40 +133,9 @@ public final class DeleteOperation extends AbstractFilterOperation bindFacetValues(List facets) { - if (facets == null) { - return new ArrayList(); - } - List boundFacets = new ArrayList<>(); - Map filterMap = new HashMap<>(filters.size()); - filters.forEach(f -> filterMap.put(f.getNode().getProperty(), f)); - - for (Facet facet : facets) { - if (facet instanceof UnboundFacet) { - UnboundFacet unboundFacet = (UnboundFacet) facet; - UnboundFacet.Binder binder = unboundFacet.binder(); - if (filters != null) { - for (HelenusProperty prop : unboundFacet.getProperties()) { - - Filter filter = filterMap.get(prop); - if (filter != null) { - Object[] postulates = filter.postulateValues(); - for (Object p : postulates) { - binder.setValueForProperty(prop, p.toString()); - } - } - } - - } - if (binder.isBound()) { - boundFacets.add(binder.bind()); - } - } else { - boundFacets.add(facet); - } - } - return boundFacets; - } + public List bindFacetValues() { + return bindFacetValues(getFacets()); + } @Override public ResultSet sync() throws TimeoutException { @@ -177,20 +146,19 @@ public final class DeleteOperation extends AbstractFilterOperation getFacets() { - return entity.getFacets(); - } - @Override public ResultSet sync(UnitOfWork uow) throws TimeoutException { if (uow == null) { return sync(); } ResultSet result = super.sync(uow); - List facets = getFacets(); - uow.cacheEvict(bindFacetValues(facets)); + uow.cacheEvict(bindFacetValues()); return result; } + @Override + public List getFacets() { + return entity.getFacets(); + } + } diff --git a/src/main/java/net/helenus/core/operation/InsertOperation.java b/src/main/java/net/helenus/core/operation/InsertOperation.java index 89fb3c3..ff7d3ce 100644 --- a/src/main/java/net/helenus/core/operation/InsertOperation.java +++ b/src/main/java/net/helenus/core/operation/InsertOperation.java @@ -44,7 +44,7 @@ public final class InsertOperation extends AbstractOperation> values = new ArrayList>(); private final T pojo; - private final Class resultType; + private final Class resultType; private HelenusEntity entity; private boolean ifNotExists; @@ -56,7 +56,7 @@ public final class InsertOperation extends AbstractOperation resultType, boolean ifNotExists) { @@ -251,10 +251,14 @@ public final class InsertOperation extends AbstractOperation iface = entity.getMappingInterface(); - if (resultType == iface) { + Class iface = entity.getMappingInterface(); + if (resultType == iface) { cacheUpdate(uow, result, entity.getFacets()); - } + } else { + if (entity.isCacheable()) { + sessionOps.cacheEvict(bindFacetValues()); + } + } return result; } diff --git a/src/main/java/net/helenus/core/operation/SelectOperation.java b/src/main/java/net/helenus/core/operation/SelectOperation.java index 497868b..fd05b22 100644 --- a/src/main/java/net/helenus/core/operation/SelectOperation.java +++ b/src/main/java/net/helenus/core/operation/SelectOperation.java @@ -207,7 +207,7 @@ public final class SelectOperation extends AbstractFilterStreamOperation extends AbstractFilterOperation> { - private final List assignments = new ArrayList(); + private final Map assignments = new HashMap<>(); private final AbstractEntityDraft draft; private final Map draftMap; private HelenusEntity entity = null; + private Object pojo; private int[] ttl; private long[] timestamp; @@ -55,24 +61,47 @@ public final class UpdateOperation extends AbstractFilterOperation UpdateOperation set(Getter getter, V v) { + addPropertyNode(p); + } + + public UpdateOperation set(Getter getter, V v) { Objects.requireNonNull(getter, "getter is empty"); HelenusPropertyNode p = MappingUtil.resolveMappingProperty(getter); + HelenusProperty prop = p.getProperty(); - Object value = sessionOps.getValuePreparer().prepareColumnValue(v, p.getProperty()); - assignments.add(QueryBuilder.set(p.getColumnName(), value)); + Object value = sessionOps.getValuePreparer().prepareColumnValue(v, prop); + assignments.put(QueryBuilder.set(p.getColumnName(), value), new BoundFacet(prop, value)); + + if (draft != null) { + String key = prop.getPropertyName(); + if (draft.get(key, value.getClass()) != value) { + draft.set(key, value); + } + } + + if (pojo != null && pojo instanceof MapExportable) { + String key = prop.getPropertyName(); + Map map = ((MapExportable)pojo).toMap(); + if (map.get(key) != value) { + map.put(key, value); + } + } addPropertyNode(p); @@ -97,15 +126,20 @@ public final class UpdateOperation extends AbstractFilterOperation extends AbstractFilterOperation extends AbstractFilterOperation list = new ArrayList((List)BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop)); + list.add(0, value); + facet = new BoundFacet(prop, list); + } else if (draft != null) { + String key = p.getProperty().getPropertyName(); + List list = (List) draftMap.get(key); + list.add(0, value); + } + + assignments.put(QueryBuilder.prepend(p.getColumnName(), valueObj), facet); addPropertyNode(p); - if (draft != null) { - String key = p.getProperty().getPropertyName(); - List list = (List) draftMap.get(key); - list.add(0, value); - } - return this; } @@ -167,16 +212,22 @@ public final class UpdateOperation extends AbstractFilterOperation list = new ArrayList((List)BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop)); + list.addAll(0, value); + facet = new BoundFacet(prop, list); + } else if (draft != null && value.size() > 0) { + String key = p.getProperty().getPropertyName(); + List list = (List) draftMap.get(key); + list.addAll(0, value); + } + + assignments.put(QueryBuilder.prependAll(p.getColumnName(), valueObj), facet); addPropertyNode(p); - if (draft != null && value.size() > 0) { - String key = p.getProperty().getPropertyName(); - List list = (List) draftMap.get(key); - list.addAll(0, value); - } - return this; } @@ -188,23 +239,31 @@ public final class UpdateOperation extends AbstractFilterOperation list; + HelenusProperty prop = p.getProperty(); + if (pojo != null) { + list = new ArrayList((List) BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop)); + } else { + String key = p.getProperty().getPropertyName(); + list = (List) draftMap.get(key); + } + if (idx < 0) { + list.add(0, value); + } else if (idx > list.size()) { + list.add(list.size(), value); + } else { + list.add(idx, value); + } + list.add(0, value); + facet = new BoundFacet(prop, list); + } + + assignments.put(QueryBuilder.setIdx(p.getColumnName(), idx, valueObj), facet); addPropertyNode(p); - if (draft != null) { - String key = p.getProperty().getPropertyName(); - List list = (List) draftMap.get(key); - if (idx < 0) { - list.add(0, value); - } else if (idx > list.size()) { - list.add(list.size(), value); - } else { - list.add(idx, value); - } - list.add(0, value); - } - return this; } @@ -216,16 +275,21 @@ public final class UpdateOperation extends AbstractFilterOperation list = new ArrayList((List)BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop)); + list.add(value); + facet = new BoundFacet(prop, list); + } else if (draft != null) { + String key = p.getProperty().getPropertyName(); + List list = (List) draftMap.get(key); + list.add(value); + } + assignments.put(QueryBuilder.append(p.getColumnName(), valueObj), facet); addPropertyNode(p); - if (draft != null) { - String key = p.getProperty().getPropertyName(); - List list = (List) draftMap.get(key); - list.add(value); - } - return this; } @@ -237,16 +301,21 @@ public final class UpdateOperation extends AbstractFilterOperation list = new ArrayList((List)BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop)); + list.addAll(value); + facet = new BoundFacet(prop, list); + } else if (draft != null && value.size() > 0) { + String key = p.getProperty().getPropertyName(); + List list = (List) draftMap.get(key); + list.addAll(value); + } + assignments.put(QueryBuilder.appendAll(p.getColumnName(), valueObj), facet); addPropertyNode(p); - if (draft != null && value.size() > 0) { - String key = p.getProperty().getPropertyName(); - List list = (List) draftMap.get(key); - list.addAll(value); - } - return this; } @@ -258,16 +327,21 @@ public final class UpdateOperation extends AbstractFilterOperation list = new ArrayList((List)BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop)); + list.remove(value); + facet = new BoundFacet(prop, list); + } else if (draft != null) { + String key = p.getProperty().getPropertyName(); + List list = (List) draftMap.get(key); + list.remove(value); + } + assignments.put(QueryBuilder.discard(p.getColumnName(), valueObj), facet); addPropertyNode(p); - if (draft != null) { - String key = p.getProperty().getPropertyName(); - List list = (List) draftMap.get(key); - list.remove(value); - } - return this; } @@ -279,16 +353,21 @@ public final class UpdateOperation extends AbstractFilterOperation list = new ArrayList((List)BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop)); + list.removeAll(value); + facet = new BoundFacet(prop, list); + } else if (draft != null) { + String key = p.getProperty().getPropertyName(); + List list = (List) draftMap.get(key); + list.removeAll(value); + } + assignments.put(QueryBuilder.discardAll(p.getColumnName(), valueObj), facet); addPropertyNode(p); - if (draft != null) { - String key = p.getProperty().getPropertyName(); - List list = (List) draftMap.get(key); - list.removeAll(value); - } - return this; } @@ -336,16 +415,21 @@ public final class UpdateOperation extends AbstractFilterOperation set = new HashSet((Set)BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop)); + set.add(value); + facet = new BoundFacet(prop, set); + } else if (draft != null) { + String key = p.getProperty().getPropertyName(); + Set set = (Set) draftMap.get(key); + set.add(value); + } + assignments.put(QueryBuilder.add(p.getColumnName(), valueObj), facet); addPropertyNode(p); - if (draft != null) { - String key = p.getProperty().getPropertyName(); - Set set = (Set) draftMap.get(key); - set.add(value); - } - return this; } @@ -357,16 +441,21 @@ public final class UpdateOperation extends AbstractFilterOperation set = new HashSet((Set)BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop)); + set.addAll(value); + facet = new BoundFacet(prop, set); + } else if (draft != null) { + String key = p.getProperty().getPropertyName(); + Set set = (Set) draftMap.get(key); + set.addAll(value); + } + assignments.put(QueryBuilder.addAll(p.getColumnName(), valueObj), facet); addPropertyNode(p); - if (draft != null) { - String key = p.getProperty().getPropertyName(); - Set set = (Set) draftMap.get(key); - set.addAll(value); - } - return this; } @@ -378,16 +467,21 @@ public final class UpdateOperation extends AbstractFilterOperation set = new HashSet((Set)BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop)); + set.remove(value); + facet = new BoundFacet(prop, set); + } else if (draft != null) { + String key = p.getProperty().getPropertyName(); + Set set = (Set) draftMap.get(key); + set.remove(value); + } + assignments.put(QueryBuilder.remove(p.getColumnName(), valueObj), facet); addPropertyNode(p); - if (draft != null) { - String key = p.getProperty().getPropertyName(); - Set set = (Set) draftMap.get(key); - set.remove(value); - } - return this; } @@ -399,16 +493,21 @@ public final class UpdateOperation extends AbstractFilterOperation set = new HashSet((Set)BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop)); + set.removeAll(value); + facet = new BoundFacet(prop, set); + } else if (draft != null) { + String key = p.getProperty().getPropertyName(); + Set set = (Set) draftMap.get(key); + set.removeAll(value); + } + assignments.put(QueryBuilder.removeAll(p.getColumnName(), valueObj), facet); addPropertyNode(p); - if (draft != null) { - String key = p.getProperty().getPropertyName(); - Set set = (Set) draftMap.get(key); - set.removeAll(value); - } - return this; } @@ -455,23 +554,28 @@ public final class UpdateOperation extends AbstractFilterOperation map = new HashMap((Map)BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop)); + map.put(key, value); + facet = new BoundFacet(prop, map); + } else if (draft != null) { + ((Map) draftMap.get(prop.getPropertyName())).put(key, value); + } + Optional> converter = prop.getWriteConverter(sessionOps.getSessionRepository()); if (converter.isPresent()) { Map convertedMap = (Map) converter.get() .apply(Immutables.mapOf(key, value)); for (Map.Entry e : convertedMap.entrySet()) { - assignments.add(QueryBuilder.put(p.getColumnName(), e.getKey(), e.getValue())); + assignments.put(QueryBuilder.put(p.getColumnName(), e.getKey(), e.getValue()), facet); } } else { - assignments.add(QueryBuilder.put(p.getColumnName(), key, value)); + assignments.put(QueryBuilder.put(p.getColumnName(), key, value), facet); } addPropertyNode(p); - if (draft != null) { - ((Map) draftMap.get(prop.getPropertyName())).put(key, value); - } - return this; } @@ -483,20 +587,25 @@ public final class UpdateOperation extends AbstractFilterOperation newMap = new HashMap((Map)BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop)); + newMap.putAll(map); + facet = new BoundFacet(prop, newMap); + } else if (draft != null) { + ((Map) draftMap.get(prop.getPropertyName())).putAll(map); + } + Optional> converter = prop.getWriteConverter(sessionOps.getSessionRepository()); if (converter.isPresent()) { Map convertedMap = (Map) converter.get().apply(map); - assignments.add(QueryBuilder.putAll(p.getColumnName(), convertedMap)); + assignments.put(QueryBuilder.putAll(p.getColumnName(), convertedMap), facet); } else { - assignments.add(QueryBuilder.putAll(p.getColumnName(), map)); + assignments.put(QueryBuilder.putAll(p.getColumnName(), map), facet); } addPropertyNode(p); - if (draft != null) { - ((Map) draftMap.get(prop.getPropertyName())).putAll(map); - } - return this; } @@ -509,7 +618,7 @@ public final class UpdateOperation extends AbstractFilterOperation extends AbstractFilterOperation extends AbstractFilterOperation bindFacetValues() { + List facets = bindFacetValues(entity.getFacets()); + facets.addAll(assignments.values().stream().distinct().filter(o -> o != null).collect(Collectors.toList())); + return facets; + } + + @Override public List getFacets() { if (entity != null) { return entity.getFacets(); diff --git a/src/main/java/net/helenus/core/reflect/MapperInvocationHandler.java b/src/main/java/net/helenus/core/reflect/MapperInvocationHandler.java index e45b6f7..42af52a 100644 --- a/src/main/java/net/helenus/core/reflect/MapperInvocationHandler.java +++ b/src/main/java/net/helenus/core/reflect/MapperInvocationHandler.java @@ -102,7 +102,8 @@ public class MapperInvocationHandler implements InvocationHandler, Serializab } if (MapExportable.TO_MAP_METHOD.equals(methodName)) { - return Collections.unmodifiableMap(src); + //return Collections.unmodifiableMap(src); + return src; } Object value = src.get(methodName); diff --git a/src/main/java/net/helenus/mapping/MappingUtil.java b/src/main/java/net/helenus/mapping/MappingUtil.java index 8eadfac..f554b72 100644 --- a/src/main/java/net/helenus/mapping/MappingUtil.java +++ b/src/main/java/net/helenus/mapping/MappingUtil.java @@ -16,6 +16,7 @@ package net.helenus.mapping; import java.lang.annotation.Annotation; +import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; @@ -282,4 +283,43 @@ public final class MappingUtil { return e.getPropertyNode(); } } + + // https://stackoverflow.com/a/4882306/366692 + public static T clone(T object) + throws CloneNotSupportedException { + Object clone = null; + + // Use reflection, because there is no other way + try { + Method method = object.getClass().getMethod("clone"); + clone = method.invoke(object); + } catch (InvocationTargetException e) { + rethrow(e.getCause()); + } catch (Exception cause) { + rethrow(cause); + } + if (object.getClass().isInstance(clone)) { + @SuppressWarnings("unchecked") // clone class <= object class <= T + T t = (T) clone; + return t; + } else { + throw new ClassCastException(clone.getClass().getName()); + } + } + + private static void rethrow(Throwable cause) + throws CloneNotSupportedException { + if (cause instanceof RuntimeException) { + throw (RuntimeException) cause; + } + if (cause instanceof Error) { + throw (Error) cause; + } + if (cause instanceof CloneNotSupportedException) { + throw (CloneNotSupportedException) cause; + } + CloneNotSupportedException e = new CloneNotSupportedException(); + e.initCause(cause); + throw e; + } } diff --git a/src/test/java/net/helenus/test/integration/core/unitofwork/UnitOfWorkTest.java b/src/test/java/net/helenus/test/integration/core/unitofwork/UnitOfWorkTest.java index 328fb67..2369393 100644 --- a/src/test/java/net/helenus/test/integration/core/unitofwork/UnitOfWorkTest.java +++ b/src/test/java/net/helenus/test/integration/core/unitofwork/UnitOfWorkTest.java @@ -140,41 +140,92 @@ public class UnitOfWorkTest extends AbstractEmbeddedCassandraTest { }); } } - @Test - public void testSelectAfterDeleted() throws Exception { - Widget w1, w2, w3, w4; - UUID key = UUIDs.timeBased(); - // This should inserted Widget, but not cache it. - w1 = session.insert(widget).value(widget::id, key).value(widget::name, RandomString.make(20)).sync(); + @Test + public void testSelectAfterUpdated() throws Exception { + Widget w1, w2, w3, w4, w5, w6; + UUID key = UUIDs.timeBased(); - try (UnitOfWork uow = session.begin()) { + // This should inserted Widget, but not cache it. + w1 = session.insert(widget).value(widget::id, key).value(widget::name, RandomString.make(20)).sync(); - // This should read from the database and return a Widget. - w2 = session.select(widget).where(widget::id, eq(key)).single() + try (UnitOfWork uow = session.begin()) { + + // This should read from the database and return a Widget. + w2 = session.select(widget).where(widget::id, eq(key)).single() .sync(uow).orElse(null); + Assert.assertEquals(w1, w2); - // This should remove the object from the cache. - session.delete(widget).where(widget::id, eq(key)) + // This should remove the object from the cache. + //TODO(gburd): w3 = session. + session.update(w2) + .set(widget::name, "Bill") + .where(widget::id, eq(key)) .sync(uow); - // This should fail to read from the cache. - w3 = session.select(widget).where(widget::id, eq(key)).single() + // Fetch from session cache, should have old name. + w4 = session.select(widget).where(widget::id, eq(key)).single() + .sync().orElse(null); + Assert.assertEquals(w4, w2); + Assert.assertEquals(w4.name(), w1.name()); + + // This should skip the cache. + w5 = session.select(widget).where(widget::id, eq(key)).single() + .uncached() + .sync().orElse(null); + + Assert.assertNotEquals(w5, w2); // Not the same instance + Assert.assertTrue(w2.equals(w5)); // But they have the same values + Assert.assertFalse(w5.equals(w2)); // TODO(gburd): should also work + Assert.assertEquals(w5.name(), "Bill"); + + uow.commit().andThen(() -> { + Assert.assertEquals(w1, w2); + }); + } + + // The name changed, this should miss cache and not find anything in the database. + w6 = session.select(widget).where(widget::name, eq(w1.name())).single() + .sync().orElse(null); + Assert.assertTrue(w2.equals(w5)); + } + + + @Test + public void testSelectAfterDeleted() throws Exception { + Widget w1, w2, w3, w4; + UUID key = UUIDs.timeBased(); + + // This should inserted Widget, but not cache it. + w1 = session.insert(widget).value(widget::id, key).value(widget::name, RandomString.make(20)).sync(); + + try (UnitOfWork uow = session.begin()) { + + // This should read from the database and return a Widget. + w2 = session.select(widget).where(widget::id, eq(key)).single() .sync(uow).orElse(null); - Assert.assertEquals(w3, null); + // This should remove the object from the cache. + session.delete(widget).where(widget::id, eq(key)) + .sync(uow); - uow.commit().andThen(() -> { - Assert.assertEquals(w1, w2); - Assert.assertEquals(w3, null); - }); - } + // This should fail to read from the cache. + w3 = session.select(widget).where(widget::id, eq(key)).single() + .sync(uow).orElse(null); - w4 = session.select(widget).where(widget::name, eq(w1.name())).single() + Assert.assertEquals(w3, null); + + uow.commit().andThen(() -> { + Assert.assertEquals(w1, w2); + Assert.assertEquals(w3, null); + }); + } + + w4 = session.select(widget).where(widget::name, eq(w1.name())).single() .sync().orElse(null); - Assert.assertEquals(w4, null); - } + Assert.assertEquals(w4, null); + } /* * @Test public void testSelectAfterInsertProperlyCachesEntity() throws @@ -200,7 +251,7 @@ public class UnitOfWorkTest extends AbstractEmbeddedCassandraTest { * * // This should read the widget from the database, no object identity but * values should match. w4 = session.select(widget) .where(widget::id, - * eq(key)) .ignoreCache() .single() .sync() .orElse(null); + * eq(key)) .uncached() .single() .sync() .orElse(null); * * Assert.assertNotEquals(w1, w4); Assert.assertTrue(w1.equals(w4)); } */ From a65b775faa96b4688257efdb7ea0438b3a8fe603 Mon Sep 17 00:00:00 2001 From: Greg Burd Date: Fri, 27 Oct 2017 14:33:04 -0400 Subject: [PATCH 13/18] Abstract the SessionCache and allow outside implementations. --- helenus-core.iml | 5 --- pom.xml | 14 ------ .../java/net/helenus/core/HelenusSession.java | 2 +- .../net/helenus/core/SessionInitializer.java | 11 ++++- .../net/helenus/core/cache/CaffeineCache.java | 43 ------------------- .../helenus/core/cache/MemcacheDbCache.java | 41 ------------------ .../net/helenus/core/cache/RedisCache.java | 41 ------------------ .../core/operation/UpdateOperation.java | 16 ++++--- 8 files changed, 21 insertions(+), 152 deletions(-) delete mode 100644 src/main/java/net/helenus/core/cache/CaffeineCache.java delete mode 100644 src/main/java/net/helenus/core/cache/MemcacheDbCache.java delete mode 100644 src/main/java/net/helenus/core/cache/RedisCache.java diff --git a/helenus-core.iml b/helenus-core.iml index fdf1252..be96637 100644 --- a/helenus-core.iml +++ b/helenus-core.iml @@ -125,11 +125,6 @@ - - - - - diff --git a/pom.xml b/pom.xml index 4579ff7..71feca8 100644 --- a/pom.xml +++ b/pom.xml @@ -259,20 +259,6 @@ test - - - com.github.ben-manes.caffeine - jcache - 2.5.6 - test - - - - net.spy - spymemcached - 2.12.3 - - org.slf4j diff --git a/src/main/java/net/helenus/core/HelenusSession.java b/src/main/java/net/helenus/core/HelenusSession.java index 2e7ee3d..e67b387 100644 --- a/src/main/java/net/helenus/core/HelenusSession.java +++ b/src/main/java/net/helenus/core/HelenusSession.java @@ -190,7 +190,7 @@ public final class HelenusSession extends AbstractSessionOperations implements C Object result = null; for (String[] combination : facetCombinations) { String cacheKey = tableName + "." + Arrays.toString(combination); - result = sessionCache.getIfPresent(cacheKey); + result = sessionCache.get(cacheKey); if (result != null) { return result; } diff --git a/src/main/java/net/helenus/core/SessionInitializer.java b/src/main/java/net/helenus/core/SessionInitializer.java index d131b7c..d5c4117 100644 --- a/src/main/java/net/helenus/core/SessionInitializer.java +++ b/src/main/java/net/helenus/core/SessionInitializer.java @@ -27,6 +27,7 @@ import com.datastax.driver.core.*; import com.google.common.util.concurrent.MoreExecutors; import brave.Tracer; +import net.helenus.core.cache.SessionCache; import net.helenus.core.reflect.DslExportable; import net.helenus.mapping.HelenusEntity; import net.helenus.mapping.HelenusEntityType; @@ -56,6 +57,7 @@ public final class SessionInitializer extends AbstractSessionOperations { private boolean dropUnusedIndexes = false; private KeyspaceMetadata keyspaceMetadata; private AutoDdl autoDdl = AutoDdl.UPDATE; + private SessionCache sessionCache = null; SessionInitializer(Session session) { this.session = Objects.requireNonNull(session, "empty session"); @@ -123,6 +125,11 @@ public final class SessionInitializer extends AbstractSessionOperations { return this; } + public SessionInitializer setSessionCache(SessionCache sessionCache) { + this.sessionCache = sessionCache; + return this; + } + public ConsistencyLevel getDefaultConsistencyLevel() { return consistencyLevel; } @@ -243,8 +250,8 @@ public final class SessionInitializer extends AbstractSessionOperations { public synchronized HelenusSession get() { initialize(); return new HelenusSession(session, usingKeyspace, registry, showCql, printStream, sessionRepository, executor, - autoDdl == AutoDdl.CREATE_DROP, consistencyLevel, idempotent, unitOfWorkClass, metricRegistry, - zipkinTracer); + autoDdl == AutoDdl.CREATE_DROP, consistencyLevel, idempotent, unitOfWorkClass, sessionCache, + metricRegistry, zipkinTracer); } private void initialize() { diff --git a/src/main/java/net/helenus/core/cache/CaffeineCache.java b/src/main/java/net/helenus/core/cache/CaffeineCache.java deleted file mode 100644 index 0f5a9a4..0000000 --- a/src/main/java/net/helenus/core/cache/CaffeineCache.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2015 The Helenus Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.helenus.core.cache; - -public class CaffeineCache implements SessionCache { - - - final Cache cache; - - CaffeineCache(Cache cache) { - this.cache = cache; - } - - @Override - public void invalidate(K key) { - cache.invalidate(key); - } - - @Override - public V get(K key) { - return cache.getIfPresent(key); - } - - @Override - public void put(K key, V value) { - cache.put(key, value); - } - -} diff --git a/src/main/java/net/helenus/core/cache/MemcacheDbCache.java b/src/main/java/net/helenus/core/cache/MemcacheDbCache.java deleted file mode 100644 index 4f9a09c..0000000 --- a/src/main/java/net/helenus/core/cache/MemcacheDbCache.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2015 The Helenus Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.helenus.core.cache; - -public class MemcacheDbCache implements SessionCache { - //final Cache cache; - - MemcacheDbCache() { - //this.cache = cache; - } - - @Override - public void invalidate(K key) { - //cache.invalidate(key); - } - - @Override - public V get(K key) { - return null; - } - - @Override - public void put(K key, V value) { - //cache.put(key, value); - } - -} diff --git a/src/main/java/net/helenus/core/cache/RedisCache.java b/src/main/java/net/helenus/core/cache/RedisCache.java deleted file mode 100644 index 6d11aa5..0000000 --- a/src/main/java/net/helenus/core/cache/RedisCache.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2015 The Helenus Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.helenus.core.cache; - -public class RedisCache implements SessionCache { - //final Cache cache; - - RedisCache() { - //this.cache = cache; - } - - @Override - public void invalidate(K key) { - //cache.invalidate(key); - } - - @Override - public V get(K key) { - return null; - } - - @Override - public void put(K key, V value) { - //cache.put(key, value); - } - -} diff --git a/src/main/java/net/helenus/core/operation/UpdateOperation.java b/src/main/java/net/helenus/core/operation/UpdateOperation.java index 44e1de9..40edffb 100644 --- a/src/main/java/net/helenus/core/operation/UpdateOperation.java +++ b/src/main/java/net/helenus/core/operation/UpdateOperation.java @@ -36,6 +36,7 @@ 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.HelenusMappingException; import net.helenus.support.Immutables; @@ -66,6 +67,7 @@ public final class UpdateOperation extends AbstractFilterOperation extends AbstractFilterOperation map = ((MapExportable)pojo).toMap(); - if (map.get(key) != value) { - map.put(key, value); + if (entity != null) { + if (entity.isCacheable() && pojo != null && pojo instanceof MapExportable) { + String key = prop.getPropertyName(); + Map map = ((MapExportable) pojo).toMap(); + if (!(map instanceof ValueProviderMap)) { + if (map.get(key) != value) { + map.put(key, value); + } + } } } From 52dab5872c34c4b3a85fd8e24c47413ef7545fcc Mon Sep 17 00:00:00 2001 From: Greg Burd Date: Fri, 27 Oct 2017 15:05:08 -0400 Subject: [PATCH 14/18] Formatting. Also, need to redo merge so as to avoid ValueProviderMap immutability. --- .../net/helenus/core/AbstractEntityDraft.java | 47 +- .../net/helenus/core/AbstractUnitOfWork.java | 4 +- .../java/net/helenus/core/HelenusSession.java | 120 +++-- .../net/helenus/core/SessionInitializer.java | 8 +- .../net/helenus/core/cache/BoundFacet.java | 8 +- .../net/helenus/core/cache/CacheUtil.java | 37 +- .../net/helenus/core/cache/GuavaCache.java | 32 +- .../net/helenus/core/cache/SessionCache.java | 24 +- .../operation/AbstractFilterOperation.java | 63 ++- .../operation/AbstractStatementOperation.java | 8 +- .../core/operation/DeleteOperation.java | 17 +- .../core/operation/InsertOperation.java | 16 +- .../core/operation/SelectOperation.java | 2 +- .../core/operation/UpdateOperation.java | 449 +++++++++--------- .../core/reflect/MapperInvocationHandler.java | 5 +- .../java/net/helenus/mapping/MappingUtil.java | 68 ++- 16 files changed, 449 insertions(+), 459 deletions(-) diff --git a/src/main/java/net/helenus/core/AbstractEntityDraft.java b/src/main/java/net/helenus/core/AbstractEntityDraft.java index 8479223..1bfd2d1 100644 --- a/src/main/java/net/helenus/core/AbstractEntityDraft.java +++ b/src/main/java/net/helenus/core/AbstractEntityDraft.java @@ -3,13 +3,15 @@ package net.helenus.core; import java.io.Serializable; import java.util.*; +import net.helenus.mapping.value.ValueProviderMap; +import org.apache.commons.lang3.SerializationUtils; + import com.google.common.primitives.Primitives; import net.helenus.core.reflect.DefaultPrimitiveTypes; import net.helenus.core.reflect.Drafted; import net.helenus.core.reflect.MapExportable; import net.helenus.mapping.MappingUtil; -import org.apache.commons.lang3.SerializationUtils; public abstract class AbstractEntityDraft implements Drafted { @@ -38,31 +40,30 @@ public abstract class AbstractEntityDraft implements Drafted { T value = (T) backingMap.get(key); if (value == null) { - value = (T) entityMap.get(key); - if (value == null) { + value = (T) entityMap.get(key); + if (value == null) { - if (Primitives.allPrimitiveTypes().contains(returnType)) { + if (Primitives.allPrimitiveTypes().contains(returnType)) { - DefaultPrimitiveTypes type = DefaultPrimitiveTypes.lookup(returnType); - if (type == null) { - throw new RuntimeException("unknown primitive type " + returnType); - } + DefaultPrimitiveTypes type = DefaultPrimitiveTypes.lookup(returnType); + if (type == null) { + throw new RuntimeException("unknown primitive type " + returnType); + } - return (T) type.getDefaultValue(); - } - } else { - // Collections fetched from the entityMap - if (value instanceof Collection) { - try { - value = MappingUtil.clone(value); - } - catch (CloneNotSupportedException e) { - //TODO(gburd): deep?shallow? copy of List, Map, Set to a mutable collection. - value = (T)SerializationUtils.clone((Serializable)value); - } - } - } - } + return (T) type.getDefaultValue(); + } + } else { + // Collections fetched from the entityMap + if (value instanceof Collection) { + try { + value = MappingUtil.clone(value); + } catch (CloneNotSupportedException e) { + // TODO(gburd): deep?shallow? copy of List, Map, Set to a mutable collection. + value = (T) SerializationUtils.clone((Serializable) value); + } + } + } + } return value; } diff --git a/src/main/java/net/helenus/core/AbstractUnitOfWork.java b/src/main/java/net/helenus/core/AbstractUnitOfWork.java index c2d7013..9182054 100644 --- a/src/main/java/net/helenus/core/AbstractUnitOfWork.java +++ b/src/main/java/net/helenus/core/AbstractUnitOfWork.java @@ -86,7 +86,7 @@ public abstract class AbstractUnitOfWork implements UnitOfW @Override public synchronized UnitOfWork begin() { elapsedTime = Stopwatch.createStarted(); - // log.recordCacheAndDatabaseOperationCount(txn::start) + // log.record(txn::start) return this; } @@ -306,7 +306,7 @@ public abstract class AbstractUnitOfWork implements UnitOfW uow.committed = false; uow.aborted = true; }); - // log.recordCacheAndDatabaseOperationCount(txn::abort) + // log.record(txn::abort) // cache.invalidateSince(txn::start time) if (!hasAborted()) { elapsedTime.stop(); diff --git a/src/main/java/net/helenus/core/HelenusSession.java b/src/main/java/net/helenus/core/HelenusSession.java index e67b387..7dd63e9 100644 --- a/src/main/java/net/helenus/core/HelenusSession.java +++ b/src/main/java/net/helenus/core/HelenusSession.java @@ -23,23 +23,20 @@ import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.util.*; import java.util.concurrent.Executor; -import java.util.concurrent.TimeUnit; import java.util.function.Function; import java.util.stream.Collectors; -import net.helenus.core.cache.SessionCache; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.codahale.metrics.MetricRegistry; import com.datastax.driver.core.*; -import com.google.common.cache.Cache; -import com.google.common.cache.CacheBuilder; import com.google.common.collect.Table; import brave.Tracer; import net.helenus.core.cache.CacheUtil; import net.helenus.core.cache.Facet; +import net.helenus.core.cache.SessionCache; import net.helenus.core.cache.UnboundFacet; import net.helenus.core.operation.*; import net.helenus.core.reflect.Drafted; @@ -80,8 +77,8 @@ public final class HelenusSession extends AbstractSessionOperations implements C HelenusSession(Session session, String usingKeyspace, CodecRegistry registry, boolean showCql, PrintStream printStream, SessionRepositoryBuilder sessionRepositoryBuilder, Executor executor, boolean dropSchemaOnClose, ConsistencyLevel consistencyLevel, boolean defaultQueryIdempotency, - Class unitOfWorkClass, SessionCache sessionCache, - MetricRegistry metricRegistry, Tracer tracer) { + Class unitOfWorkClass, SessionCache sessionCache, MetricRegistry metricRegistry, + Tracer tracer) { this.session = session; this.registry = registry == null ? CodecRegistry.DEFAULT_INSTANCE : registry; this.usingKeyspace = Objects.requireNonNull(usingKeyspace, @@ -98,10 +95,10 @@ public final class HelenusSession extends AbstractSessionOperations implements C this.zipkinTracer = tracer; if (sessionCache == null) { - this.sessionCache = SessionCache.defaultCache(); - } else { - this.sessionCache = sessionCache; - } + this.sessionCache = SessionCache.defaultCache(); + } else { + this.sessionCache = sessionCache; + } this.valueProvider = new RowColumnValueProvider(this.sessionRepository); this.valuePreparer = new StatementColumnValuePreparer(this.sessionRepository); @@ -242,48 +239,49 @@ public final class HelenusSession extends AbstractSessionOperations implements C @Override public void mergeCache(Table>> uowCache) { - List items = uowCache.values().stream().filter(Either::isLeft).map(Either::getLeft).distinct().collect(Collectors.toList()); + List items = uowCache.values().stream().filter(Either::isLeft).map(Either::getLeft).distinct() + .collect(Collectors.toList()); for (Object pojo : items) { - HelenusEntity entity = Helenus.resolve(MappingUtil.getMappingInterface(pojo)); - Map valueMap = pojo instanceof MapExportable ? ((MapExportable) pojo).toMap() : null; - if (entity.isCacheable()) { - List boundFacets = new ArrayList<>(); - for (Facet facet : entity.getFacets()) { - if (facet instanceof UnboundFacet) { - UnboundFacet unboundFacet = (UnboundFacet) facet; - UnboundFacet.Binder binder = unboundFacet.binder(); - unboundFacet.getProperties().forEach(prop -> { - if (valueMap == null) { - Object value = BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop); - binder.setValueForProperty(prop, value.toString()); - } else { - binder.setValueForProperty(prop, valueMap.get(prop.getPropertyName()).toString()); - } - }); - if (binder.isBound()) { - boundFacets.add(binder.bind()); - } - } else { - boundFacets.add(facet); - } - } - // NOTE: should equal `String tableName = CacheUtil.schemaName(facets);` - List facetCombinations = CacheUtil.flattenFacets(boundFacets); - String tableName = CacheUtil.schemaName(boundFacets); - mergeAndUpdateCacheValues(pojo, tableName, facetCombinations); - } - } + HelenusEntity entity = Helenus.resolve(MappingUtil.getMappingInterface(pojo)); + Map valueMap = pojo instanceof MapExportable ? ((MapExportable) pojo).toMap() : null; + if (entity.isCacheable()) { + List boundFacets = new ArrayList<>(); + for (Facet facet : entity.getFacets()) { + if (facet instanceof UnboundFacet) { + UnboundFacet unboundFacet = (UnboundFacet) facet; + UnboundFacet.Binder binder = unboundFacet.binder(); + unboundFacet.getProperties().forEach(prop -> { + if (valueMap == null) { + Object value = BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop); + binder.setValueForProperty(prop, value.toString()); + } else { + binder.setValueForProperty(prop, valueMap.get(prop.getPropertyName()).toString()); + } + }); + if (binder.isBound()) { + boundFacets.add(binder.bind()); + } + } else { + boundFacets.add(facet); + } + } + // NOTE: should equal `String tableName = CacheUtil.schemaName(facets);` + List facetCombinations = CacheUtil.flattenFacets(boundFacets); + String tableName = CacheUtil.schemaName(boundFacets); + mergeAndUpdateCacheValues(pojo, tableName, facetCombinations); + } + } - List> deletedFacetSets = uowCache.values().stream().filter(Either::isRight).map(Either::getRight).collect( - Collectors.toList()); - for (List facets : deletedFacetSets) { - String tableName = CacheUtil.schemaName(facets); - List combinations = CacheUtil.flattenFacets(facets); - for (String[] combination : combinations) { - String cacheKey = tableName + "." + Arrays.toString(combination); - sessionCache.invalidate(cacheKey); - } - } + List> deletedFacetSets = uowCache.values().stream().filter(Either::isRight).map(Either::getRight) + .collect(Collectors.toList()); + for (List facets : deletedFacetSets) { + String tableName = CacheUtil.schemaName(facets); + List combinations = CacheUtil.flattenFacets(facets); + for (String[] combination : combinations) { + String cacheKey = tableName + "." + Arrays.toString(combination); + sessionCache.invalidate(cacheKey); + } + } } private void mergeAndUpdateCacheValues(Object pojo, String tableName, List facetCombinations) { @@ -505,20 +503,20 @@ public final class HelenusSession extends AbstractSessionOperations implements C } public UpdateOperation update(Object pojo) { - if (pojo instanceof MapExportable == false) { - throw new HelenusMappingException( - "update of objects that don't implement MapExportable is not yet supported"); - } - return new UpdateOperation(this, pojo); - } + if (pojo instanceof MapExportable == false) { + throw new HelenusMappingException( + "update of objects that don't implement MapExportable is not yet supported"); + } + return new UpdateOperation(this, pojo); + } public UpdateOperation update(Drafted drafted) { - if (drafted instanceof AbstractEntityDraft == false) { - throw new HelenusMappingException( - "update of draft objects that don't inherit from AbstractEntityDraft is not yet supported"); - } + if (drafted instanceof AbstractEntityDraft == false) { + throw new HelenusMappingException( + "update of draft objects that don't inherit from AbstractEntityDraft is not yet supported"); + } AbstractEntityDraft draft = (AbstractEntityDraft) drafted; - UpdateOperation update = new UpdateOperation(this, draft); + UpdateOperation update = new UpdateOperation(this, draft); Map map = draft.toMap(); Set mutatedProperties = draft.mutated(); HelenusEntity entity = Helenus.entity(draft.getEntityClass()); diff --git a/src/main/java/net/helenus/core/SessionInitializer.java b/src/main/java/net/helenus/core/SessionInitializer.java index d5c4117..2559276 100644 --- a/src/main/java/net/helenus/core/SessionInitializer.java +++ b/src/main/java/net/helenus/core/SessionInitializer.java @@ -126,9 +126,9 @@ public final class SessionInitializer extends AbstractSessionOperations { } public SessionInitializer setSessionCache(SessionCache sessionCache) { - this.sessionCache = sessionCache; - return this; - } + this.sessionCache = sessionCache; + return this; + } public ConsistencyLevel getDefaultConsistencyLevel() { return consistencyLevel; @@ -251,7 +251,7 @@ public final class SessionInitializer extends AbstractSessionOperations { initialize(); return new HelenusSession(session, usingKeyspace, registry, showCql, printStream, sessionRepository, executor, autoDdl == AutoDdl.CREATE_DROP, consistencyLevel, idempotent, unitOfWorkClass, sessionCache, - metricRegistry, zipkinTracer); + metricRegistry, zipkinTracer); } private void initialize() { diff --git a/src/main/java/net/helenus/core/cache/BoundFacet.java b/src/main/java/net/helenus/core/cache/BoundFacet.java index 48949ea..0eea23c 100644 --- a/src/main/java/net/helenus/core/cache/BoundFacet.java +++ b/src/main/java/net/helenus/core/cache/BoundFacet.java @@ -25,10 +25,10 @@ public class BoundFacet extends Facet { private final Map properties; public BoundFacet(HelenusProperty property, Object value) { - super(property.getPropertyName(), value == null ? null : value.toString()); - this.properties = new HashMap(1); - this.properties.put(property, value); - } + super(property.getPropertyName(), value == null ? null : value.toString()); + this.properties = new HashMap(1); + this.properties.put(property, value); + } public BoundFacet(String name, Map properties) { super(name, diff --git a/src/main/java/net/helenus/core/cache/CacheUtil.java b/src/main/java/net/helenus/core/cache/CacheUtil.java index 2b08e87..3f2b3a2 100644 --- a/src/main/java/net/helenus/core/cache/CacheUtil.java +++ b/src/main/java/net/helenus/core/cache/CacheUtil.java @@ -1,16 +1,12 @@ package net.helenus.core.cache; -import net.helenus.core.Helenus; -import net.helenus.core.reflect.MapExportable; -import net.helenus.mapping.HelenusEntity; -import net.helenus.mapping.MappingUtil; -import net.helenus.mapping.value.BeanColumnValueProvider; - import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.stream.Collectors; +import net.helenus.core.reflect.MapExportable; + public class CacheUtil { public static List combinations(List items) { @@ -45,22 +41,25 @@ public class CacheUtil { } public static Object merge(Object to, Object from) { - if (to == from) { - return to; + if (to == from) { + return to; + } else { + return from; } +/* + // TODO(gburd): take ttl and writeTime into account when merging. + Map toValueMap = to instanceof MapExportable ? ((MapExportable) to).toMap() : null; + Map fromValueMap = to instanceof MapExportable ? ((MapExportable) from).toMap() : null; - //TODO(gburd): take ttl and writeTime into account when merging. - Map toValueMap = to instanceof MapExportable ? ((MapExportable) to).toMap() : null; - Map fromValueMap = to instanceof MapExportable ? ((MapExportable) from).toMap() : null; - - if (toValueMap != null && fromValueMap != null) { - for (String key : fromValueMap.keySet()) { - if (toValueMap.containsKey(key) && toValueMap.get(key) != fromValueMap.get(key)) { - toValueMap.put(key, fromValueMap.get(key)); - } - } - } + if (toValueMap != null && fromValueMap != null) { + for (String key : fromValueMap.keySet()) { + if (toValueMap.containsKey(key) && toValueMap.get(key) != fromValueMap.get(key)) { + toValueMap.put(key, fromValueMap.get(key)); + } + } + } return to; +*/ } public static String schemaName(List facets) { diff --git a/src/main/java/net/helenus/core/cache/GuavaCache.java b/src/main/java/net/helenus/core/cache/GuavaCache.java index 7438c63..4411e7c 100644 --- a/src/main/java/net/helenus/core/cache/GuavaCache.java +++ b/src/main/java/net/helenus/core/cache/GuavaCache.java @@ -20,25 +20,25 @@ import com.google.common.cache.Cache; public class GuavaCache implements SessionCache { - final Cache cache; + final Cache cache; - GuavaCache(Cache cache) { - this.cache = cache; - } + GuavaCache(Cache cache) { + this.cache = cache; + } - @Override - public void invalidate(K key) { - cache.invalidate(key); - } + @Override + public void invalidate(K key) { + cache.invalidate(key); + } - @Override - public V get(K key) { - return cache.getIfPresent(key); - } + @Override + public V get(K key) { + return cache.getIfPresent(key); + } - @Override - public void put(K key, V value) { - cache.put(key, value); - } + @Override + public void put(K key, V value) { + cache.put(key, value); + } } diff --git a/src/main/java/net/helenus/core/cache/SessionCache.java b/src/main/java/net/helenus/core/cache/SessionCache.java index 02b15c6..44717e0 100644 --- a/src/main/java/net/helenus/core/cache/SessionCache.java +++ b/src/main/java/net/helenus/core/cache/SessionCache.java @@ -16,21 +16,21 @@ package net.helenus.core.cache; -import com.google.common.cache.CacheBuilder; - import java.util.concurrent.TimeUnit; +import com.google.common.cache.CacheBuilder; + public interface SessionCache { - static SessionCache defaultCache() { - int MAX_CACHE_SIZE = 10000; - int MAX_CACHE_EXPIRE_SECONDS = 600; - return new GuavaCache(CacheBuilder.newBuilder().maximumSize(MAX_CACHE_SIZE) - .expireAfterAccess(MAX_CACHE_EXPIRE_SECONDS, TimeUnit.SECONDS) - .expireAfterWrite(MAX_CACHE_EXPIRE_SECONDS, TimeUnit.SECONDS).recordStats().build()); - } + static SessionCache defaultCache() { + int MAX_CACHE_SIZE = 10000; + int MAX_CACHE_EXPIRE_SECONDS = 600; + return new GuavaCache(CacheBuilder.newBuilder().maximumSize(MAX_CACHE_SIZE) + .expireAfterAccess(MAX_CACHE_EXPIRE_SECONDS, TimeUnit.SECONDS) + .expireAfterWrite(MAX_CACHE_EXPIRE_SECONDS, TimeUnit.SECONDS).recordStats().build()); + } - void invalidate(K key); - V get(K key); - void put(K key, V value); + void invalidate(K key); + V get(K key); + void put(K key, V value); } diff --git a/src/main/java/net/helenus/core/operation/AbstractFilterOperation.java b/src/main/java/net/helenus/core/operation/AbstractFilterOperation.java index 6eec08d..eb30d37 100644 --- a/src/main/java/net/helenus/core/operation/AbstractFilterOperation.java +++ b/src/main/java/net/helenus/core/operation/AbstractFilterOperation.java @@ -20,7 +20,6 @@ import java.util.*; import net.helenus.core.*; import net.helenus.core.cache.Facet; import net.helenus.core.cache.UnboundFacet; -import net.helenus.mapping.HelenusEntity; import net.helenus.mapping.HelenusProperty; public abstract class AbstractFilterOperation> @@ -111,38 +110,38 @@ public abstract class AbstractFilterOperation bindFacetValues(List facets) { - if (facets == null) { - return new ArrayList(); - } - List boundFacets = new ArrayList<>(); - Map filterMap = new HashMap<>(filters.size()); - filters.forEach(f -> filterMap.put(f.getNode().getProperty(), f)); + protected List bindFacetValues(List facets) { + if (facets == null) { + return new ArrayList(); + } + List boundFacets = new ArrayList<>(); + Map filterMap = new HashMap<>(filters.size()); + filters.forEach(f -> filterMap.put(f.getNode().getProperty(), f)); - for (Facet facet : facets) { - if (facet instanceof UnboundFacet) { - UnboundFacet unboundFacet = (UnboundFacet) facet; - UnboundFacet.Binder binder = unboundFacet.binder(); - if (filters != null) { - for (HelenusProperty prop : unboundFacet.getProperties()) { + for (Facet facet : facets) { + if (facet instanceof UnboundFacet) { + UnboundFacet unboundFacet = (UnboundFacet) facet; + UnboundFacet.Binder binder = unboundFacet.binder(); + if (filters != null) { + for (HelenusProperty prop : unboundFacet.getProperties()) { - Filter filter = filterMap.get(prop); - if (filter != null) { - Object[] postulates = filter.postulateValues(); - for (Object p : postulates) { - binder.setValueForProperty(prop, p.toString()); - } - } - } + Filter filter = filterMap.get(prop); + if (filter != null) { + Object[] postulates = filter.postulateValues(); + for (Object p : postulates) { + binder.setValueForProperty(prop, p.toString()); + } + } + } - } - if (binder.isBound()) { - boundFacets.add(binder.bind()); - } - } else { - boundFacets.add(facet); - } - } - return boundFacets; - } + } + if (binder.isBound()) { + boundFacets.add(binder.bind()); + } + } else { + boundFacets.add(facet); + } + } + return boundFacets; + } } diff --git a/src/main/java/net/helenus/core/operation/AbstractStatementOperation.java b/src/main/java/net/helenus/core/operation/AbstractStatementOperation.java index 34a1da3..7f9cff3 100644 --- a/src/main/java/net/helenus/core/operation/AbstractStatementOperation.java +++ b/src/main/java/net/helenus/core/operation/AbstractStatementOperation.java @@ -333,10 +333,10 @@ public abstract class AbstractStatementOperation facets = new ArrayList<>(); Map valueMap = pojo instanceof MapExportable ? ((MapExportable) pojo).toMap() : null; - for (Facet facet : identifyingFacets) { - if (facet instanceof UnboundFacet) { - UnboundFacet unboundFacet = (UnboundFacet) facet; - UnboundFacet.Binder binder = unboundFacet.binder(); + for (Facet facet : identifyingFacets) { + if (facet instanceof UnboundFacet) { + UnboundFacet unboundFacet = (UnboundFacet) facet; + UnboundFacet.Binder binder = unboundFacet.binder(); for (HelenusProperty prop : unboundFacet.getProperties()) { Object value; if (valueMap == null) { diff --git a/src/main/java/net/helenus/core/operation/DeleteOperation.java b/src/main/java/net/helenus/core/operation/DeleteOperation.java index e17e0a4..1280f45 100644 --- a/src/main/java/net/helenus/core/operation/DeleteOperation.java +++ b/src/main/java/net/helenus/core/operation/DeleteOperation.java @@ -15,10 +15,7 @@ */ package net.helenus.core.operation; -import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.concurrent.TimeoutException; import com.datastax.driver.core.ResultSet; @@ -31,10 +28,8 @@ import net.helenus.core.AbstractSessionOperations; import net.helenus.core.Filter; import net.helenus.core.UnitOfWork; import net.helenus.core.cache.Facet; -import net.helenus.core.cache.UnboundFacet; import net.helenus.core.reflect.HelenusPropertyNode; import net.helenus.mapping.HelenusEntity; -import net.helenus.mapping.HelenusProperty; import net.helenus.support.HelenusMappingException; public final class DeleteOperation extends AbstractFilterOperation { @@ -134,8 +129,8 @@ public final class DeleteOperation extends AbstractFilterOperation bindFacetValues() { - return bindFacetValues(getFacets()); - } + return bindFacetValues(getFacets()); + } @Override public ResultSet sync() throws TimeoutException { @@ -156,9 +151,9 @@ public final class DeleteOperation extends AbstractFilterOperation getFacets() { - return entity.getFacets(); - } + @Override + public List getFacets() { + return entity.getFacets(); + } } diff --git a/src/main/java/net/helenus/core/operation/InsertOperation.java b/src/main/java/net/helenus/core/operation/InsertOperation.java index ff7d3ce..91959ba 100644 --- a/src/main/java/net/helenus/core/operation/InsertOperation.java +++ b/src/main/java/net/helenus/core/operation/InsertOperation.java @@ -44,7 +44,7 @@ public final class InsertOperation extends AbstractOperation> values = new ArrayList>(); private final T pojo; - private final Class resultType; + private final Class resultType; private HelenusEntity entity; private boolean ifNotExists; @@ -56,7 +56,7 @@ public final class InsertOperation extends AbstractOperation resultType, boolean ifNotExists) { @@ -251,14 +251,14 @@ public final class InsertOperation extends AbstractOperation iface = entity.getMappingInterface(); - if (resultType == iface) { + Class iface = entity.getMappingInterface(); + if (resultType == iface) { cacheUpdate(uow, result, entity.getFacets()); } else { - if (entity.isCacheable()) { - sessionOps.cacheEvict(bindFacetValues()); - } - } + if (entity.isCacheable()) { + sessionOps.cacheEvict(bindFacetValues()); + } + } return result; } diff --git a/src/main/java/net/helenus/core/operation/SelectOperation.java b/src/main/java/net/helenus/core/operation/SelectOperation.java index fd05b22..497868b 100644 --- a/src/main/java/net/helenus/core/operation/SelectOperation.java +++ b/src/main/java/net/helenus/core/operation/SelectOperation.java @@ -207,7 +207,7 @@ public final class SelectOperation extends AbstractFilterStreamOperation extends AbstractFilterOperation UpdateOperation set(Getter getter, V v) { + public UpdateOperation set(Getter getter, V v) { Objects.requireNonNull(getter, "getter is empty"); HelenusPropertyNode p = MappingUtil.resolveMappingProperty(getter); @@ -91,23 +90,23 @@ public final class UpdateOperation extends AbstractFilterOperation map = ((MapExportable) pojo).toMap(); - if (!(map instanceof ValueProviderMap)) { - if (map.get(key) != value) { - map.put(key, value); - } - } - } - } + if (entity != null) { + if (entity.isCacheable() && pojo != null && pojo instanceof MapExportable) { + String key = prop.getPropertyName(); + Map map = ((MapExportable) pojo).toMap(); + if (!(map instanceof ValueProviderMap)) { + if (map.get(key) != value) { + map.put(key, value); + } + } + } + } addPropertyNode(p); @@ -132,15 +131,15 @@ public final class UpdateOperation extends AbstractFilterOperation extends AbstractFilterOperation extends AbstractFilterOperation list = new ArrayList((List)BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop)); - list.add(0, value); - facet = new BoundFacet(prop, list); - } else if (draft != null) { - String key = p.getProperty().getPropertyName(); - List list = (List) draftMap.get(key); - list.add(0, value); - } + BoundFacet facet = null; + if (pojo != null) { + HelenusProperty prop = p.getProperty(); + List list = new ArrayList((List) BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop)); + list.add(0, value); + facet = new BoundFacet(prop, list); + } else if (draft != null) { + String key = p.getProperty().getPropertyName(); + List list = (List) draftMap.get(key); + list.add(0, value); + } - assignments.put(QueryBuilder.prepend(p.getColumnName(), valueObj), facet); + assignments.put(QueryBuilder.prepend(p.getColumnName(), valueObj), facet); addPropertyNode(p); @@ -218,19 +217,19 @@ public final class UpdateOperation extends AbstractFilterOperation list = new ArrayList((List)BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop)); - list.addAll(0, value); - facet = new BoundFacet(prop, list); - } else if (draft != null && value.size() > 0) { - String key = p.getProperty().getPropertyName(); - List list = (List) draftMap.get(key); - list.addAll(0, value); - } + BoundFacet facet = null; + if (pojo != null) { + HelenusProperty prop = p.getProperty(); + List list = new ArrayList((List) BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop)); + list.addAll(0, value); + facet = new BoundFacet(prop, list); + } else if (draft != null && value.size() > 0) { + String key = p.getProperty().getPropertyName(); + List list = (List) draftMap.get(key); + list.addAll(0, value); + } - assignments.put(QueryBuilder.prependAll(p.getColumnName(), valueObj), facet); + assignments.put(QueryBuilder.prependAll(p.getColumnName(), valueObj), facet); addPropertyNode(p); @@ -245,28 +244,28 @@ public final class UpdateOperation extends AbstractFilterOperation list; - HelenusProperty prop = p.getProperty(); - if (pojo != null) { - list = new ArrayList((List) BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop)); - } else { - String key = p.getProperty().getPropertyName(); - list = (List) draftMap.get(key); - } - if (idx < 0) { - list.add(0, value); - } else if (idx > list.size()) { - list.add(list.size(), value); - } else { - list.add(idx, value); - } - list.add(0, value); - facet = new BoundFacet(prop, list); - } + BoundFacet facet = null; + if (pojo != null || draft != null) { + List list; + HelenusProperty prop = p.getProperty(); + if (pojo != null) { + list = new ArrayList((List) BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop)); + } else { + String key = p.getProperty().getPropertyName(); + list = (List) draftMap.get(key); + } + if (idx < 0) { + list.add(0, value); + } else if (idx > list.size()) { + list.add(list.size(), value); + } else { + list.add(idx, value); + } + list.add(0, value); + facet = new BoundFacet(prop, list); + } - assignments.put(QueryBuilder.setIdx(p.getColumnName(), idx, valueObj), facet); + assignments.put(QueryBuilder.setIdx(p.getColumnName(), idx, valueObj), facet); addPropertyNode(p); @@ -281,18 +280,18 @@ public final class UpdateOperation extends AbstractFilterOperation list = new ArrayList((List)BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop)); - list.add(value); - facet = new BoundFacet(prop, list); - } else if (draft != null) { - String key = p.getProperty().getPropertyName(); - List list = (List) draftMap.get(key); - list.add(value); - } - assignments.put(QueryBuilder.append(p.getColumnName(), valueObj), facet); + BoundFacet facet = null; + if (pojo != null) { + HelenusProperty prop = p.getProperty(); + List list = new ArrayList((List) BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop)); + list.add(value); + facet = new BoundFacet(prop, list); + } else if (draft != null) { + String key = p.getProperty().getPropertyName(); + List list = (List) draftMap.get(key); + list.add(value); + } + assignments.put(QueryBuilder.append(p.getColumnName(), valueObj), facet); addPropertyNode(p); @@ -307,18 +306,18 @@ public final class UpdateOperation extends AbstractFilterOperation list = new ArrayList((List)BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop)); - list.addAll(value); - facet = new BoundFacet(prop, list); - } else if (draft != null && value.size() > 0) { - String key = p.getProperty().getPropertyName(); - List list = (List) draftMap.get(key); - list.addAll(value); - } - assignments.put(QueryBuilder.appendAll(p.getColumnName(), valueObj), facet); + BoundFacet facet = null; + if (pojo != null) { + HelenusProperty prop = p.getProperty(); + List list = new ArrayList((List) BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop)); + list.addAll(value); + facet = new BoundFacet(prop, list); + } else if (draft != null && value.size() > 0) { + String key = p.getProperty().getPropertyName(); + List list = (List) draftMap.get(key); + list.addAll(value); + } + assignments.put(QueryBuilder.appendAll(p.getColumnName(), valueObj), facet); addPropertyNode(p); @@ -333,18 +332,18 @@ public final class UpdateOperation extends AbstractFilterOperation list = new ArrayList((List)BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop)); - list.remove(value); - facet = new BoundFacet(prop, list); - } else if (draft != null) { - String key = p.getProperty().getPropertyName(); - List list = (List) draftMap.get(key); - list.remove(value); - } - assignments.put(QueryBuilder.discard(p.getColumnName(), valueObj), facet); + BoundFacet facet = null; + if (pojo != null) { + HelenusProperty prop = p.getProperty(); + List list = new ArrayList((List) BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop)); + list.remove(value); + facet = new BoundFacet(prop, list); + } else if (draft != null) { + String key = p.getProperty().getPropertyName(); + List list = (List) draftMap.get(key); + list.remove(value); + } + assignments.put(QueryBuilder.discard(p.getColumnName(), valueObj), facet); addPropertyNode(p); @@ -359,18 +358,18 @@ public final class UpdateOperation extends AbstractFilterOperation list = new ArrayList((List)BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop)); - list.removeAll(value); - facet = new BoundFacet(prop, list); - } else if (draft != null) { - String key = p.getProperty().getPropertyName(); - List list = (List) draftMap.get(key); - list.removeAll(value); - } - assignments.put(QueryBuilder.discardAll(p.getColumnName(), valueObj), facet); + BoundFacet facet = null; + if (pojo != null) { + HelenusProperty prop = p.getProperty(); + List list = new ArrayList((List) BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop)); + list.removeAll(value); + facet = new BoundFacet(prop, list); + } else if (draft != null) { + String key = p.getProperty().getPropertyName(); + List list = (List) draftMap.get(key); + list.removeAll(value); + } + assignments.put(QueryBuilder.discardAll(p.getColumnName(), valueObj), facet); addPropertyNode(p); @@ -421,18 +420,18 @@ public final class UpdateOperation extends AbstractFilterOperation set = new HashSet((Set)BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop)); - set.add(value); - facet = new BoundFacet(prop, set); - } else if (draft != null) { - String key = p.getProperty().getPropertyName(); - Set set = (Set) draftMap.get(key); - set.add(value); - } - assignments.put(QueryBuilder.add(p.getColumnName(), valueObj), facet); + BoundFacet facet = null; + if (pojo != null) { + HelenusProperty prop = p.getProperty(); + Set set = new HashSet((Set) BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop)); + set.add(value); + facet = new BoundFacet(prop, set); + } else if (draft != null) { + String key = p.getProperty().getPropertyName(); + Set set = (Set) draftMap.get(key); + set.add(value); + } + assignments.put(QueryBuilder.add(p.getColumnName(), valueObj), facet); addPropertyNode(p); @@ -447,17 +446,17 @@ public final class UpdateOperation extends AbstractFilterOperation set = new HashSet((Set)BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop)); - set.addAll(value); - facet = new BoundFacet(prop, set); - } else if (draft != null) { - String key = p.getProperty().getPropertyName(); - Set set = (Set) draftMap.get(key); - set.addAll(value); - } + BoundFacet facet = null; + if (pojo != null) { + HelenusProperty prop = p.getProperty(); + Set set = new HashSet((Set) BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop)); + set.addAll(value); + facet = new BoundFacet(prop, set); + } else if (draft != null) { + String key = p.getProperty().getPropertyName(); + Set set = (Set) draftMap.get(key); + set.addAll(value); + } assignments.put(QueryBuilder.addAll(p.getColumnName(), valueObj), facet); addPropertyNode(p); @@ -473,17 +472,17 @@ public final class UpdateOperation extends AbstractFilterOperation set = new HashSet((Set)BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop)); - set.remove(value); - facet = new BoundFacet(prop, set); - } else if (draft != null) { - String key = p.getProperty().getPropertyName(); - Set set = (Set) draftMap.get(key); - set.remove(value); - } + BoundFacet facet = null; + if (pojo != null) { + HelenusProperty prop = p.getProperty(); + Set set = new HashSet((Set) BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop)); + set.remove(value); + facet = new BoundFacet(prop, set); + } else if (draft != null) { + String key = p.getProperty().getPropertyName(); + Set set = (Set) draftMap.get(key); + set.remove(value); + } assignments.put(QueryBuilder.remove(p.getColumnName(), valueObj), facet); addPropertyNode(p); @@ -499,17 +498,17 @@ public final class UpdateOperation extends AbstractFilterOperation set = new HashSet((Set)BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop)); - set.removeAll(value); - facet = new BoundFacet(prop, set); - } else if (draft != null) { - String key = p.getProperty().getPropertyName(); - Set set = (Set) draftMap.get(key); - set.removeAll(value); - } + BoundFacet facet = null; + if (pojo != null) { + HelenusProperty prop = p.getProperty(); + Set set = new HashSet((Set) BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop)); + set.removeAll(value); + facet = new BoundFacet(prop, set); + } else if (draft != null) { + String key = p.getProperty().getPropertyName(); + Set set = (Set) draftMap.get(key); + set.removeAll(value); + } assignments.put(QueryBuilder.removeAll(p.getColumnName(), valueObj), facet); addPropertyNode(p); @@ -560,14 +559,15 @@ public final class UpdateOperation extends AbstractFilterOperation map = new HashMap((Map)BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop)); - map.put(key, value); - facet = new BoundFacet(prop, map); - } else if (draft != null) { - ((Map) draftMap.get(prop.getPropertyName())).put(key, value); - } + BoundFacet facet = null; + if (pojo != null) { + Map map = new HashMap( + (Map) BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop)); + map.put(key, value); + facet = new BoundFacet(prop, map); + } else if (draft != null) { + ((Map) draftMap.get(prop.getPropertyName())).put(key, value); + } Optional> converter = prop.getWriteConverter(sessionOps.getSessionRepository()); if (converter.isPresent()) { @@ -593,14 +593,15 @@ public final class UpdateOperation extends AbstractFilterOperation newMap = new HashMap((Map)BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop)); - newMap.putAll(map); - facet = new BoundFacet(prop, newMap); - } else if (draft != null) { - ((Map) draftMap.get(prop.getPropertyName())).putAll(map); - } + BoundFacet facet = null; + if (pojo != null) { + Map newMap = new HashMap( + (Map) BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop)); + newMap.putAll(map); + facet = new BoundFacet(prop, newMap); + } else if (draft != null) { + ((Map) draftMap.get(prop.getPropertyName())).putAll(map); + } Optional> converter = prop.getWriteConverter(sessionOps.getSessionRepository()); if (converter.isPresent()) { @@ -687,13 +688,13 @@ public final class UpdateOperation extends AbstractFilterOperation extends AbstractFilterOperation bindFacetValues() { - List facets = bindFacetValues(entity.getFacets()); - facets.addAll(assignments.values().stream().distinct().filter(o -> o != null).collect(Collectors.toList())); - return facets; - } + @Override + public List bindFacetValues() { + List facets = bindFacetValues(entity.getFacets()); + facets.addAll(assignments.values().stream().distinct().filter(o -> o != null).collect(Collectors.toList())); + return facets; + } - @Override + @Override public List getFacets() { if (entity != null) { return entity.getFacets(); diff --git a/src/main/java/net/helenus/core/reflect/MapperInvocationHandler.java b/src/main/java/net/helenus/core/reflect/MapperInvocationHandler.java index 42af52a..9bde57c 100644 --- a/src/main/java/net/helenus/core/reflect/MapperInvocationHandler.java +++ b/src/main/java/net/helenus/core/reflect/MapperInvocationHandler.java @@ -21,7 +21,6 @@ import java.lang.reflect.Constructor; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; -import java.util.Collections; import java.util.Map; import net.helenus.core.Helenus; @@ -102,8 +101,8 @@ public class MapperInvocationHandler implements InvocationHandler, Serializab } if (MapExportable.TO_MAP_METHOD.equals(methodName)) { - //return Collections.unmodifiableMap(src); - return src; + // return Collections.unmodifiableMap(src); + return src; } Object value = src.get(methodName); diff --git a/src/main/java/net/helenus/mapping/MappingUtil.java b/src/main/java/net/helenus/mapping/MappingUtil.java index f554b72..f421c40 100644 --- a/src/main/java/net/helenus/mapping/MappingUtil.java +++ b/src/main/java/net/helenus/mapping/MappingUtil.java @@ -285,41 +285,39 @@ public final class MappingUtil { } // https://stackoverflow.com/a/4882306/366692 - public static T clone(T object) - throws CloneNotSupportedException { - Object clone = null; + public static T clone(T object) throws CloneNotSupportedException { + Object clone = null; - // Use reflection, because there is no other way - try { - Method method = object.getClass().getMethod("clone"); - clone = method.invoke(object); - } catch (InvocationTargetException e) { - rethrow(e.getCause()); - } catch (Exception cause) { - rethrow(cause); - } - if (object.getClass().isInstance(clone)) { - @SuppressWarnings("unchecked") // clone class <= object class <= T - T t = (T) clone; - return t; - } else { - throw new ClassCastException(clone.getClass().getName()); - } - } + // Use reflection, because there is no other way + try { + Method method = object.getClass().getMethod("clone"); + clone = method.invoke(object); + } catch (InvocationTargetException e) { + rethrow(e.getCause()); + } catch (Exception cause) { + rethrow(cause); + } + if (object.getClass().isInstance(clone)) { + @SuppressWarnings("unchecked") // clone class <= object class <= T + T t = (T) clone; + return t; + } else { + throw new ClassCastException(clone.getClass().getName()); + } + } - private static void rethrow(Throwable cause) - throws CloneNotSupportedException { - if (cause instanceof RuntimeException) { - throw (RuntimeException) cause; - } - if (cause instanceof Error) { - throw (Error) cause; - } - if (cause instanceof CloneNotSupportedException) { - throw (CloneNotSupportedException) cause; - } - CloneNotSupportedException e = new CloneNotSupportedException(); - e.initCause(cause); - throw e; - } + private static void rethrow(Throwable cause) throws CloneNotSupportedException { + if (cause instanceof RuntimeException) { + throw (RuntimeException) cause; + } + if (cause instanceof Error) { + throw (Error) cause; + } + if (cause instanceof CloneNotSupportedException) { + throw (CloneNotSupportedException) cause; + } + CloneNotSupportedException e = new CloneNotSupportedException(); + e.initCause(cause); + throw e; + } } From c3f9b83770240ffcb8702f7df39a4fc4bfd3db11 Mon Sep 17 00:00:00 2001 From: Greg Burd Date: Mon, 30 Oct 2017 09:40:41 -0400 Subject: [PATCH 15/18] Log the purposes of nested UOWs as well as the parent. Create a serialization proxy for mapped objects. --- .../net/helenus/core/AbstractUnitOfWork.java | 13 +++-- .../java/net/helenus/core/HelenusSession.java | 26 +++++----- .../java/net/helenus/core/UnitOfWork.java | 1 + .../core/reflect/MapperInvocationHandler.java | 49 +++++++++++++++++-- .../reflect/ReflectionMapperInstantiator.java | 3 +- 5 files changed, 70 insertions(+), 22 deletions(-) diff --git a/src/main/java/net/helenus/core/AbstractUnitOfWork.java b/src/main/java/net/helenus/core/AbstractUnitOfWork.java index 9182054..fa09f30 100644 --- a/src/main/java/net/helenus/core/AbstractUnitOfWork.java +++ b/src/main/java/net/helenus/core/AbstractUnitOfWork.java @@ -44,6 +44,7 @@ public abstract class AbstractUnitOfWork implements UnitOfW private final AbstractUnitOfWork parent; private final Table>> cache = HashBasedTable.create(); protected String purpose; + protected List nestedPurposes = new ArrayList(); protected int cacheHits = 0; protected int cacheMisses = 0; protected int databaseLookups = 0; @@ -90,6 +91,11 @@ public abstract class AbstractUnitOfWork implements UnitOfW return this; } + @Override + public String getPurpose() { + return purpose; + } + @Override public UnitOfWork setPurpose(String purpose) { this.purpose = purpose; @@ -137,10 +143,11 @@ public abstract class AbstractUnitOfWork implements UnitOfW double daf = (dat / e) * 100; da = String.format(" consuming %,.3fms for data access, or %,2.2f%% of total UOW time.", dat, daf); } + String x = nestedPurposes.stream().distinct().collect(Collectors.joining(", ")); String n = nested.stream().map(uow -> String.valueOf(uow.hashCode())).collect(Collectors.joining(", ")); - String s = String.format(Locale.US, "UOW(%s%s) %s in %,.3fms%s%s%s%s", hashCode(), + String s = String.format(Locale.US, "UOW(%s%s) %s in %,.3fms%s%s%s%s%s", hashCode(), (nested.size() > 0 ? ", [" + n + "]" : ""), what, e, cache, database, da, - (purpose == null ? "" : " " + purpose)); + (purpose == null ? "" : " " + purpose), (nestedPurposes.isEmpty()) ? "" : ", " + x); return s; } @@ -277,7 +284,7 @@ public abstract class AbstractUnitOfWork implements UnitOfW // Merge cache and statistics into parent if there is one. parent.mergeCache(cache); - + if (purpose != null) {parent.nestedPurposes.add(purpose);} parent.cacheHits += cacheHits; parent.cacheMisses += cacheMisses; parent.databaseLookups += databaseLookups; diff --git a/src/main/java/net/helenus/core/HelenusSession.java b/src/main/java/net/helenus/core/HelenusSession.java index 7dd63e9..6b33f60 100644 --- a/src/main/java/net/helenus/core/HelenusSession.java +++ b/src/main/java/net/helenus/core/HelenusSession.java @@ -311,24 +311,22 @@ public final class HelenusSession extends AbstractSessionOperations implements C } public synchronized UnitOfWork begin(UnitOfWork parent) { - StringBuilder purpose = null; - if (LOG.isInfoEnabled()) { - StackTraceElement[] trace = Thread.currentThread().getStackTrace(); - int frame = 2; - if (trace[2].getMethodName().equals("begin")) { - frame = 3; - } - purpose = new StringBuilder().append(trace[frame].getClassName()).append(".") - .append(trace[frame].getMethodName()).append("(").append(trace[frame].getFileName()).append(":") - .append(trace[frame].getLineNumber()).append(")"); - } try { Class clazz = unitOfWorkClass; Constructor ctor = clazz.getConstructor(HelenusSession.class, UnitOfWork.class); UnitOfWork uow = ctor.newInstance(this, parent); - if (LOG.isInfoEnabled() && purpose != null) { - uow.setPurpose(purpose.toString()); - } + if (LOG.isInfoEnabled() && uow.getPurpose() == null) { + StringBuilder purpose = null; + StackTraceElement[] trace = Thread.currentThread().getStackTrace(); + int frame = 2; + if (trace[2].getMethodName().equals("begin")) { + frame = 3; + } + purpose = new StringBuilder().append(trace[frame].getClassName()).append(".") + .append(trace[frame].getMethodName()).append("(").append(trace[frame].getFileName()).append(":") + .append(trace[frame].getLineNumber()).append(")"); + uow.setPurpose(purpose.toString()); + } if (parent != null) { parent.addNestedUnitOfWork(uow); } diff --git a/src/main/java/net/helenus/core/UnitOfWork.java b/src/main/java/net/helenus/core/UnitOfWork.java index 5a1c7bc..5d55853 100644 --- a/src/main/java/net/helenus/core/UnitOfWork.java +++ b/src/main/java/net/helenus/core/UnitOfWork.java @@ -61,6 +61,7 @@ public interface UnitOfWork extends AutoCloseable { List cacheEvict(List facets); + String getPurpose(); UnitOfWork setPurpose(String purpose); void addDatabaseTime(String name, Stopwatch amount); diff --git a/src/main/java/net/helenus/core/reflect/MapperInvocationHandler.java b/src/main/java/net/helenus/core/reflect/MapperInvocationHandler.java index 9bde57c..a1e5094 100644 --- a/src/main/java/net/helenus/core/reflect/MapperInvocationHandler.java +++ b/src/main/java/net/helenus/core/reflect/MapperInvocationHandler.java @@ -15,16 +15,21 @@ */ package net.helenus.core.reflect; +import java.io.InvalidObjectException; +import java.io.ObjectInputStream; +import java.io.ObjectStreamException; import java.io.Serializable; import java.lang.invoke.MethodHandles; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; +import java.util.HashMap; import java.util.Map; import net.helenus.core.Helenus; import net.helenus.mapping.annotation.Transient; +import net.helenus.mapping.value.ValueProviderMap; import net.helenus.support.HelenusException; public class MapperInvocationHandler implements InvocationHandler, Serializable { @@ -50,14 +55,20 @@ public class MapperInvocationHandler implements InvocationHandler, Serializab int.class); constructor.setAccessible(true); - // Now we need to lookup and invoke special the default method on the interface - // class. + // Now we need to lookup and invoke special the default method on the interface class. final Class declaringClass = method.getDeclaringClass(); Object result = constructor.newInstance(declaringClass, MethodHandles.Lookup.PRIVATE) .unreflectSpecial(method, declaringClass).bindTo(proxy).invokeWithArguments(args); return result; } + private Object writeReplace() { + return new SerializationProxy(this); + } + private void readObject(ObjectInputStream stream) throws InvalidObjectException { + throw new InvalidObjectException("Proxy required."); + } + @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { @@ -96,13 +107,20 @@ public class MapperInvocationHandler implements InvocationHandler, Serializab return iface.getSimpleName() + ": " + src.toString(); } + if ("writeReplace".equals(methodName)) { + return new SerializationProxy(this); + } + + if ("readObject".equals(methodName)) { + throw new InvalidObjectException("Proxy required."); + } + if ("dsl".equals(methodName)) { return Helenus.dsl(iface); } if (MapExportable.TO_MAP_METHOD.equals(methodName)) { - // return Collections.unmodifiableMap(src); - return src; + return src; // return Collections.unmodifiableMap(src); } Object value = src.get(methodName); @@ -132,4 +150,27 @@ public class MapperInvocationHandler implements InvocationHandler, Serializab return value; } + + static class SerializationProxy implements Serializable { + + private static final long serialVersionUID = -5617583940055969353L; + + private final Class iface; + private final Map src; + + public SerializationProxy(MapperInvocationHandler mapper) { + this.iface = mapper.iface; + if (mapper.src instanceof ValueProviderMap) { + this.src = new HashMap(mapper.src.size()); + this.src.putAll(src); + } else { + this.src = mapper.src; + } + } + + Object readResolve() throws ObjectStreamException { + return Helenus.map(iface, src); + } + + } } diff --git a/src/main/java/net/helenus/core/reflect/ReflectionMapperInstantiator.java b/src/main/java/net/helenus/core/reflect/ReflectionMapperInstantiator.java index 811a682..4485d0d 100644 --- a/src/main/java/net/helenus/core/reflect/ReflectionMapperInstantiator.java +++ b/src/main/java/net/helenus/core/reflect/ReflectionMapperInstantiator.java @@ -15,6 +15,7 @@ */ package net.helenus.core.reflect; +import java.io.Serializable; import java.lang.reflect.Proxy; import java.util.Map; @@ -28,7 +29,7 @@ public enum ReflectionMapperInstantiator implements MapperInstantiator { public E instantiate(Class iface, Map src, ClassLoader classLoader) { MapperInvocationHandler handler = new MapperInvocationHandler(iface, src); - E proxy = (E) Proxy.newProxyInstance(classLoader, new Class[]{iface, MapExportable.class}, handler); + E proxy = (E) Proxy.newProxyInstance(classLoader, new Class[]{iface, MapExportable.class, Serializable.class}, handler); return proxy; } } From 560582488686f2a5bf78578ccb52cf2ee0e875fa Mon Sep 17 00:00:00 2001 From: Greg Burd Date: Mon, 30 Oct 2017 11:49:48 -0400 Subject: [PATCH 16/18] Minor fixes. --- src/main/java/net/helenus/core/AbstractUnitOfWork.java | 8 +++++--- src/main/java/net/helenus/core/HelenusSession.java | 2 ++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/main/java/net/helenus/core/AbstractUnitOfWork.java b/src/main/java/net/helenus/core/AbstractUnitOfWork.java index fa09f30..6e77501 100644 --- a/src/main/java/net/helenus/core/AbstractUnitOfWork.java +++ b/src/main/java/net/helenus/core/AbstractUnitOfWork.java @@ -256,7 +256,7 @@ public abstract class AbstractUnitOfWork implements UnitOfW } } - // log.recordCacheAndDatabaseOperationCount(txn::provisionalCommit) + // log.record(txn::provisionalCommit) // examine log for conflicts in read-set and write-set between begin and // provisional commit // if (conflict) { throw new ConflictingUnitOfWorkException(this) } @@ -310,12 +310,14 @@ public abstract class AbstractUnitOfWork implements UnitOfW public synchronized void abort() { TreeTraverser> traverser = TreeTraverser.using(node -> node::getChildNodes); traverser.postOrderTraversal(this).forEach(uow -> { - uow.committed = false; - uow.aborted = true; + uow.committed = false; + uow.aborted = true; }); // log.record(txn::abort) // cache.invalidateSince(txn::start time) if (!hasAborted()) { + committed = false; + aborted = true; elapsedTime.stop(); if (LOG.isInfoEnabled()) { LOG.info(logTimers("aborted")); diff --git a/src/main/java/net/helenus/core/HelenusSession.java b/src/main/java/net/helenus/core/HelenusSession.java index 6b33f60..dfd2ffe 100644 --- a/src/main/java/net/helenus/core/HelenusSession.java +++ b/src/main/java/net/helenus/core/HelenusSession.java @@ -321,6 +321,8 @@ public final class HelenusSession extends AbstractSessionOperations implements C int frame = 2; if (trace[2].getMethodName().equals("begin")) { frame = 3; + } else if (trace[2].getClassName().equals(unitOfWorkClass.getName())) { + frame = 3; } purpose = new StringBuilder().append(trace[frame].getClassName()).append(".") .append(trace[frame].getMethodName()).append("(").append(trace[frame].getFileName()).append(":") From dcea254fdb1ac24a6d5c666f7358777eb74b5293 Mon Sep 17 00:00:00 2001 From: Greg Burd Date: Mon, 30 Oct 2017 11:52:12 -0400 Subject: [PATCH 17/18] Formatting. --- .../net/helenus/core/AbstractEntityDraft.java | 1 - .../net/helenus/core/AbstractUnitOfWork.java | 18 +++--- .../java/net/helenus/core/HelenusSession.java | 26 ++++----- .../net/helenus/core/cache/CacheUtil.java | 30 ++++------ .../core/reflect/MapperInvocationHandler.java | 57 ++++++++++--------- .../reflect/ReflectionMapperInstantiator.java | 3 +- 6 files changed, 66 insertions(+), 69 deletions(-) diff --git a/src/main/java/net/helenus/core/AbstractEntityDraft.java b/src/main/java/net/helenus/core/AbstractEntityDraft.java index 1bfd2d1..94005ff 100644 --- a/src/main/java/net/helenus/core/AbstractEntityDraft.java +++ b/src/main/java/net/helenus/core/AbstractEntityDraft.java @@ -3,7 +3,6 @@ package net.helenus.core; import java.io.Serializable; import java.util.*; -import net.helenus.mapping.value.ValueProviderMap; import org.apache.commons.lang3.SerializationUtils; import com.google.common.primitives.Primitives; diff --git a/src/main/java/net/helenus/core/AbstractUnitOfWork.java b/src/main/java/net/helenus/core/AbstractUnitOfWork.java index 6e77501..ea0d005 100644 --- a/src/main/java/net/helenus/core/AbstractUnitOfWork.java +++ b/src/main/java/net/helenus/core/AbstractUnitOfWork.java @@ -92,9 +92,9 @@ public abstract class AbstractUnitOfWork implements UnitOfW } @Override - public String getPurpose() { - return purpose; - } + public String getPurpose() { + return purpose; + } @Override public UnitOfWork setPurpose(String purpose) { @@ -284,7 +284,9 @@ public abstract class AbstractUnitOfWork implements UnitOfW // Merge cache and statistics into parent if there is one. parent.mergeCache(cache); - if (purpose != null) {parent.nestedPurposes.add(purpose);} + if (purpose != null) { + parent.nestedPurposes.add(purpose); + } parent.cacheHits += cacheHits; parent.cacheMisses += cacheMisses; parent.databaseLookups += databaseLookups; @@ -310,14 +312,14 @@ public abstract class AbstractUnitOfWork implements UnitOfW public synchronized void abort() { TreeTraverser> traverser = TreeTraverser.using(node -> node::getChildNodes); traverser.postOrderTraversal(this).forEach(uow -> { - uow.committed = false; - uow.aborted = true; + uow.committed = false; + uow.aborted = true; }); // log.record(txn::abort) // cache.invalidateSince(txn::start time) if (!hasAborted()) { - committed = false; - aborted = true; + committed = false; + aborted = true; elapsedTime.stop(); if (LOG.isInfoEnabled()) { LOG.info(logTimers("aborted")); diff --git a/src/main/java/net/helenus/core/HelenusSession.java b/src/main/java/net/helenus/core/HelenusSession.java index dfd2ffe..91986e4 100644 --- a/src/main/java/net/helenus/core/HelenusSession.java +++ b/src/main/java/net/helenus/core/HelenusSession.java @@ -316,19 +316,19 @@ public final class HelenusSession extends AbstractSessionOperations implements C Constructor ctor = clazz.getConstructor(HelenusSession.class, UnitOfWork.class); UnitOfWork uow = ctor.newInstance(this, parent); if (LOG.isInfoEnabled() && uow.getPurpose() == null) { - StringBuilder purpose = null; - StackTraceElement[] trace = Thread.currentThread().getStackTrace(); - int frame = 2; - if (trace[2].getMethodName().equals("begin")) { - frame = 3; - } else if (trace[2].getClassName().equals(unitOfWorkClass.getName())) { - frame = 3; - } - purpose = new StringBuilder().append(trace[frame].getClassName()).append(".") - .append(trace[frame].getMethodName()).append("(").append(trace[frame].getFileName()).append(":") - .append(trace[frame].getLineNumber()).append(")"); - uow.setPurpose(purpose.toString()); - } + StringBuilder purpose = null; + StackTraceElement[] trace = Thread.currentThread().getStackTrace(); + int frame = 2; + if (trace[2].getMethodName().equals("begin")) { + frame = 3; + } else if (trace[2].getClassName().equals(unitOfWorkClass.getName())) { + frame = 3; + } + purpose = new StringBuilder().append(trace[frame].getClassName()).append(".") + .append(trace[frame].getMethodName()).append("(").append(trace[frame].getFileName()).append(":") + .append(trace[frame].getLineNumber()).append(")"); + uow.setPurpose(purpose.toString()); + } if (parent != null) { parent.addNestedUnitOfWork(uow); } diff --git a/src/main/java/net/helenus/core/cache/CacheUtil.java b/src/main/java/net/helenus/core/cache/CacheUtil.java index 3f2b3a2..2607d45 100644 --- a/src/main/java/net/helenus/core/cache/CacheUtil.java +++ b/src/main/java/net/helenus/core/cache/CacheUtil.java @@ -2,11 +2,8 @@ package net.helenus.core.cache; import java.util.ArrayList; import java.util.List; -import java.util.Map; import java.util.stream.Collectors; -import net.helenus.core.reflect.MapExportable; - public class CacheUtil { public static List combinations(List items) { @@ -44,22 +41,19 @@ public class CacheUtil { if (to == from) { return to; } else { - return from; - } -/* - // TODO(gburd): take ttl and writeTime into account when merging. - Map toValueMap = to instanceof MapExportable ? ((MapExportable) to).toMap() : null; - Map fromValueMap = to instanceof MapExportable ? ((MapExportable) from).toMap() : null; - - if (toValueMap != null && fromValueMap != null) { - for (String key : fromValueMap.keySet()) { - if (toValueMap.containsKey(key) && toValueMap.get(key) != fromValueMap.get(key)) { - toValueMap.put(key, fromValueMap.get(key)); - } - } + return from; } - return to; -*/ + /* + * // TODO(gburd): take ttl and writeTime into account when merging. Map toValueMap = to instanceof MapExportable ? ((MapExportable) + * to).toMap() : null; Map fromValueMap = to instanceof + * MapExportable ? ((MapExportable) from).toMap() : null; + * + * if (toValueMap != null && fromValueMap != null) { for (String key : + * fromValueMap.keySet()) { if (toValueMap.containsKey(key) && + * toValueMap.get(key) != fromValueMap.get(key)) { toValueMap.put(key, + * fromValueMap.get(key)); } } } return to; + */ } public static String schemaName(List facets) { diff --git a/src/main/java/net/helenus/core/reflect/MapperInvocationHandler.java b/src/main/java/net/helenus/core/reflect/MapperInvocationHandler.java index a1e5094..fdfa0b1 100644 --- a/src/main/java/net/helenus/core/reflect/MapperInvocationHandler.java +++ b/src/main/java/net/helenus/core/reflect/MapperInvocationHandler.java @@ -55,19 +55,20 @@ public class MapperInvocationHandler implements InvocationHandler, Serializab int.class); constructor.setAccessible(true); - // Now we need to lookup and invoke special the default method on the interface class. + // Now we need to lookup and invoke special the default method on the interface + // class. final Class declaringClass = method.getDeclaringClass(); Object result = constructor.newInstance(declaringClass, MethodHandles.Lookup.PRIVATE) .unreflectSpecial(method, declaringClass).bindTo(proxy).invokeWithArguments(args); return result; } - private Object writeReplace() { - return new SerializationProxy(this); - } - private void readObject(ObjectInputStream stream) throws InvalidObjectException { - throw new InvalidObjectException("Proxy required."); - } + private Object writeReplace() { + return new SerializationProxy(this); + } + private void readObject(ObjectInputStream stream) throws InvalidObjectException { + throw new InvalidObjectException("Proxy required."); + } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { @@ -108,12 +109,12 @@ public class MapperInvocationHandler implements InvocationHandler, Serializab } if ("writeReplace".equals(methodName)) { - return new SerializationProxy(this); - } + return new SerializationProxy(this); + } - if ("readObject".equals(methodName)) { - throw new InvalidObjectException("Proxy required."); - } + if ("readObject".equals(methodName)) { + throw new InvalidObjectException("Proxy required."); + } if ("dsl".equals(methodName)) { return Helenus.dsl(iface); @@ -153,24 +154,24 @@ public class MapperInvocationHandler implements InvocationHandler, Serializab static class SerializationProxy implements Serializable { - private static final long serialVersionUID = -5617583940055969353L; + private static final long serialVersionUID = -5617583940055969353L; - private final Class iface; - private final Map src; + private final Class iface; + private final Map src; - public SerializationProxy(MapperInvocationHandler mapper) { - this.iface = mapper.iface; - if (mapper.src instanceof ValueProviderMap) { - this.src = new HashMap(mapper.src.size()); - this.src.putAll(src); - } else { - this.src = mapper.src; - } - } + public SerializationProxy(MapperInvocationHandler mapper) { + this.iface = mapper.iface; + if (mapper.src instanceof ValueProviderMap) { + this.src = new HashMap(mapper.src.size()); + this.src.putAll(src); + } else { + this.src = mapper.src; + } + } - Object readResolve() throws ObjectStreamException { - return Helenus.map(iface, src); - } + Object readResolve() throws ObjectStreamException { + return Helenus.map(iface, src); + } - } + } } diff --git a/src/main/java/net/helenus/core/reflect/ReflectionMapperInstantiator.java b/src/main/java/net/helenus/core/reflect/ReflectionMapperInstantiator.java index 4485d0d..4ce43f8 100644 --- a/src/main/java/net/helenus/core/reflect/ReflectionMapperInstantiator.java +++ b/src/main/java/net/helenus/core/reflect/ReflectionMapperInstantiator.java @@ -29,7 +29,8 @@ public enum ReflectionMapperInstantiator implements MapperInstantiator { public E instantiate(Class iface, Map src, ClassLoader classLoader) { MapperInvocationHandler handler = new MapperInvocationHandler(iface, src); - E proxy = (E) Proxy.newProxyInstance(classLoader, new Class[]{iface, MapExportable.class, Serializable.class}, handler); + E proxy = (E) Proxy.newProxyInstance(classLoader, new Class[]{iface, MapExportable.class, Serializable.class}, + handler); return proxy; } } From 48545c1e8400f7eaf8cd1d27a139375dfb43266c Mon Sep 17 00:00:00 2001 From: Greg Burd Date: Mon, 30 Oct 2017 15:21:43 -0400 Subject: [PATCH 18/18] Finish implementation of proxy model objects. --- .../net/helenus/core/AbstractUnitOfWork.java | 14 ++-- .../core/reflect/MapperInvocationHandler.java | 14 ++-- .../core/draft/EntityDraftBuilderTest.java | 83 +++++++++++++------ 3 files changed, 75 insertions(+), 36 deletions(-) diff --git a/src/main/java/net/helenus/core/AbstractUnitOfWork.java b/src/main/java/net/helenus/core/AbstractUnitOfWork.java index ea0d005..1b4454d 100644 --- a/src/main/java/net/helenus/core/AbstractUnitOfWork.java +++ b/src/main/java/net/helenus/core/AbstractUnitOfWork.java @@ -86,7 +86,9 @@ public abstract class AbstractUnitOfWork implements UnitOfW @Override public synchronized UnitOfWork begin() { - elapsedTime = Stopwatch.createStarted(); + if (LOG.isInfoEnabled()) { + elapsedTime = Stopwatch.createStarted(); + } // log.record(txn::start) return this; } @@ -317,13 +319,11 @@ public abstract class AbstractUnitOfWork implements UnitOfW }); // log.record(txn::abort) // cache.invalidateSince(txn::start time) - if (!hasAborted()) { - committed = false; - aborted = true; - elapsedTime.stop(); - if (LOG.isInfoEnabled()) { - LOG.info(logTimers("aborted")); + if (LOG.isInfoEnabled()) { + if (elapsedTime.isRunning()) { + elapsedTime.stop(); } + LOG.info(logTimers("aborted")); } } diff --git a/src/main/java/net/helenus/core/reflect/MapperInvocationHandler.java b/src/main/java/net/helenus/core/reflect/MapperInvocationHandler.java index fdfa0b1..cbff40b 100644 --- a/src/main/java/net/helenus/core/reflect/MapperInvocationHandler.java +++ b/src/main/java/net/helenus/core/reflect/MapperInvocationHandler.java @@ -26,6 +26,7 @@ import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.HashMap; import java.util.Map; +import java.util.Set; import net.helenus.core.Helenus; import net.helenus.mapping.annotation.Transient; @@ -64,7 +65,7 @@ public class MapperInvocationHandler implements InvocationHandler, Serializab } private Object writeReplace() { - return new SerializationProxy(this); + return new SerializationProxy(this); } private void readObject(ObjectInputStream stream) throws InvalidObjectException { throw new InvalidObjectException("Proxy required."); @@ -152,25 +153,28 @@ public class MapperInvocationHandler implements InvocationHandler, Serializab return value; } - static class SerializationProxy implements Serializable { + static class SerializationProxy implements Serializable { private static final long serialVersionUID = -5617583940055969353L; - private final Class iface; + private final Class iface; private final Map src; public SerializationProxy(MapperInvocationHandler mapper) { this.iface = mapper.iface; if (mapper.src instanceof ValueProviderMap) { this.src = new HashMap(mapper.src.size()); - this.src.putAll(src); + Set keys = mapper.src.keySet(); + for (String key : keys) { + this.src.put(key, mapper.src.get(key)); + } } else { this.src = mapper.src; } } Object readResolve() throws ObjectStreamException { - return Helenus.map(iface, src); + return new MapperInvocationHandler(iface, src); } } diff --git a/src/test/java/net/helenus/test/integration/core/draft/EntityDraftBuilderTest.java b/src/test/java/net/helenus/test/integration/core/draft/EntityDraftBuilderTest.java index f21c50b..72c088e 100644 --- a/src/test/java/net/helenus/test/integration/core/draft/EntityDraftBuilderTest.java +++ b/src/test/java/net/helenus/test/integration/core/draft/EntityDraftBuilderTest.java @@ -15,9 +15,11 @@ */ package net.helenus.test.integration.core.draft; +import java.io.*; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; +import java.util.concurrent.TimeoutException; import org.junit.Assert; import org.junit.BeforeClass; @@ -27,41 +29,48 @@ import net.helenus.core.Helenus; import net.helenus.core.HelenusSession; import net.helenus.test.integration.build.AbstractEmbeddedCassandraTest; +import static net.helenus.core.Query.eq; + public class EntityDraftBuilderTest extends AbstractEmbeddedCassandraTest { static Supply supply; static HelenusSession session; + static Supply.Draft draft = null; @BeforeClass - public static void beforeTest() { + public static void beforeTest() throws TimeoutException { session = Helenus.init(getSession()).showCql().add(Supply.class).autoCreateDrop().get(); - supply = session.dsl(Supply.class); - } + supply = session.dsl(Supply.class); + + draft = Supply.draft("APAC").code("WIDGET-002").description("Our second Widget!") + .demand(new HashMap() { + { + put("APAC", 100L); + put("EMEA", 10000L); + put("NORAM", 2000000L); + } + }).shipments(new HashSet() { + { + add("HMS Puddle in transit to APAC, 100 units."); + add("Frigate Jimmy in transit to EMEA, 10000 units."); + } + }).suppliers(new ArrayList() { + { + add("Puddle, Inc."); + add("Jimmy Town, LTD."); + } + }); + + Supply s1 = session.insert(draft).sync(); + } @Test public void testFoo() throws Exception { - Supply.Draft draft = null; - draft = Supply.draft("APAC").code("WIDGET-002").description("Our second Widget!") - .demand(new HashMap() { - { - put("APAC", 100L); - put("EMEA", 10000L); - put("NORAM", 2000000L); - } - }).shipments(new HashSet() { - { - add("HMS Puddle in transit to APAC, 100 units."); - add("Frigate Jimmy in transit to EMEA, 10000 units."); - } - }).suppliers(new ArrayList() { - { - add("Puddle, Inc."); - add("Jimmy Town, LTD."); - } - }); - - Supply s1 = session.insert(draft).sync(); + Supply s1 = session.select(Supply.class).where(supply::id, eq(draft.id())) + .single() + .sync() + .orElse(null); // List Supply s2 = session.update(s1.update()).prepend(supply::suppliers, "Pignose Supply, LLC.").sync(); @@ -76,4 +85,30 @@ public class EntityDraftBuilderTest extends AbstractEmbeddedCassandraTest { Supply s4 = session.update(s3.update()).put(supply::demand, "NORAM", 10L).sync(); Assert.assertEquals((long) s4.demand().get("NORAM"), 10L); } + + @Test + public void testSerialization() throws Exception { + Supply s1, s2; + + s1 = session.select(Supply.class).where(supply::id, eq(draft.id())) + .single() + .sync() + .orElse(null); + + byte[] data; + try (ByteArrayOutputStream bos = new ByteArrayOutputStream(); + ObjectOutput out = new ObjectOutputStream(bos)) { + out.writeObject(s1); + out.flush(); + data = bos.toByteArray(); + } + + try (ByteArrayInputStream bis = new ByteArrayInputStream(data); + ObjectInput in = new ObjectInputStream(bis)) { + s2 = (Supply)in.readObject(); + } + + Assert.assertEquals(s2.id(), s1.id()); + Assert.assertEquals(s2, s1); + } }