]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-storage: Added support for searching save date.
authorTimo Sirainen <tss@iki.fi>
Tue, 13 Apr 2010 13:52:23 +0000 (16:52 +0300)
committerTimo Sirainen <tss@iki.fi>
Tue, 13 Apr 2010 13:52:23 +0000 (16:52 +0300)
--HG--
branch : HEAD

src/lib-storage/index/index-search.c
src/lib-storage/mail-search-build.c
src/lib-storage/mail-search.c
src/lib-storage/mail-search.h

index 58749ffa6c17a6e3bc62842b53d89dda7b54323b..5c63ea55b15ccc08ac2f97b6045bf09fe1145d34 100644 (file)
@@ -215,20 +215,38 @@ static int search_arg_match_cached(struct index_search_context *ctx,
        struct tm *tm;
        uoff_t virtual_size;
        time_t date;
-       int timezone_offset;
+       int tz_offset;
+       bool have_tz_offset;
 
        switch (arg->type) {
        /* internal dates */
        case SEARCH_BEFORE:
        case SEARCH_ON:
        case SEARCH_SINCE:
-               if (mail_get_received_date(ctx->mail, &date) < 0)
-                       return -1;
+               have_tz_offset = FALSE; tz_offset = 0; date = (time_t)-1;
+               switch (arg->value.date_type) {
+               case MAIL_SEARCH_DATE_TYPE_SENT:
+                       if (mail_get_date(ctx->mail, &date, &tz_offset) < 0)
+                               return -1;
+                       have_tz_offset = TRUE;
+                       break;
+               case MAIL_SEARCH_DATE_TYPE_RECEIVED:
+                       if (mail_get_received_date(ctx->mail, &date) < 0)
+                               return -1;
+                       break;
+               case MAIL_SEARCH_DATE_TYPE_SAVED:
+                       if (mail_get_save_date(ctx->mail, &date) < 0)
+                               return -1;
+                       break;
+               }
 
                if ((arg->value.search_flags &
                     MAIL_SEARCH_ARG_FLAG_USE_TZ) == 0) {
-                       tm = localtime(&date);
-                       date += utc_offset(tm, date)*60;
+                       if (!have_tz_offset) {
+                               tm = localtime(&date);
+                               tz_offset = utc_offset(tm, date);
+                       }
+                       date += tz_offset * 60;
                }
 
                switch (arg->type) {
@@ -244,32 +262,6 @@ static int search_arg_match_cached(struct index_search_context *ctx,
                        break;
                }
 
-       /* sent dates */
-       case SEARCH_SENTBEFORE:
-       case SEARCH_SENTON:
-       case SEARCH_SENTSINCE:
-               /* NOTE: RFC-3501 specifies that timezone is ignored
-                  in searches. date is returned as UTC, so change it. */
-               if (mail_get_date(ctx->mail, &date, &timezone_offset) < 0)
-                       return -1;
-
-               if ((arg->value.search_flags &
-                    MAIL_SEARCH_ARG_FLAG_USE_TZ) == 0)
-                       date += timezone_offset * 60;
-
-               switch (arg->type) {
-               case SEARCH_SENTBEFORE:
-                       return date < arg->value.time;
-               case SEARCH_SENTON:
-                       return date >= arg->value.time &&
-                               date < arg->value.time + 3600*24;
-               case SEARCH_SENTSINCE:
-                       return date >= arg->value.time;
-               default:
-                       /* unreachable */
-                       break;
-               }
-
        /* sizes */
        case SEARCH_SMALLER:
        case SEARCH_LARGER:
@@ -331,12 +323,12 @@ static int search_sent(enum mail_search_arg_type type, time_t search_time,
        sent_time += timezone_offset * 60;
 
        switch (type) {
-       case SEARCH_SENTBEFORE:
+       case SEARCH_BEFORE:
                return sent_time < search_time;
-       case SEARCH_SENTON:
+       case SEARCH_ON:
                return sent_time >= search_time &&
                        sent_time < search_time + 3600*24;
-       case SEARCH_SENTSINCE:
+       case SEARCH_SINCE:
                return sent_time >= search_time;
        default:
                 i_unreached();
@@ -400,9 +392,12 @@ static void search_header_arg(struct mail_search_arg *arg,
 
        /* first check that the field name matches to argument. */
        switch (arg->type) {
-       case SEARCH_SENTBEFORE:
-       case SEARCH_SENTON:
-       case SEARCH_SENTSINCE:
+       case SEARCH_BEFORE:
+       case SEARCH_ON:
+       case SEARCH_SINCE:
+               if (arg->value.date_type != MAIL_SEARCH_DATE_TYPE_SENT)
+                       return;
+
                /* date is handled differently than others */
                if (strcasecmp(ctx->hdr->name, "Date") == 0) {
                        if (ctx->hdr->continues) {
@@ -491,9 +486,12 @@ static void search_header_unmatch(struct mail_search_arg *arg,
                                  void *context ATTR_UNUSED)
 {
        switch (arg->type) {
-       case SEARCH_SENTBEFORE:
-       case SEARCH_SENTON:
-       case SEARCH_SENTSINCE:
+       case SEARCH_BEFORE:
+       case SEARCH_ON:
+       case SEARCH_SINCE:
+               if (arg->value.date_type != MAIL_SEARCH_DATE_TYPE_SENT)
+                       break;
+
                if (arg->not) {
                        /* date header not found, so we match only for
                           NOT searches */
@@ -1167,9 +1165,6 @@ static bool search_arg_is_static(struct mail_search_arg *arg)
        case SEARCH_BEFORE:
        case SEARCH_ON:
        case SEARCH_SINCE:
-       case SEARCH_SENTBEFORE:
-       case SEARCH_SENTON:
-       case SEARCH_SENTSINCE:
        case SEARCH_SMALLER:
        case SEARCH_LARGER:
        case SEARCH_HEADER:
index 14bb79ae3bc9141ae89225175b2fec0803f6d0a5..086956f37aa045dab647f74ea7a4ed6739bf9259 100644 (file)
@@ -105,12 +105,13 @@ arg_new_size(struct search_build_data *data,
        return TRUE;
 }
 
-#define ARG_NEW_DATE(type) \
-       arg_new_date(data, args, next_sarg, type)
+#define ARG_NEW_DATE(type, date_type) \
+       arg_new_date(data, args, next_sarg, type, date_type)
 static bool
 arg_new_date(struct search_build_data *data,
             const struct imap_arg **args, struct mail_search_arg **next_sarg,
-            enum mail_search_arg_type type)
+            enum mail_search_arg_type type,
+            enum mail_search_date_type date_type)
 {
        struct mail_search_arg *sarg;
        const char *value;
@@ -122,6 +123,7 @@ arg_new_date(struct search_build_data *data,
                data->error = "Invalid search date parameter";
                return FALSE;
        }
+       sarg->value.date_type = date_type;
        return TRUE;
 }
 
@@ -316,7 +318,8 @@ static bool search_arg_build(struct search_build_data *data,
                        return ARG_NEW_STR(SEARCH_BODY);
                } else if (strcmp(key, "BEFORE") == 0) {
                        /* <date> */
-                       return ARG_NEW_DATE(SEARCH_BEFORE);
+                       return ARG_NEW_DATE(SEARCH_BEFORE,
+                                           MAIL_SEARCH_DATE_TYPE_RECEIVED);
                } else if (strcmp(key, "BCC") == 0) {
                        /* <string> */
                        return ARG_NEW_HEADER(SEARCH_HEADER_ADDRESS, key);
@@ -445,7 +448,8 @@ static bool search_arg_build(struct search_build_data *data,
                        return TRUE;
                } if (strcmp(key, "ON") == 0) {
                        /* <date> */
-                       return ARG_NEW_DATE(SEARCH_ON);
+                       return ARG_NEW_DATE(SEARCH_ON,
+                                           MAIL_SEARCH_DATE_TYPE_RECEIVED);
                } if (strcmp(key, "OLD") == 0) {
                        /* OLD == NOT RECENT */
                        if (!ARG_NEW_FLAGS(MAIL_RECENT))
@@ -476,16 +480,20 @@ static bool search_arg_build(struct search_build_data *data,
                        return ARG_NEW_HEADER(SEARCH_HEADER_COMPRESS_LWSP, key);
                } else if (strcmp(key, "SENTBEFORE") == 0) {
                        /* <date> */
-                       return ARG_NEW_DATE(SEARCH_SENTBEFORE);
+                       return ARG_NEW_DATE(SEARCH_BEFORE,
+                                           MAIL_SEARCH_DATE_TYPE_SENT);
                } else if (strcmp(key, "SENTON") == 0) {
                        /* <date> */
-                       return ARG_NEW_DATE(SEARCH_SENTON);
+                       return ARG_NEW_DATE(SEARCH_ON,
+                                           MAIL_SEARCH_DATE_TYPE_SENT);
                } else if (strcmp(key, "SENTSINCE") == 0) {
                        /* <date> */
-                       return ARG_NEW_DATE(SEARCH_SENTSINCE);
+                       return ARG_NEW_DATE(SEARCH_SINCE,
+                                           MAIL_SEARCH_DATE_TYPE_SENT);
                } else if (strcmp(key, "SINCE") == 0) {
                        /* <date> */
-                       return ARG_NEW_DATE(SEARCH_SINCE);
+                       return ARG_NEW_DATE(SEARCH_SINCE,
+                                           MAIL_SEARCH_DATE_TYPE_RECEIVED);
                } else if (strcmp(key, "SMALLER") == 0) {
                        /* <n> */
                        return ARG_NEW_SIZE(SEARCH_SMALLER);
@@ -589,6 +597,18 @@ static bool search_arg_build(struct search_build_data *data,
                } else if (strcmp(key, "X-MAILBOX") == 0) {
                        /* <string> */
                        return ARG_NEW_STR(SEARCH_MAILBOX);
+               } else if (strcmp(key, "X-SAVEDBEFORE") == 0) {
+                       /* <date> */
+                       return ARG_NEW_DATE(SEARCH_BEFORE,
+                                           MAIL_SEARCH_DATE_TYPE_SAVED);
+               } else if (strcmp(key, "X-SAVEDON") == 0) {
+                       /* <date> */
+                       return ARG_NEW_DATE(SEARCH_ON,
+                                           MAIL_SEARCH_DATE_TYPE_SAVED);
+               } else if (strcmp(key, "X-SAVEDSINCE") == 0) {
+                       /* <date> */
+                       return ARG_NEW_DATE(SEARCH_SINCE,
+                                           MAIL_SEARCH_DATE_TYPE_SAVED);
                }
                break;
        default:
index fff19b629ce8aacabc443dec975b197b8d442607..8b9d27deb47c49eb80f1c598e8f46062b963a89f 100644 (file)
@@ -277,10 +277,8 @@ mail_search_arg_dup_one(pool_t pool, const struct mail_search_arg *arg)
        case SEARCH_BEFORE:
        case SEARCH_ON:
        case SEARCH_SINCE:
-       case SEARCH_SENTBEFORE:
-       case SEARCH_SENTON:
-       case SEARCH_SENTSINCE:
                new_arg->value.time = arg->value.time;
+               new_arg->value.date_type = arg->value.date_type;
                break;
        case SEARCH_SMALLER:
        case SEARCH_LARGER:
@@ -461,10 +459,11 @@ search_arg_analyze(struct mail_search_arg *arg, buffer_t *headers,
                        subarg = subarg->next;
                }
                break;
-       case SEARCH_SENTBEFORE:
-       case SEARCH_SENTON:
-       case SEARCH_SENTSINCE:
-               buffer_append(headers, &date_hdr, sizeof(const char *));
+       case SEARCH_BEFORE:
+       case SEARCH_ON:
+       case SEARCH_SINCE:
+               if (arg->value.date_type == MAIL_SEARCH_DATE_TYPE_SENT)
+                       buffer_append(headers, &date_hdr, sizeof(const char *));
                break;
        case SEARCH_HEADER:
        case SEARCH_HEADER_ADDRESS:
@@ -752,10 +751,8 @@ static bool mail_search_arg_one_equals(const struct mail_search_arg *arg1,
        case SEARCH_BEFORE:
        case SEARCH_ON:
        case SEARCH_SINCE:
-       case SEARCH_SENTBEFORE:
-       case SEARCH_SENTON:
-       case SEARCH_SENTSINCE:
-               return arg1->value.time == arg2->value.time;
+               return arg1->value.time == arg2->value.time &&
+                       arg1->value.date_type == arg2->value.date_type;
 
        case SEARCH_SMALLER:
        case SEARCH_LARGER:
index fa42a691b8582a151c2fd42c67dae56a0b25b3d0..5f489e4d3b7186f271ee402d3ef8871e1895b0d3 100644 (file)
@@ -18,13 +18,10 @@ enum mail_search_arg_type {
        SEARCH_FLAGS,
        SEARCH_KEYWORDS,
 
-       /* dates */
+       /* dates (date_type required) */
        SEARCH_BEFORE,
        SEARCH_ON, /* time must point to beginning of the day */
        SEARCH_SINCE,
-       SEARCH_SENTBEFORE,
-       SEARCH_SENTON, /* time must point to beginning of the day */
-       SEARCH_SENTSINCE,
 
        /* sizes */
        SEARCH_SMALLER,
@@ -48,8 +45,14 @@ enum mail_search_arg_type {
        SEARCH_MAILBOX
 };
 
+enum mail_search_date_type {
+       MAIL_SEARCH_DATE_TYPE_SENT = 1,
+       MAIL_SEARCH_DATE_TYPE_RECEIVED,
+       MAIL_SEARCH_DATE_TYPE_SAVED
+};
+
 enum mail_search_arg_flag {
-       /* For (SENT)BEFORE/SINCE/ON searches: Don't drop timezone from
+       /* For BEFORE/SINCE/ON searches: Don't drop timezone from
           comparisons */
        MAIL_SEARCH_ARG_FLAG_USE_TZ     = 0x01,
 };
@@ -77,6 +80,7 @@ struct mail_search_arg {
                uoff_t size;
                enum mail_flags flags;
                enum mail_search_arg_flag search_flags;
+               enum mail_search_date_type date_type;
                enum mail_thread_type thread_type;
                struct mail_keywords *keywords;
                struct mail_search_modseq *modseq;