You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@james.apache.org by rc...@apache.org on 2023/12/06 08:13:02 UTC
(james-project) 01/03: JAMES-2586 [PGSQL] Implement correctly FetchType
This is an automated email from the ASF dual-hosted git repository.
rcordier pushed a commit to branch postgresql
in repository https://gitbox.apache.org/repos/asf/james-project.git
commit 6b7568324842a18d1859d976e8f421faf53a69e7
Author: Tung Tran <vt...@linagora.com>
AuthorDate: Mon Dec 4 12:05:42 2023 +0700
JAMES-2586 [PGSQL] Implement correctly FetchType
---
.../james/backends/postgres/PostgresCommons.java | 7 +-
.../postgres/mail/PostgresMessageMapper.java | 44 +++---
.../mail/dao/PostgresMailboxMessageDAO.java | 50 ++++---
.../mail/dao/PostgresMailboxMessageDAOUtils.java | 37 +++---
.../dao/PostgresMailboxMessageFetchStrategy.java | 147 +++++++++++++++++++++
5 files changed, 217 insertions(+), 68 deletions(-)
diff --git a/backends-common/postgres/src/main/java/org/apache/james/backends/postgres/PostgresCommons.java b/backends-common/postgres/src/main/java/org/apache/james/backends/postgres/PostgresCommons.java
index ae4b8ebf5e..5ffb190525 100644
--- a/backends-common/postgres/src/main/java/org/apache/james/backends/postgres/PostgresCommons.java
+++ b/backends-common/postgres/src/main/java/org/apache/james/backends/postgres/PostgresCommons.java
@@ -49,11 +49,10 @@ public class PostgresCommons {
DataType<String[]> STRING_ARRAY = SQLDataType.CLOB.getArrayDataType();
}
- public interface SimpleTableField {
- Field<Object> of(Table<Record> table, Field<?> field);
- }
- public static final SimpleTableField TABLE_FIELD = (table, field) -> DSL.field(table.getName() + "." + field.getName());
+ public static <T> Field<T> tableField(Table<Record> table, Field<T> field) {
+ return DSL.field(table.getName() + "." + field.getName(), field.getDataType());
+ }
public static final Function<Date, LocalDateTime> DATE_TO_LOCAL_DATE_TIME = date -> Optional.ofNullable(date)
.map(value -> LocalDateTime.ofInstant(value.toInstant(), ZoneOffset.UTC))
diff --git a/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/mail/PostgresMessageMapper.java b/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/mail/PostgresMessageMapper.java
index 1a6787d5c4..101118676a 100644
--- a/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/mail/PostgresMessageMapper.java
+++ b/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/mail/PostgresMessageMapper.java
@@ -128,39 +128,41 @@ public class PostgresMessageMapper implements MessageMapper {
@Override
public Flux<MailboxMessage> findInMailboxReactive(Mailbox mailbox, MessageRange messageRange, FetchType fetchType, int limitAsInt) {
+ Flux<Pair<SimpleMailboxMessage.Builder, String>> fetchMessageWithoutFullContentPublisher = fetchMessageWithoutFullContent(mailbox, messageRange, fetchType, limitAsInt);
+ if (fetchType == FetchType.FULL) {
+ return fetchMessageWithoutFullContentPublisher
+ .flatMap(messageBuilderAndBlobId -> {
+ SimpleMailboxMessage.Builder messageBuilder = messageBuilderAndBlobId.getLeft();
+ String blobIdAsString = messageBuilderAndBlobId.getRight();
+ return retrieveFullContent(blobIdAsString)
+ .map(content -> messageBuilder.content(content).build());
+ })
+ .sort(Comparator.comparing(MailboxMessage::getUid))
+ .map(message -> message);
+ } else {
+ return fetchMessageWithoutFullContentPublisher
+ .map(messageBuilderAndBlobId -> messageBuilderAndBlobId.getLeft().build());
+ }
+ }
+
+ private Flux<Pair<SimpleMailboxMessage.Builder, String>> fetchMessageWithoutFullContent(Mailbox mailbox, MessageRange messageRange, FetchType fetchType, int limitAsInt) {
return Mono.just(messageRange)
.flatMapMany(range -> {
Limit limit = Limit.from(limitAsInt);
switch (messageRange.getType()) {
case ALL:
- return mailboxMessageDAO.findMessagesByMailboxId((PostgresMailboxId) mailbox.getMailboxId(), limit);
+ return mailboxMessageDAO.findMessagesByMailboxId((PostgresMailboxId) mailbox.getMailboxId(), limit, fetchType);
case FROM:
- return mailboxMessageDAO.findMessagesByMailboxIdAndAfterUID((PostgresMailboxId) mailbox.getMailboxId(), range.getUidFrom(), limit);
+ return mailboxMessageDAO.findMessagesByMailboxIdAndAfterUID((PostgresMailboxId) mailbox.getMailboxId(), range.getUidFrom(), limit, fetchType);
case ONE:
- return mailboxMessageDAO.findMessageByMailboxIdAndUid((PostgresMailboxId) mailbox.getMailboxId(), range.getUidFrom())
+ return mailboxMessageDAO.findMessageByMailboxIdAndUid((PostgresMailboxId) mailbox.getMailboxId(), range.getUidFrom(), fetchType)
.flatMapMany(Flux::just);
case RANGE:
- return mailboxMessageDAO.findMessagesByMailboxIdAndBetweenUIDs((PostgresMailboxId) mailbox.getMailboxId(), range.getUidFrom(), range.getUidTo(), limit);
+ return mailboxMessageDAO.findMessagesByMailboxIdAndBetweenUIDs((PostgresMailboxId) mailbox.getMailboxId(), range.getUidFrom(), range.getUidTo(), limit, fetchType);
default:
throw new RuntimeException("Unknown MessageRange range " + range.getType());
}
- }).flatMap(messageBuilderAndBlobId -> {
- SimpleMailboxMessage.Builder messageBuilder = messageBuilderAndBlobId.getLeft();
- String blobIdAsString = messageBuilderAndBlobId.getRight();
- switch (fetchType) {
- case METADATA:
- case ATTACHMENTS_METADATA:
- case HEADERS:
- return Mono.just(messageBuilder.build());
- case FULL:
- return retrieveFullContent(blobIdAsString)
- .map(content -> messageBuilder.content(content).build());
- default:
- return Flux.error(new RuntimeException("Unknown FetchType " + fetchType));
- }
- })
- .sort(Comparator.comparing(MailboxMessage::getUid))
- .map(message -> message);
+ });
}
private Mono<Content> retrieveFullContent(String blobIdString) {
diff --git a/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/mail/dao/PostgresMailboxMessageDAO.java b/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/mail/dao/PostgresMailboxMessageDAO.java
index cbcba2943e..48f93a912e 100644
--- a/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/mail/dao/PostgresMailboxMessageDAO.java
+++ b/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/mail/dao/PostgresMailboxMessageDAO.java
@@ -22,8 +22,8 @@ package org.apache.james.mailbox.postgres.mail.dao;
import static org.apache.james.backends.postgres.PostgresCommons.DATE_TO_LOCAL_DATE_TIME;
import static org.apache.james.backends.postgres.PostgresCommons.IN_CLAUSE_MAX_SIZE;
-import static org.apache.james.backends.postgres.PostgresCommons.TABLE_FIELD;
import static org.apache.james.backends.postgres.PostgresCommons.UNNEST_FIELD;
+import static org.apache.james.backends.postgres.PostgresCommons.tableField;
import static org.apache.james.mailbox.postgres.mail.PostgresMessageModule.MessageTable.BLOB_ID;
import static org.apache.james.mailbox.postgres.mail.PostgresMessageModule.MessageTable.INTERNAL_DATE;
import static org.apache.james.mailbox.postgres.mail.PostgresMessageModule.MessageTable.SIZE;
@@ -42,9 +42,9 @@ import static org.apache.james.mailbox.postgres.mail.PostgresMessageModule.Messa
import static org.apache.james.mailbox.postgres.mail.PostgresMessageModule.MessageToMailboxTable.THREAD_ID;
import static org.apache.james.mailbox.postgres.mail.PostgresMessageModule.MessageToMailboxTable.USER_FLAGS;
import static org.apache.james.mailbox.postgres.mail.dao.PostgresMailboxMessageDAOUtils.BOOLEAN_FLAGS_MAPPING;
+import static org.apache.james.mailbox.postgres.mail.dao.PostgresMailboxMessageDAOUtils.FETCH_TYPE_TO_FETCH_STRATEGY;
import static org.apache.james.mailbox.postgres.mail.dao.PostgresMailboxMessageDAOUtils.MESSAGE_METADATA_FIELDS_REQUIRE;
import static org.apache.james.mailbox.postgres.mail.dao.PostgresMailboxMessageDAOUtils.RECORD_TO_COMPOSED_MESSAGE_ID_WITH_META_DATA_FUNCTION;
-import static org.apache.james.mailbox.postgres.mail.dao.PostgresMailboxMessageDAOUtils.RECORD_TO_MAILBOX_MESSAGE_BUILDER_FUNCTION;
import static org.apache.james.mailbox.postgres.mail.dao.PostgresMailboxMessageDAOUtils.RECORD_TO_MESSAGE_METADATA_FUNCTION;
import static org.apache.james.mailbox.postgres.mail.dao.PostgresMailboxMessageDAOUtils.RECORD_TO_MESSAGE_UID_FUNCTION;
@@ -66,6 +66,8 @@ import org.apache.james.mailbox.model.UpdatedFlags;
import org.apache.james.mailbox.postgres.PostgresMailboxId;
import org.apache.james.mailbox.postgres.PostgresMessageId;
import org.apache.james.mailbox.postgres.mail.PostgresMessageModule.MessageTable;
+import org.apache.james.mailbox.store.mail.MessageMapper;
+import org.apache.james.mailbox.store.mail.MessageMapper.FetchType;
import org.apache.james.mailbox.store.mail.model.MailboxMessage;
import org.apache.james.mailbox.store.mail.model.impl.SimpleMailboxMessage;
import org.apache.james.util.streams.Limit;
@@ -89,7 +91,7 @@ import reactor.core.publisher.Mono;
public class PostgresMailboxMessageDAO {
private static final TableOnConditionStep<Record> MESSAGES_JOIN_MAILBOX_MESSAGES_CONDITION_STEP = TABLE_NAME.join(MessageTable.TABLE_NAME)
- .on(TABLE_FIELD.of(TABLE_NAME, MESSAGE_ID).eq(TABLE_FIELD.of(MessageTable.TABLE_NAME, MessageTable.MESSAGE_ID)));
+ .on(tableField(TABLE_NAME, MESSAGE_ID).eq(tableField(MessageTable.TABLE_NAME, MessageTable.MESSAGE_ID)));
public static final SortField<Long> DEFAULT_SORT_ORDER_BY = MESSAGE_UID.asc();
@@ -163,8 +165,9 @@ public class PostgresMailboxMessageDAO {
.where(MAILBOX_ID.eq(mailboxId.asUuid()))));
}
- public Flux<Pair<SimpleMailboxMessage.Builder, String>> findMessagesByMailboxId(PostgresMailboxId mailboxId, Limit limit) {
- Function<DSLContext, SelectSeekStep1<Record, Long>> queryWithoutLimit = dslContext -> dslContext.select()
+ public Flux<Pair<SimpleMailboxMessage.Builder, String>> findMessagesByMailboxId(PostgresMailboxId mailboxId, Limit limit, MessageMapper.FetchType fetchType) {
+ PostgresMailboxMessageFetchStrategy fetchStrategy = FETCH_TYPE_TO_FETCH_STRATEGY.apply(fetchType);
+ Function<DSLContext, SelectSeekStep1<Record, Long>> queryWithoutLimit = dslContext -> dslContext.select(fetchStrategy.fetchFields())
.from(MESSAGES_JOIN_MAILBOX_MESSAGES_CONDITION_STEP)
.where(MAILBOX_ID.eq(mailboxId.asUuid()))
.orderBy(DEFAULT_SORT_ORDER_BY);
@@ -172,11 +175,12 @@ public class PostgresMailboxMessageDAO {
return postgresExecutor.executeRows(dslContext -> limit.getLimit()
.map(limitValue -> Flux.from(queryWithoutLimit.andThen(step -> step.limit(limitValue)).apply(dslContext)))
.orElse(Flux.from(queryWithoutLimit.apply(dslContext))))
- .map(record -> Pair.of(RECORD_TO_MAILBOX_MESSAGE_BUILDER_FUNCTION.apply(record), record.get(BLOB_ID)));
+ .map(record -> Pair.of(fetchStrategy.toMessageBuilder().apply(record), record.get(BLOB_ID)));
}
- public Flux<Pair<SimpleMailboxMessage.Builder, String>> findMessagesByMailboxIdAndBetweenUIDs(PostgresMailboxId mailboxId, MessageUid from, MessageUid to, Limit limit) {
- Function<DSLContext, SelectSeekStep1<Record, Long>> queryWithoutLimit = dslContext -> dslContext.select()
+ public Flux<Pair<SimpleMailboxMessage.Builder, String>> findMessagesByMailboxIdAndBetweenUIDs(PostgresMailboxId mailboxId, MessageUid from, MessageUid to, Limit limit, FetchType fetchType) {
+ PostgresMailboxMessageFetchStrategy fetchStrategy = FETCH_TYPE_TO_FETCH_STRATEGY.apply(fetchType);
+ Function<DSLContext, SelectSeekStep1<Record, Long>> queryWithoutLimit = dslContext -> dslContext.select(fetchStrategy.fetchFields())
.from(MESSAGES_JOIN_MAILBOX_MESSAGES_CONDITION_STEP)
.where(MAILBOX_ID.eq(mailboxId.asUuid()))
.and(MESSAGE_UID.greaterOrEqual(from.asLong()))
@@ -186,19 +190,21 @@ public class PostgresMailboxMessageDAO {
return postgresExecutor.executeRows(dslContext -> limit.getLimit()
.map(limitValue -> Flux.from(queryWithoutLimit.andThen(step -> step.limit(limitValue)).apply(dslContext)))
.orElse(Flux.from(queryWithoutLimit.apply(dslContext))))
- .map(record -> Pair.of(RECORD_TO_MAILBOX_MESSAGE_BUILDER_FUNCTION.apply(record), record.get(BLOB_ID)));
+ .map(record -> Pair.of(fetchStrategy.toMessageBuilder().apply(record), record.get(BLOB_ID)));
}
- public Mono<Pair<SimpleMailboxMessage.Builder, String>> findMessageByMailboxIdAndUid(PostgresMailboxId mailboxId, MessageUid uid) {
- return postgresExecutor.executeRow(dslContext -> Mono.from(dslContext.select()
+ public Mono<Pair<SimpleMailboxMessage.Builder, String>> findMessageByMailboxIdAndUid(PostgresMailboxId mailboxId, MessageUid uid, FetchType fetchType) {
+ PostgresMailboxMessageFetchStrategy fetchStrategy = FETCH_TYPE_TO_FETCH_STRATEGY.apply(fetchType);
+ return postgresExecutor.executeRow(dslContext -> Mono.from(dslContext.select(fetchStrategy.fetchFields())
.from(MESSAGES_JOIN_MAILBOX_MESSAGES_CONDITION_STEP)
.where(MAILBOX_ID.eq(mailboxId.asUuid()))
.and(MESSAGE_UID.eq(uid.asLong()))))
- .map(record -> Pair.of(RECORD_TO_MAILBOX_MESSAGE_BUILDER_FUNCTION.apply(record), record.get(BLOB_ID)));
+ .map(record -> Pair.of(fetchStrategy.toMessageBuilder().apply(record), record.get(BLOB_ID)));
}
- public Flux<Pair<SimpleMailboxMessage.Builder, String>> findMessagesByMailboxIdAndAfterUID(PostgresMailboxId mailboxId, MessageUid from, Limit limit) {
- Function<DSLContext, SelectSeekStep1<Record, Long>> queryWithoutLimit = dslContext -> dslContext.select()
+ public Flux<Pair<SimpleMailboxMessage.Builder, String>> findMessagesByMailboxIdAndAfterUID(PostgresMailboxId mailboxId, MessageUid from, Limit limit, FetchType fetchType) {
+ PostgresMailboxMessageFetchStrategy fetchStrategy = FETCH_TYPE_TO_FETCH_STRATEGY.apply(fetchType);
+ Function<DSLContext, SelectSeekStep1<Record, Long>> queryWithoutLimit = dslContext -> dslContext.select(fetchStrategy.fetchFields())
.from(MESSAGES_JOIN_MAILBOX_MESSAGES_CONDITION_STEP)
.where(MAILBOX_ID.eq(mailboxId.asUuid()))
.and(MESSAGE_UID.greaterOrEqual(from.asLong()))
@@ -207,16 +213,18 @@ public class PostgresMailboxMessageDAO {
return postgresExecutor.executeRows(dslContext -> limit.getLimit()
.map(limitValue -> Flux.from(queryWithoutLimit.andThen(step -> step.limit(limitValue)).apply(dslContext)))
.orElse(Flux.from(queryWithoutLimit.apply(dslContext))))
- .map(record -> Pair.of(RECORD_TO_MAILBOX_MESSAGE_BUILDER_FUNCTION.apply(record), record.get(BLOB_ID)));
+ .map(record -> Pair.of(fetchStrategy.toMessageBuilder().apply(record), record.get(BLOB_ID)));
}
public Flux<SimpleMailboxMessage.Builder> findMessagesByMailboxIdAndUIDs(PostgresMailboxId mailboxId, List<MessageUid> uids) {
- Function<List<MessageUid>, Flux<SimpleMailboxMessage.Builder>> queryPublisherFunction = uidsToFetch -> postgresExecutor.executeRows(dslContext -> Flux.from(dslContext.select()
- .from(MESSAGES_JOIN_MAILBOX_MESSAGES_CONDITION_STEP)
- .where(MAILBOX_ID.eq(mailboxId.asUuid()))
- .and(MESSAGE_UID.in(uidsToFetch.stream().map(MessageUid::asLong).toArray(Long[]::new)))
- .orderBy(DEFAULT_SORT_ORDER_BY)))
- .map(RECORD_TO_MAILBOX_MESSAGE_BUILDER_FUNCTION);
+ PostgresMailboxMessageFetchStrategy fetchStrategy = PostgresMailboxMessageFetchStrategy.METADATA;
+ Function<List<MessageUid>, Flux<SimpleMailboxMessage.Builder>> queryPublisherFunction =
+ uidsToFetch -> postgresExecutor.executeRows(dslContext -> Flux.from(dslContext.select(fetchStrategy.fetchFields())
+ .from(MESSAGES_JOIN_MAILBOX_MESSAGES_CONDITION_STEP)
+ .where(MAILBOX_ID.eq(mailboxId.asUuid()))
+ .and(MESSAGE_UID.in(uidsToFetch.stream().map(MessageUid::asLong).toArray(Long[]::new)))
+ .orderBy(DEFAULT_SORT_ORDER_BY)))
+ .map(fetchStrategy.toMessageBuilder());
if (uids.size() <= IN_CLAUSE_MAX_SIZE) {
return queryPublisherFunction.apply(uids);
diff --git a/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/mail/dao/PostgresMailboxMessageDAOUtils.java b/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/mail/dao/PostgresMailboxMessageDAOUtils.java
index f69021d3bb..65404964a4 100644
--- a/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/mail/dao/PostgresMailboxMessageDAOUtils.java
+++ b/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/mail/dao/PostgresMailboxMessageDAOUtils.java
@@ -20,7 +20,6 @@
package org.apache.james.mailbox.postgres.mail.dao;
import static org.apache.james.backends.postgres.PostgresCommons.LOCAL_DATE_TIME_DATE_FUNCTION;
-import static org.apache.james.mailbox.postgres.mail.PostgresMessageModule.MessageTable.BODY_START_OCTET;
import static org.apache.james.mailbox.postgres.mail.PostgresMessageModule.MessageTable.CONTENT_DESCRIPTION;
import static org.apache.james.mailbox.postgres.mail.PostgresMessageModule.MessageTable.CONTENT_DISPOSITION_PARAMETERS;
import static org.apache.james.mailbox.postgres.mail.PostgresMessageModule.MessageTable.CONTENT_DISPOSITION_TYPE;
@@ -30,7 +29,6 @@ import static org.apache.james.mailbox.postgres.mail.PostgresMessageModule.Messa
import static org.apache.james.mailbox.postgres.mail.PostgresMessageModule.MessageTable.CONTENT_MD5;
import static org.apache.james.mailbox.postgres.mail.PostgresMessageModule.MessageTable.CONTENT_TRANSFER_ENCODING;
import static org.apache.james.mailbox.postgres.mail.PostgresMessageModule.MessageTable.CONTENT_TYPE_PARAMETERS;
-import static org.apache.james.mailbox.postgres.mail.PostgresMessageModule.MessageTable.HEADER_CONTENT;
import static org.apache.james.mailbox.postgres.mail.PostgresMessageModule.MessageTable.INTERNAL_DATE;
import static org.apache.james.mailbox.postgres.mail.PostgresMessageModule.MessageTable.SIZE;
import static org.apache.james.mailbox.postgres.mail.PostgresMessageModule.MessageToMailboxTable.IS_ANSWERED;
@@ -49,9 +47,7 @@ import static org.apache.james.mailbox.postgres.mail.PostgresMessageModule.Messa
import java.io.ByteArrayInputStream;
import java.io.InputStream;
-import java.time.LocalDateTime;
import java.util.Arrays;
-import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@@ -69,9 +65,9 @@ import org.apache.james.mailbox.model.ThreadId;
import org.apache.james.mailbox.postgres.PostgresMailboxId;
import org.apache.james.mailbox.postgres.PostgresMessageId;
import org.apache.james.mailbox.postgres.mail.PostgresMessageModule;
+import org.apache.james.mailbox.store.mail.MessageMapper;
import org.apache.james.mailbox.store.mail.model.impl.Properties;
import org.apache.james.mailbox.store.mail.model.impl.PropertyBuilder;
-import org.apache.james.mailbox.store.mail.model.impl.SimpleMailboxMessage;
import org.jooq.Field;
import org.jooq.Record;
@@ -156,8 +152,8 @@ interface PostgresMailboxMessageDAOUtils {
property.setContentTransferEncoding(record.get(CONTENT_TRANSFER_ENCODING));
property.setContentLocation(record.get(CONTENT_LOCATION));
property.setContentLanguage(Optional.ofNullable(record.get(CONTENT_LANGUAGE)).map(List::of).orElse(null));
- property.setContentDispositionParameters(record.get(CONTENT_DISPOSITION_PARAMETERS, LinkedHashMap.class));
- property.setContentTypeParameters(record.get(CONTENT_TYPE_PARAMETERS, LinkedHashMap.class));
+ property.setContentDispositionParameters(record.get(CONTENT_DISPOSITION_PARAMETERS).data());
+ property.setContentTypeParameters(record.get(CONTENT_TYPE_PARAMETERS).data());
return property.build();
};
@@ -173,19 +169,16 @@ interface PostgresMailboxMessageDAOUtils {
}
};
- Function<Record, SimpleMailboxMessage.Builder> RECORD_TO_MAILBOX_MESSAGE_BUILDER_FUNCTION = record -> SimpleMailboxMessage.builder()
- .messageId(PostgresMessageId.Factory.of(record.get(MESSAGE_ID)))
- .mailboxId(PostgresMailboxId.of(record.get(MAILBOX_ID)))
- .uid(MessageUid.of(record.get(MESSAGE_UID)))
- .modseq(ModSeq.of(record.get(MOD_SEQ)))
- .threadId(RECORD_TO_THREAD_ID_FUNCTION.apply(record))
- .internalDate(LOCAL_DATE_TIME_DATE_FUNCTION.apply(record.get(PostgresMessageModule.MessageTable.INTERNAL_DATE, LocalDateTime.class)))
- .saveDate(LOCAL_DATE_TIME_DATE_FUNCTION.apply(record.get(SAVE_DATE, LocalDateTime.class)))
- .flags(RECORD_TO_FLAGS_FUNCTION.apply(record))
- .size(record.get(PostgresMessageModule.MessageTable.SIZE))
- .bodyStartOctet(record.get(BODY_START_OCTET))
- .content(BYTE_TO_CONTENT_FUNCTION.apply(record.get(HEADER_CONTENT)))
- .properties(RECORD_TO_PROPERTIES_FUNCTION.apply(record));
-
-
+ Function<MessageMapper.FetchType, PostgresMailboxMessageFetchStrategy> FETCH_TYPE_TO_FETCH_STRATEGY = fetchType -> {
+ switch (fetchType) {
+ case METADATA:
+ case ATTACHMENTS_METADATA:
+ return PostgresMailboxMessageFetchStrategy.METADATA;
+ case HEADERS:
+ case FULL:
+ return PostgresMailboxMessageFetchStrategy.FULL;
+ default:
+ throw new RuntimeException("Unknown FetchType " + fetchType);
+ }
+ };
}
diff --git a/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/mail/dao/PostgresMailboxMessageFetchStrategy.java b/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/mail/dao/PostgresMailboxMessageFetchStrategy.java
new file mode 100644
index 0000000000..4aef7b69ef
--- /dev/null
+++ b/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/mail/dao/PostgresMailboxMessageFetchStrategy.java
@@ -0,0 +1,147 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you 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 org.apache.james.mailbox.postgres.mail.dao;
+
+import static org.apache.james.backends.postgres.PostgresCommons.LOCAL_DATE_TIME_DATE_FUNCTION;
+import static org.apache.james.backends.postgres.PostgresCommons.tableField;
+import static org.apache.james.mailbox.postgres.mail.PostgresMessageModule.MessageTable;
+import static org.apache.james.mailbox.postgres.mail.PostgresMessageModule.MessageTable.BODY_START_OCTET;
+import static org.apache.james.mailbox.postgres.mail.PostgresMessageModule.MessageTable.HEADER_CONTENT;
+import static org.apache.james.mailbox.postgres.mail.PostgresMessageModule.MessageToMailboxTable.MAILBOX_ID;
+import static org.apache.james.mailbox.postgres.mail.PostgresMessageModule.MessageToMailboxTable.MESSAGE_UID;
+import static org.apache.james.mailbox.postgres.mail.PostgresMessageModule.MessageToMailboxTable.MOD_SEQ;
+import static org.apache.james.mailbox.postgres.mail.PostgresMessageModule.MessageToMailboxTable.SAVE_DATE;
+import static org.apache.james.mailbox.postgres.mail.dao.PostgresMailboxMessageDAOUtils.BYTE_TO_CONTENT_FUNCTION;
+import static org.apache.james.mailbox.postgres.mail.dao.PostgresMailboxMessageDAOUtils.RECORD_TO_FLAGS_FUNCTION;
+import static org.apache.james.mailbox.postgres.mail.dao.PostgresMailboxMessageDAOUtils.RECORD_TO_PROPERTIES_FUNCTION;
+import static org.apache.james.mailbox.postgres.mail.dao.PostgresMailboxMessageDAOUtils.RECORD_TO_THREAD_ID_FUNCTION;
+
+import java.time.LocalDateTime;
+import java.util.function.Function;
+
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.ModSeq;
+import org.apache.james.mailbox.model.Content;
+import org.apache.james.mailbox.postgres.PostgresMailboxId;
+import org.apache.james.mailbox.postgres.PostgresMessageId;
+import org.apache.james.mailbox.postgres.mail.PostgresMessageModule;
+import org.apache.james.mailbox.postgres.mail.PostgresMessageModule.MessageToMailboxTable;
+import org.apache.james.mailbox.store.mail.model.impl.PropertyBuilder;
+import org.apache.james.mailbox.store.mail.model.impl.SimpleMailboxMessage;
+import org.jooq.Field;
+import org.jooq.Record;
+
+public interface PostgresMailboxMessageFetchStrategy {
+ PostgresMailboxMessageFetchStrategy METADATA = new MetaData();
+ PostgresMailboxMessageFetchStrategy FULL = new Full();
+
+ Field<?>[] fetchFields();
+
+ Function<Record, SimpleMailboxMessage.Builder> toMessageBuilder();
+
+ static Function<Record, SimpleMailboxMessage.Builder> toMessageBuilderMetadata() {
+ return record -> SimpleMailboxMessage.builder()
+ .messageId(PostgresMessageId.Factory.of(record.get(MessageTable.MESSAGE_ID)))
+ .mailboxId(PostgresMailboxId.of(record.get(MAILBOX_ID)))
+ .uid(MessageUid.of(record.get(MESSAGE_UID)))
+ .modseq(ModSeq.of(record.get(MOD_SEQ)))
+ .threadId(RECORD_TO_THREAD_ID_FUNCTION.apply(record))
+ .internalDate(LOCAL_DATE_TIME_DATE_FUNCTION.apply(record.get(PostgresMessageModule.MessageTable.INTERNAL_DATE, LocalDateTime.class)))
+ .saveDate(LOCAL_DATE_TIME_DATE_FUNCTION.apply(record.get(SAVE_DATE, LocalDateTime.class)))
+ .flags(RECORD_TO_FLAGS_FUNCTION.apply(record))
+ .size(record.get(PostgresMessageModule.MessageTable.SIZE))
+ .bodyStartOctet(record.get(BODY_START_OCTET));
+ }
+
+ static Field<?>[] fetchFieldsMetadata() {
+ return new Field[]{
+ tableField(MessageTable.TABLE_NAME, MessageTable.MESSAGE_ID).as(MessageTable.MESSAGE_ID),
+ tableField(MessageTable.TABLE_NAME, MessageTable.INTERNAL_DATE).as(MessageTable.INTERNAL_DATE),
+ tableField(MessageTable.TABLE_NAME, MessageTable.SIZE).as(MessageTable.SIZE),
+ MessageTable.BLOB_ID,
+ MessageTable.MIME_TYPE,
+ MessageTable.MIME_SUBTYPE,
+ MessageTable.BODY_START_OCTET,
+ MessageTable.TEXTUAL_LINE_COUNT,
+ MessageToMailboxTable.MAILBOX_ID,
+ MessageToMailboxTable.MESSAGE_UID,
+ MessageToMailboxTable.MOD_SEQ,
+ MessageToMailboxTable.THREAD_ID,
+ MessageToMailboxTable.IS_DELETED,
+ MessageToMailboxTable.IS_ANSWERED,
+ MessageToMailboxTable.IS_DRAFT,
+ MessageToMailboxTable.IS_FLAGGED,
+ MessageToMailboxTable.IS_RECENT,
+ MessageToMailboxTable.IS_SEEN,
+ MessageToMailboxTable.USER_FLAGS,
+ MessageToMailboxTable.SAVE_DATE};
+ }
+
+ class MetaData implements PostgresMailboxMessageFetchStrategy {
+ public static final Field<?>[] FETCH_FIELDS = fetchFieldsMetadata();
+ public static final Content EMPTY_CONTENT = BYTE_TO_CONTENT_FUNCTION.apply(new byte[0]);
+ public static final PropertyBuilder EMPTY_PROPERTY_BUILDER = new PropertyBuilder();
+
+
+ @Override
+ public Field<?>[] fetchFields() {
+ return FETCH_FIELDS;
+ }
+
+ @Override
+ public Function<Record, SimpleMailboxMessage.Builder> toMessageBuilder() {
+ return record -> toMessageBuilderMetadata()
+ .apply(record)
+ .content(EMPTY_CONTENT)
+ .properties(EMPTY_PROPERTY_BUILDER);
+ }
+ }
+
+ class Full implements PostgresMailboxMessageFetchStrategy {
+
+ public static final Field<?>[] FETCH_FIELDS = ArrayUtils.addAll(fetchFieldsMetadata(),
+ MessageTable.HEADER_CONTENT,
+ MessageTable.TEXTUAL_LINE_COUNT,
+ MessageTable.CONTENT_DESCRIPTION,
+ MessageTable.CONTENT_LOCATION,
+ MessageTable.CONTENT_TRANSFER_ENCODING,
+ MessageTable.CONTENT_DISPOSITION_TYPE,
+ MessageTable.CONTENT_ID,
+ MessageTable.CONTENT_MD5,
+ MessageTable.CONTENT_LANGUAGE,
+ MessageTable.CONTENT_TYPE_PARAMETERS,
+ MessageTable.CONTENT_DISPOSITION_PARAMETERS);
+
+ @Override
+ public Field<?>[] fetchFields() {
+ return FETCH_FIELDS;
+ }
+
+ @Override
+ public Function<Record, SimpleMailboxMessage.Builder> toMessageBuilder() {
+ return record -> toMessageBuilderMetadata()
+ .apply(record)
+ .content(BYTE_TO_CONTENT_FUNCTION.apply(record.get(HEADER_CONTENT)))
+ .properties(RECORD_TO_PROPERTIES_FUNCTION.apply(record));
+ }
+ }
+
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org