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/04/19 09:57:20 UTC

[james-project] 03/04: JAMES-3440 EmailQueryView support before sorted by received at

This is an automated email from the ASF dual-hosted git repository.

rcordier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git

commit 78e9e5a519c93f7ae7b25e2bec7c8dee6c112b9d
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Tue Apr 18 14:00:04 2023 +0700

    JAMES-3440 EmailQueryView support before sorted by received at
---
 .../projections/CassandraEmailQueryView.java       | 21 ++++++++++++++++++++
 .../james/jmap/api/projections/EmailQueryView.java | 23 ++++++++++++++++++++++
 .../memory/projections/MemoryEmailQueryView.java   |  9 +++++++++
 .../api/projections/EmailQueryViewContract.java    | 10 ++++++++++
 4 files changed, 63 insertions(+)

diff --git a/server/data/data-jmap-cassandra/src/main/java/org/apache/james/jmap/cassandra/projections/CassandraEmailQueryView.java b/server/data/data-jmap-cassandra/src/main/java/org/apache/james/jmap/cassandra/projections/CassandraEmailQueryView.java
index c409361cd2..903270c12c 100644
--- a/server/data/data-jmap-cassandra/src/main/java/org/apache/james/jmap/cassandra/projections/CassandraEmailQueryView.java
+++ b/server/data/data-jmap-cassandra/src/main/java/org/apache/james/jmap/cassandra/projections/CassandraEmailQueryView.java
@@ -65,6 +65,7 @@ public class CassandraEmailQueryView implements EmailQueryView {
     private final PreparedStatement listMailboxContentByReceivedAt;
     private final PreparedStatement listMailboxContentSinceSentAt;
     private final PreparedStatement listMailboxContentSinceReceivedAt;
+    private final PreparedStatement listMailboxContentBeforeReceivedAt;
     private final PreparedStatement insertInLookupTable;
     private final PreparedStatement insertReceivedAt;
     private final PreparedStatement insertSentAt;
@@ -109,6 +110,13 @@ public class CassandraEmailQueryView implements EmailQueryView {
             .orderBy(RECEIVED_AT, DESC)
             .build());
 
+        listMailboxContentBeforeReceivedAt = session.prepare(selectFrom(TABLE_NAME_RECEIVED_AT)
+            .columns(MESSAGE_ID, SENT_AT)
+            .whereColumn(MAILBOX_ID).isEqualTo(bindMarker(MAILBOX_ID))
+            .whereColumn(RECEIVED_AT).isLessThanOrEqualTo(bindMarker(RECEIVED_AT))
+            .orderBy(RECEIVED_AT, DESC)
+            .build());
+
         insertInLookupTable = session.prepare(insertInto(DATE_LOOKUP_TABLE)
             .value(MAILBOX_ID, bindMarker(MAILBOX_ID))
             .value(MESSAGE_ID, bindMarker(MESSAGE_ID))
@@ -220,6 +228,19 @@ public class CassandraEmailQueryView implements EmailQueryView {
             .take(limit.getLimit().get());
     }
 
+    @Override
+    public Flux<MessageId> listMailboxContentBeforeSortedByReceivedAt(MailboxId mailboxId, ZonedDateTime since, Limit limit) {
+        Preconditions.checkArgument(!limit.isUnlimited(), "Limit should be defined");
+
+        CassandraId cassandraId = (CassandraId) mailboxId;
+
+        return executor.executeRows(listMailboxContentBeforeReceivedAt.bind()
+            .set(MAILBOX_ID, cassandraId.asUuid(), TypeCodecs.UUID)
+            .setInstant(RECEIVED_AT, since.toInstant()))
+            .<MessageId>map(row -> CassandraMessageId.Factory.of(row.get(0, TypeCodecs.UUID)))
+            .take(limit.getLimit().get());
+    }
+
     @Override
     public Flux<MessageId> listMailboxContentSinceSentAt(MailboxId mailboxId, ZonedDateTime since, Limit limit) {
         Preconditions.checkArgument(!limit.isUnlimited(), "Limit should be defined");
diff --git a/server/data/data-jmap/src/main/java/org/apache/james/jmap/api/projections/EmailQueryView.java b/server/data/data-jmap/src/main/java/org/apache/james/jmap/api/projections/EmailQueryView.java
index 41247aca8f..11afa60599 100644
--- a/server/data/data-jmap/src/main/java/org/apache/james/jmap/api/projections/EmailQueryView.java
+++ b/server/data/data-jmap/src/main/java/org/apache/james/jmap/api/projections/EmailQueryView.java
@@ -174,6 +174,29 @@ public interface EmailQueryView {
      */
     Flux<MessageId> listMailboxContentSinceAfterSortedByReceivedAt(MailboxId mailboxId, ZonedDateTime since, Limit limit);
 
+    /**
+     *  Sample JMAP requests:
+     *
+     *      - RFC-8621:
+     *
+     *    ["Email/query",
+     *     {
+     *       "accountId": "29883977c13473ae7cb7678ef767cbfbaffc8a44a6e463d971d23a65c1dc4af6",
+     *       "filter: {
+     *           "inMailbox":"abcd",
+     *           "before":"aDate"
+     *       }
+     *       "sort": [{
+     *         "property":"receivedAt",
+     *         "isAscending": false
+     *       }]
+     *     },
+     *     "c1"]
+     *
+     * @return messageIds of the messages in this mailbox, since being "after". Sorted by receivedAt.
+     */
+    Flux<MessageId> listMailboxContentBeforeSortedByReceivedAt(MailboxId mailboxId, ZonedDateTime since, Limit limit);
+
     /**
      *  Sample JMAP requests:
      *
diff --git a/server/data/data-jmap/src/main/java/org/apache/james/jmap/memory/projections/MemoryEmailQueryView.java b/server/data/data-jmap/src/main/java/org/apache/james/jmap/memory/projections/MemoryEmailQueryView.java
index ee1648fbc2..d0f1767a2c 100644
--- a/server/data/data-jmap/src/main/java/org/apache/james/jmap/memory/projections/MemoryEmailQueryView.java
+++ b/server/data/data-jmap/src/main/java/org/apache/james/jmap/memory/projections/MemoryEmailQueryView.java
@@ -94,6 +94,15 @@ public class MemoryEmailQueryView implements EmailQueryView {
             .take(limit.getLimit().get());
     }
 
+    @Override
+    public Flux<MessageId> listMailboxContentBeforeSortedByReceivedAt(MailboxId mailboxId, ZonedDateTime before, Limit limit) {
+        return Flux.fromIterable(entries.row(mailboxId).values())
+            .filter(e -> e.getReceivedAt().isBefore(before) || e.getReceivedAt().isEqual(before))
+            .sort(Comparator.comparing(Entry::getReceivedAt).reversed())
+            .map(Entry::getMessageId)
+            .take(limit.getLimit().get());
+    }
+
     @Override
     public Mono<Void> delete(MailboxId mailboxId, MessageId messageId) {
         return Mono.fromRunnable(() -> entries.remove(mailboxId, messageId));
diff --git a/server/data/data-jmap/src/test/java/org/apache/james/jmap/api/projections/EmailQueryViewContract.java b/server/data/data-jmap/src/test/java/org/apache/james/jmap/api/projections/EmailQueryViewContract.java
index 4570da538b..4e1b3abb4e 100644
--- a/server/data/data-jmap/src/test/java/org/apache/james/jmap/api/projections/EmailQueryViewContract.java
+++ b/server/data/data-jmap/src/test/java/org/apache/james/jmap/api/projections/EmailQueryViewContract.java
@@ -247,6 +247,16 @@ public interface EmailQueryViewContract {
             .containsExactly(messageId3(), messageId1());
     }
 
+    @Test
+    default void listMailboxContentBeforeSortedByReceivedAtShouldBeSortedByReceivedAt() {
+        testee().save(mailboxId1(), DATE_1, DATE_4, messageId1()).block();
+        testee().save(mailboxId1(), DATE_2, DATE_3, messageId2()).block();
+        testee().save(mailboxId1(), DATE_5, DATE_6, messageId3()).block();
+
+        assertThat(testee().listMailboxContentBeforeSortedByReceivedAt(mailboxId1(), DATE_4, Limit.limit(12)).collectList().block())
+            .containsExactly(messageId1(), messageId2());
+    }
+
     @Test
     default void clearShouldNotFailWhenEmpty() {
         assertThatCode(() -> testee().delete(mailboxId1()).block()).doesNotThrowAnyException();


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org