You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by bt...@apache.org on 2016/09/29 10:51:53 UTC
[03/12] james-project git commit: JAMES-1781 Cassandra implementation
for partial updates
JAMES-1781 Cassandra implementation for partial updates
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/6da59847
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/6da59847
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/6da59847
Branch: refs/heads/master
Commit: 6da598471ac2f3632ae9c341b5b5a42e6fcec451
Parents: 50e3ab5
Author: Benoit Tellier <bt...@linagora.com>
Authored: Mon Jun 27 19:02:53 2016 +0700
Committer: Benoit Tellier <bt...@linagora.com>
Committed: Thu Sep 29 12:48:14 2016 +0200
----------------------------------------------------------------------
.../vacation/CassandraVacationDAO.java | 66 +++++++++++++-------
.../vacation/CassandraVacationRepository.java | 13 +++-
2 files changed, 55 insertions(+), 24 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/james-project/blob/6da59847/server/data/data-jmap-cassandra/src/main/java/org/apache/james/jmap/cassandra/vacation/CassandraVacationDAO.java
----------------------------------------------------------------------
diff --git a/server/data/data-jmap-cassandra/src/main/java/org/apache/james/jmap/cassandra/vacation/CassandraVacationDAO.java b/server/data/data-jmap-cassandra/src/main/java/org/apache/james/jmap/cassandra/vacation/CassandraVacationDAO.java
index e52139c..2ac0823 100644
--- a/server/data/data-jmap-cassandra/src/main/java/org/apache/james/jmap/cassandra/vacation/CassandraVacationDAO.java
+++ b/server/data/data-jmap-cassandra/src/main/java/org/apache/james/jmap/cassandra/vacation/CassandraVacationDAO.java
@@ -27,6 +27,7 @@ import static com.datastax.driver.core.querybuilder.QueryBuilder.select;
import java.time.ZonedDateTime;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
+import java.util.function.Function;
import javax.inject.Inject;
@@ -36,51 +37,53 @@ import org.apache.james.backends.cassandra.utils.CassandraAsyncExecutor;
import org.apache.james.backends.cassandra.utils.ZonedDateTimeRepresentation;
import org.apache.james.jmap.api.vacation.AccountId;
import org.apache.james.jmap.api.vacation.Vacation;
+import org.apache.james.jmap.api.vacation.VacationPatch;
import org.apache.james.jmap.cassandra.vacation.tables.CassandraVacationTable;
+import org.apache.james.util.FunctionGenerator;
+import org.apache.james.util.PatchedValue;
import com.datastax.driver.core.PreparedStatement;
import com.datastax.driver.core.Row;
import com.datastax.driver.core.Session;
import com.datastax.driver.core.UDTValue;
import com.datastax.driver.core.UserType;
+import com.datastax.driver.core.querybuilder.Insert;
+import com.google.common.collect.ImmutableList;
public class CassandraVacationDAO {
private final CassandraAsyncExecutor cassandraAsyncExecutor;
- private final PreparedStatement insertStatement;
private final PreparedStatement readStatement;
private final UserType zonedDateTimeUserType;
+ private final FunctionGenerator<VacationPatch, Insert> insertGeneratorPipeline;
@Inject
public CassandraVacationDAO(Session session, CassandraTypesProvider cassandraTypesProvider) {
this.zonedDateTimeUserType = cassandraTypesProvider.getDefinedUserType(CassandraZonedDateTimeModule.ZONED_DATE_TIME);
this.cassandraAsyncExecutor = new CassandraAsyncExecutor(session);
- this.insertStatement = session.prepare(insertInto(CassandraVacationTable.TABLE_NAME)
- .value(CassandraVacationTable.ACCOUNT_ID, bindMarker(CassandraVacationTable.ACCOUNT_ID))
- .value(CassandraVacationTable.IS_ENABLED, bindMarker(CassandraVacationTable.IS_ENABLED))
- .value(CassandraVacationTable.FROM_DATE, bindMarker(CassandraVacationTable.FROM_DATE))
- .value(CassandraVacationTable.TO_DATE, bindMarker(CassandraVacationTable.TO_DATE))
- .value(CassandraVacationTable.TEXT, bindMarker(CassandraVacationTable.TEXT))
- .value(CassandraVacationTable.SUBJECT, bindMarker(CassandraVacationTable.SUBJECT))
- .value(CassandraVacationTable.HTML, bindMarker(CassandraVacationTable.HTML)));
-
this.readStatement = session.prepare(select()
.from(CassandraVacationTable.TABLE_NAME)
.where(eq(CassandraVacationTable.ACCOUNT_ID,
bindMarker(CassandraVacationTable.ACCOUNT_ID))));
+
+ insertGeneratorPipeline = ImmutableList.<FunctionGenerator<VacationPatch, Insert>>of(
+ patch -> applyPatchForField(CassandraVacationTable.SUBJECT, patch.getSubject()),
+ patch -> applyPatchForField(CassandraVacationTable.HTML, patch.getHtmlBody()),
+ patch -> applyPatchForField(CassandraVacationTable.TEXT, patch.getTextBody()),
+ patch -> applyPatchForField(CassandraVacationTable.IS_ENABLED, patch.getIsEnabled()),
+ patch -> applyPatchForFieldZonedDateTime(CassandraVacationTable.FROM_DATE, patch.getFromDate()),
+ patch -> applyPatchForFieldZonedDateTime(CassandraVacationTable.TO_DATE, patch.getToDate()))
+ .stream()
+ .reduce(FunctionGenerator::composeGeneratedFunctions)
+ .get();
}
- public CompletableFuture<Void> modifyVacation(AccountId accountId, Vacation vacation) {
+ public CompletableFuture<Void> modifyVacation(AccountId accountId, VacationPatch vacationPatch) {
return cassandraAsyncExecutor.executeVoid(
- insertStatement.bind()
- .setString(CassandraVacationTable.ACCOUNT_ID, accountId.getIdentifier())
- .setBool(CassandraVacationTable.IS_ENABLED, vacation.isEnabled())
- .setUDTValue(CassandraVacationTable.FROM_DATE, convertToUDTValue(vacation.getFromDate()))
- .setUDTValue(CassandraVacationTable.TO_DATE, convertToUDTValue(vacation.getToDate()))
- .setString(CassandraVacationTable.TEXT, vacation.getTextBody().orElse(null))
- .setString(CassandraVacationTable.SUBJECT, vacation.getSubject().orElse(null))
- .setString(CassandraVacationTable.HTML, vacation.getHtmlBody().orElse(null)));
+ createSpecificUpdate(vacationPatch,
+ insertInto(CassandraVacationTable.TABLE_NAME)
+ .value(CassandraVacationTable.ACCOUNT_ID, accountId.getIdentifier())));
}
public CompletableFuture<Optional<Vacation>> retrieveVacation(AccountId accountId) {
@@ -104,11 +107,30 @@ public class CassandraVacationDAO {
.getZonedDateTime());
}
- private UDTValue convertToUDTValue(Optional<ZonedDateTime> zonedDateTimeOptional) {
+ private Insert createSpecificUpdate(VacationPatch vacationPatch, Insert baseInsert) {
+ return insertGeneratorPipeline
+ .apply(vacationPatch)
+ .apply(baseInsert);
+ }
+
+ public <T> Function<Insert, Insert> applyPatchForField(String field, PatchedValue<T> patchedValue) {
+ return patchedValue.mapNotKeptToOptional(optionalValue -> applyPatchForField(field, optionalValue))
+ .orElse(Function.identity());
+ }
+
+ public Function<Insert, Insert> applyPatchForFieldZonedDateTime(String field, PatchedValue<ZonedDateTime> patchedValue) {
+ return patchedValue.mapNotKeptToOptional(optionalValue -> applyPatchForField(field, convertToUDTOptional(optionalValue)))
+ .orElse(Function.identity());
+ }
+
+ private <T> Function<Insert, Insert> applyPatchForField(String field, Optional<T> value) {
+ return insert -> insert.value(field, value.orElse(null));
+ }
+
+ private Optional<UDTValue> convertToUDTOptional(Optional<ZonedDateTime> zonedDateTimeOptional) {
return zonedDateTimeOptional.map(ZonedDateTimeRepresentation::fromZonedDateTime)
.map(representation -> zonedDateTimeUserType.newValue()
.setDate(CassandraZonedDateTimeModule.DATE, representation.getDate())
- .setString(CassandraZonedDateTimeModule.TIME_ZONE, representation.getSerializedZoneId()))
- .orElse(null);
+ .setString(CassandraZonedDateTimeModule.TIME_ZONE, representation.getSerializedZoneId()));
}
}
http://git-wip-us.apache.org/repos/asf/james-project/blob/6da59847/server/data/data-jmap-cassandra/src/main/java/org/apache/james/jmap/cassandra/vacation/CassandraVacationRepository.java
----------------------------------------------------------------------
diff --git a/server/data/data-jmap-cassandra/src/main/java/org/apache/james/jmap/cassandra/vacation/CassandraVacationRepository.java b/server/data/data-jmap-cassandra/src/main/java/org/apache/james/jmap/cassandra/vacation/CassandraVacationRepository.java
index 60958d4..51574f5 100644
--- a/server/data/data-jmap-cassandra/src/main/java/org/apache/james/jmap/cassandra/vacation/CassandraVacationRepository.java
+++ b/server/data/data-jmap-cassandra/src/main/java/org/apache/james/jmap/cassandra/vacation/CassandraVacationRepository.java
@@ -26,6 +26,9 @@ import javax.inject.Inject;
import org.apache.james.jmap.api.vacation.AccountId;
import org.apache.james.jmap.api.vacation.Vacation;
import org.apache.james.jmap.api.vacation.VacationRepository;
+import org.apache.james.jmap.api.vacation.VacationPatch;
+
+import com.google.common.base.Preconditions;
public class CassandraVacationRepository implements VacationRepository {
@@ -37,8 +40,14 @@ public class CassandraVacationRepository implements VacationRepository {
}
@Override
- public CompletableFuture<Void> modifyVacation(AccountId accountId, Vacation vacation) {
- return cassandraVacationDAO.modifyVacation(accountId, vacation);
+ public CompletableFuture<Void> modifyVacation(AccountId accountId, VacationPatch vacationPatch) {
+ Preconditions.checkNotNull(accountId);
+ Preconditions.checkNotNull(vacationPatch);
+ if (vacationPatch.isIdentity()) {
+ return CompletableFuture.completedFuture(null);
+ } else {
+ return cassandraVacationDAO.modifyVacation(accountId, vacationPatch);
+ }
}
@Override
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org