From cf2740337ebf0dcdb67e0d862df2e3b1faff6fff Mon Sep 17 00:00:00 2001 From: Greg Burd Date: Thu, 10 Aug 2017 13:09:34 -0400 Subject: [PATCH] Add 'Drafted' interface and extend the InsertOperation to recognize that so as to be able to persist the mutated set of keys only yet return a pojo with values matching the draft, not just the mutations. Changed {in,up}sert() to return the instance of the object. --- pom.xml | 2 +- .../java/net/helenus/core/HelenusSession.java | 26 ++++++++---- .../core/operation/InsertOperation.java | 42 ++++++++++--------- .../net/helenus/core/reflect/Drafted.java | 11 +++++ .../helenus/core/reflect/MapExportable.java | 3 -- .../core/reflect/MapperInvocationHandler.java | 2 - .../core/prepared/PreparedStatementTest.java | 3 +- .../core/simple/InsertPartialTest.java | 2 +- .../core/simple/SimpleUserTest.java | 8 ++++ .../core/usertype/UserDefinedTypeTest.java | 6 +-- .../helenus/test/unit/core/dsl/Account.java | 20 ++++++++- 11 files changed, 84 insertions(+), 41 deletions(-) create mode 100644 src/main/java/net/helenus/core/reflect/Drafted.java diff --git a/pom.xml b/pom.xml index e6708fd..f9e51ef 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ 4.0.0 net.helenus helenus-core - 2.0.14-SNAPSHOT + 2.0.15-SNAPSHOT jar helenus diff --git a/src/main/java/net/helenus/core/HelenusSession.java b/src/main/java/net/helenus/core/HelenusSession.java index 59b713f..9216a6d 100644 --- a/src/main/java/net/helenus/core/HelenusSession.java +++ b/src/main/java/net/helenus/core/HelenusSession.java @@ -19,6 +19,7 @@ import java.io.Closeable; import java.io.PrintStream; import java.util.Map; import java.util.Objects; +import java.util.Set; import java.util.concurrent.Executor; import java.util.concurrent.TimeUnit; import java.util.function.Function; @@ -31,6 +32,7 @@ import com.google.common.cache.CacheBuilder; import com.diffplug.common.base.Errors; import net.helenus.core.operation.*; +import net.helenus.core.reflect.Drafted; import net.helenus.core.reflect.HelenusPropertyNode; import net.helenus.mapping.HelenusEntity; import net.helenus.mapping.MappingUtil; @@ -342,30 +344,36 @@ public final class HelenusSession extends AbstractSessionOperations implements C return new UpdateOperation(this, p, v); } - public InsertOperation insert() { - return new InsertOperation(this, true); - } + public InsertOperation insert() { return new InsertOperation(this, true); } - public InsertOperation insert(Object pojo) { + public InsertOperation insert(Object pojo) { return this.insert(pojo, null); } + + public InsertOperation insert(Drafted draft) { return this.insert(draft.build(), draft.mutated()); } + + public InsertOperation insert(Object pojo, Set mutations) { Objects.requireNonNull(pojo, "pojo is empty"); Class iface = MappingUtil.getMappingInterface(pojo); HelenusEntity entity = Helenus.entity(iface); - return new InsertOperation(this, entity, pojo, true); + return new InsertOperation(this, entity, pojo, mutations, true); } - public InsertOperation upsert() { - return new InsertOperation(this, false); + public InsertOperation upsert() { + return new InsertOperation(this, false); } - public InsertOperation upsert(Object pojo) { + public InsertOperation upsert(Drafted draft) { return this.upsert(draft.build(), draft.mutated()); } + + public InsertOperation upsert(Object pojo) { return this.upsert(pojo, null); } + + public InsertOperation upsert(Object pojo, Set mutations) { Objects.requireNonNull(pojo, "pojo is empty"); Class iface = MappingUtil.getMappingInterface(pojo); HelenusEntity entity = Helenus.entity(iface); - return new InsertOperation(this, entity, pojo, false); + return new InsertOperation(this, entity, pojo, mutations, false); } public DeleteOperation delete() { diff --git a/src/main/java/net/helenus/core/operation/InsertOperation.java b/src/main/java/net/helenus/core/operation/InsertOperation.java index c57b776..4f7ca7a 100644 --- a/src/main/java/net/helenus/core/operation/InsertOperation.java +++ b/src/main/java/net/helenus/core/operation/InsertOperation.java @@ -21,8 +21,8 @@ import com.datastax.driver.core.querybuilder.Insert; import com.datastax.driver.core.querybuilder.QueryBuilder; import net.helenus.core.AbstractSessionOperations; import net.helenus.core.Getter; +import net.helenus.core.Helenus; 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; @@ -32,12 +32,13 @@ import net.helenus.support.HelenusMappingException; import java.util.*; -public final class InsertOperation extends AbstractOperation { +public final class InsertOperation extends AbstractOperation> { private HelenusEntity entity; private final List> values = new ArrayList>(); private boolean ifNotExists; + private Object pojo; private int[] ttl; private long[] timestamp; @@ -48,21 +49,15 @@ public final class InsertOperation extends AbstractOperation mutations, boolean ifNotExists) { super(sessionOperations); this.entity = entity; + this.pojo = pojo; this.ifNotExists = ifNotExists; Collection properties = entity.getOrderedProperties(); - Set keys = null; - - if (pojo instanceof MapExportable) { - keys = ((MapExportable) pojo).mutated(); - if (keys == null) { - keys = ((MapExportable) pojo).toMap().keySet(); - } - } + Set keys = (mutations == null) ? null : mutations; for (HelenusProperty prop : properties) { @@ -82,17 +77,17 @@ public final class InsertOperation extends AbstractOperation ifNotExists() { this.ifNotExists = true; return this; } - public InsertOperation ifNotExists(boolean enable) { + public InsertOperation ifNotExists(boolean enable) { this.ifNotExists = enable; return this; } - public InsertOperation value(Getter getter, V val) { + public InsertOperation value(Getter getter, V val) { Objects.requireNonNull(getter, "getter is empty"); @@ -141,17 +136,26 @@ public final class InsertOperation extends AbstractOperation 0) { + Map backingMap = new HashMap(values.size()); + values.forEach(t -> backingMap.put(t._1.getProperty().getPropertyName(), t._2)); + pojo = Helenus.map(values.get(0)._1.getEntity().getMappingInterface(), backingMap); + } + } + return (T) pojo; } - public InsertOperation usingTtl(int ttl) { + public InsertOperation usingTtl(int ttl) { this.ttl = new int[1]; this.ttl[0] = ttl; return this; } - public InsertOperation usingTimestamp(long timestamp) { + public InsertOperation usingTimestamp(long timestamp) { this.timestamp = new long[1]; this.timestamp[0] = timestamp; return this; diff --git a/src/main/java/net/helenus/core/reflect/Drafted.java b/src/main/java/net/helenus/core/reflect/Drafted.java new file mode 100644 index 0000000..aa5a54a --- /dev/null +++ b/src/main/java/net/helenus/core/reflect/Drafted.java @@ -0,0 +1,11 @@ +package net.helenus.core.reflect; + +import java.util.Set; + +public interface Drafted extends MapExportable { + + Set mutated(); + + T build(); + +} diff --git a/src/main/java/net/helenus/core/reflect/MapExportable.java b/src/main/java/net/helenus/core/reflect/MapExportable.java index fcb0e19..1e91946 100644 --- a/src/main/java/net/helenus/core/reflect/MapExportable.java +++ b/src/main/java/net/helenus/core/reflect/MapExportable.java @@ -16,7 +16,6 @@ package net.helenus.core.reflect; import java.util.Map; -import java.util.Set; public interface MapExportable { @@ -24,6 +23,4 @@ public interface MapExportable { Map toMap(); - default Set mutated() { return null; } - } diff --git a/src/main/java/net/helenus/core/reflect/MapperInvocationHandler.java b/src/main/java/net/helenus/core/reflect/MapperInvocationHandler.java index 467c857..1f2182b 100644 --- a/src/main/java/net/helenus/core/reflect/MapperInvocationHandler.java +++ b/src/main/java/net/helenus/core/reflect/MapperInvocationHandler.java @@ -101,8 +101,6 @@ public class MapperInvocationHandler implements InvocationHandler { return type.getDefaultValue(); - } else if (returnType.isEnum()) { - throw new HelenusException("missing default type for enum user type " + returnType); } } 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 8ba5484..d1bb7a2 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 @@ -18,6 +18,7 @@ package net.helenus.test.integration.core.prepared; import static net.helenus.core.Query.marker; import java.math.BigDecimal; +import java.util.Optional; import net.helenus.core.HelenusSession; import net.helenus.core.Query; @@ -57,7 +58,7 @@ public class PreparedStatementTest extends AbstractEmbeddedCassandraTest { session = Helenus.init(getSession()).showCql().add(Car.class).autoCreateDrop().get(); car = Helenus.dsl(Car.class, session.getMetadata()); - insertOp = session.insert() + insertOp = session.insert() .value(car::make, Query.marker()) .value(car::model, Query.marker()) .value(car::year, 2004) 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 a0ecbba..143fc18 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 @@ -48,7 +48,7 @@ public class InsertPartialTest extends AbstractEmbeddedCassandraTest { Long id = rnd.nextLong(); map.put("id", id); map.put("age", 5); - InsertOperation insert = session.insert(Helenus.map(User.class, map)); + 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(); 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 f34a3fb..9484656 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 @@ -28,6 +28,8 @@ import net.helenus.core.Operator; import net.helenus.support.Fun; import net.helenus.test.integration.build.AbstractEmbeddedCassandraTest; +import java.util.Optional; + public class SimpleUserTest extends AbstractEmbeddedCassandraTest { static User user; @@ -164,6 +166,12 @@ public class SimpleUserTest extends AbstractEmbeddedCassandraTest { Assert.assertEquals(Integer.valueOf(35), u.age()); // INSERT + User greg = session.insert() + .value(user::name, "greg") + .value(user::age, 44) + .value(user::type, UserType.USER) + .value(user::id, 1234L) + .sync(); session.update() .set(user::name, null) 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 bf1af4c..b77d9b8 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 @@ -143,8 +143,7 @@ public class UserDefinedTypeTest extends AbstractEmbeddedCassandraTest { Assert.assertNull(actual.country()); Assert.assertEquals(0, actual.zip()); - // INSERT - + // INSERT using UPDATE session.update().set(account::address, null).where(account::id, Query.eq(123L)).sync(); Address adrNull = session.select(account::address).where(account::id, Query.eq(123L)).sync().findFirst().get()._1; @@ -200,8 +199,7 @@ public class UserDefinedTypeTest extends AbstractEmbeddedCassandraTest { Assert.assertEquals(addressNoMapping.getString("city"), found.getString("city")); - // INSERT - + // INSERT using UPDATE session.update().set(account::addressNoMapping, null).where(account::id, Query.eq(777L)).sync(); found = session.select(account::addressNoMapping).where(account::id, Query.eq(777L)).sync().findFirst().get()._1; 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 9e585c0..f7d13b3 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 @@ -16,7 +16,10 @@ 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 @@ -35,6 +38,21 @@ public interface Account { @Transient default Draft draft() { return new Draft(); } - class Draft {} + class Draft implements Drafted { //TODO + @Override + public Set mutated() { + return null; + } + + @Override + public Object build() { + return null; + } + + @Override + public Map toMap() { + return null; + } + } }