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:21 UTC

[james-project] 04/04: JAMES-3440 RFC-8621 support for emailQueryView before + inMailbox sorted by receivedAt

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 e4f0fb8a2d6f28e909b2965fceac84f0915b76aa
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Tue Apr 18 14:14:10 2023 +0700

    JAMES-3440 RFC-8621 support for emailQueryView before + inMailbox sorted by receivedAt
---
 .../org/apache/james/jmap/mail/EmailQuery.scala    | 22 ++++++++++++++++++----
 .../james/jmap/method/EmailQueryMethod.scala       | 16 ++++++++++++++++
 2 files changed, 34 insertions(+), 4 deletions(-)

diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/EmailQuery.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/EmailQuery.scala
index 2137f20059..751b6b8d8c 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/EmailQuery.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/EmailQuery.scala
@@ -41,6 +41,8 @@ sealed trait FilterQuery {
 
   def inMailboxAndAfterFilterOnly: Boolean
 
+  def inMailboxAndBeforeFilterOnly: Boolean
+
   def countNestedMailboxFilter: Int
 
   def countMailboxFilter: Int
@@ -57,6 +59,8 @@ case class FilterOperator(operator: Operator,
 
   override val inMailboxAndAfterFilterOnly: Boolean = false
 
+  override val inMailboxAndBeforeFilterOnly: Boolean = false
+
   override def countNestedMailboxFilter: Int = conditions.map(_.countNestedMailboxFilter).sum
 
   override def countMailboxFilter: Int = conditions.map {
@@ -102,9 +106,8 @@ case class FilterCondition(inMailbox: Option[MailboxId],
                            subject: Option[Subject],
                            header: Option[Header],
                            body: Option[Body]) extends FilterQuery {
-  private val noOtherFiltersThanInMailboxAndAfter: Boolean = inMailboxOtherThan.isEmpty &&
-    before.isEmpty &&
-    hasKeyword.isEmpty &&
+
+  private val emailQueryViewInvalidCriteria: Boolean = hasKeyword.isEmpty &&
     notKeyword.isEmpty &&
     minSize.isEmpty &&
     maxSize.isEmpty &&
@@ -121,15 +124,26 @@ case class FilterCondition(inMailbox: Option[MailboxId],
     header.isEmpty &&
     body.isEmpty
 
+  private val noOtherFiltersThanInMailboxAndAfter: Boolean = inMailboxOtherThan.isEmpty &&
+    before.isEmpty &&
+    emailQueryViewInvalidCriteria
+
+  private val noOtherFiltersThanInMailboxAndBefore: Boolean = inMailboxOtherThan.isEmpty &&
+    after.isEmpty &&
+    emailQueryViewInvalidCriteria
+
   override val inMailboxFilterOnly: Boolean = inMailbox.nonEmpty &&
     after.isEmpty &&
     noOtherFiltersThanInMailboxAndAfter
 
-
   override val inMailboxAndAfterFilterOnly: Boolean = inMailbox.nonEmpty &&
     after.nonEmpty &&
     noOtherFiltersThanInMailboxAndAfter
 
+  override val inMailboxAndBeforeFilterOnly: Boolean = inMailbox.nonEmpty &&
+    before.nonEmpty &&
+    noOtherFiltersThanInMailboxAndBefore
+
   override def countNestedMailboxFilter: Int = countMailboxFilter
 
   override def countMailboxFilter: Int = Booleans.countTrue(inMailbox.isDefined, inMailboxOtherThan.isDefined)
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailQueryMethod.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailQueryMethod.scala
index e643925670..f1902846ba 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailQueryMethod.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailQueryMethod.scala
@@ -101,6 +101,8 @@ class EmailQueryMethod @Inject() (serializer: EmailQuerySerializer,
         queryViewForListingSortedByReceivedAt(session, position, limit, request, searchQuery.getNamespace)
       case request: EmailQueryRequest if matchesInMailboxAfterSortedByReceivedAt(request) =>
         queryViewForContentAfterSortedByReceivedAt(session, position, limit, request, searchQuery.getNamespace)
+      case request: EmailQueryRequest if matchesInMailboxBeforeSortedByReceivedAt(request) =>
+        queryViewForContentBeforeSortedByReceivedAt(session, position, limit, request, searchQuery.getNamespace)
       case _ => executeQueryAgainstSearchIndex(session, searchQuery, position, limit)
     }
 
@@ -126,6 +128,15 @@ class EmailQueryMethod @Inject() (serializer: EmailQuerySerializer,
     fromQueryViewEntries(mailboxId, queryViewEntries, mailboxSession, position, limitToUse, namespace)
   }
 
+  private def queryViewForContentBeforeSortedByReceivedAt(mailboxSession: MailboxSession, position: Position, limitToUse: Limit, request: EmailQueryRequest, namespace: Namespace): SMono[Seq[MessageId]] = {
+    val condition: FilterCondition = request.filter.get.asInstanceOf[FilterCondition]
+    val mailboxId: MailboxId = condition.inMailbox.get
+    val before: ZonedDateTime = condition.before.get.asUTC
+    val queryViewEntries: SFlux[MessageId] = SFlux.fromPublisher(emailQueryView.listMailboxContentBeforeSortedByReceivedAt(mailboxId, before, JavaLimit.from(limitToUse.value + position.value)))
+
+    fromQueryViewEntries(mailboxId, queryViewEntries, mailboxSession, position, limitToUse, namespace)
+  }
+
   private def queryViewForListingSortedBySentAt(mailboxSession: MailboxSession, position: Position, limitToUse: Limit, request: EmailQueryRequest, namespace: Namespace): SMono[Seq[MessageId]] = {
     val mailboxId: MailboxId = request.filter.get.asInstanceOf[FilterCondition].inMailbox.get
     val queryViewEntries: SFlux[MessageId] = SFlux.fromPublisher(emailQueryView.listMailboxContentSortedBySentAt(mailboxId, JavaLimit.from(limitToUse.value + position.value)))
@@ -173,6 +184,11 @@ class EmailQueryMethod @Inject() (serializer: EmailQuerySerializer,
       request.filter.exists(_.inMailboxAndAfterFilterOnly) &&
       request.sort.contains(Set(Comparator.RECEIVED_AT_DESC))
 
+  private def matchesInMailboxBeforeSortedByReceivedAt(request: EmailQueryRequest): Boolean =
+    configuration.isEmailQueryViewEnabled &&
+      request.filter.exists(_.inMailboxAndBeforeFilterOnly) &&
+      request.sort.contains(Set(Comparator.RECEIVED_AT_DESC))
+
   private def toResponse(request: EmailQueryRequest, position: Position, limitToUse: Limit, ids: Seq[MessageId]): EmailQueryResponse =
     EmailQueryResponse(accountId = request.accountId,
       queryState = QueryState.forIds(ids),


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