1 /* search_engines.h --  Prefiltering routines for SEARCH
2  *
3  * Copyright (c) 1994-2008 Carnegie Mellon University.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in
14  *    the documentation and/or other materials provided with the
15  *    distribution.
16  *
17  * 3. The name "Carnegie Mellon University" must not be used to
18  *    endorse or promote products derived from this software without
19  *    prior written permission. For permission or any legal
20  *    details, please contact
21  *      Carnegie Mellon University
22  *      Center for Technology Transfer and Enterprise Creation
23  *      4615 Forbes Avenue
24  *      Suite 302
25  *      Pittsburgh, PA  15213
26  *      (412) 268-7393, fax: (412) 268-7395
27  *      innovation@andrew.cmu.edu
28  *
29  * 4. Redistributions of any form whatsoever must retain the following
30  *    acknowledgment:
31  *    "This product includes software developed by Computing Services
32  *     at Carnegie Mellon University (http://www.cmu.edu/computing/)."
33  *
34  * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
35  * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
36  * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
37  * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
38  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
39  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
40  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
41  */
42 
43 #ifndef INCLUDED_SEARCH_ENGINES_H
44 #define INCLUDED_SEARCH_ENGINES_H
45 
46 #include "mailbox.h"
47 #include "message_guid.h"
48 #include "util.h"
49 #include "strarray.h"
50 
51 #include "search_part.h"
52 
53 typedef int (*search_hit_cb_t)(const char *mboxname, uint32_t uidvalidity,
54                                uint32_t uid, void *rock);
55 typedef int (*search_snippet_cb_t)(struct mailbox *, uint32_t uid,
56                                    /* SEARCH_PART_* constants */int part,
57                                    const char *snippet, void *rock);
58 
59 typedef struct search_builder search_builder_t;
60 struct search_builder {
61 /* These values are carefully chosen a) not to clash with the
62  * SEARCH_PART_* constants, and b) to reflect operator precedence */
63 #define SEARCH_OP_AND       101
64 #define SEARCH_OP_OR        102
65 #define SEARCH_OP_NOT       103
66     void (*begin_boolean)(search_builder_t *, int op);
67     void (*end_boolean)(search_builder_t *, int op);
68     void (*match)(search_builder_t *, int part, const char *str);
69     void *(*get_internalised)(search_builder_t *);
70     int (*run)(search_builder_t *, search_hit_cb_t proc, void *rock);
71 };
72 
73 typedef struct search_snippet_markup {
74     const char *hi_start;
75     const char *hi_end;
76     const char *omit;
77 } search_snippet_markup_t;
78 
79 extern search_snippet_markup_t default_snippet_markup;
80 
81 /* The functions in search_text_receiver_t get called at least once for each part of every message.
82    The invocations form a sequence:
83        begin_message(message_t)
84        receiver->begin_part(<part1>)
85        receiver->append_text(<text>)     (1 or more times)
86        receiver->end_part(<part1>)
87        ...
88        receiver->begin_part(<partN>)
89        receiver->append_text(<text>)     (1 or more times)
90        receiver->end_part(<partN>)
91        receiver->end_message()
92 
93    The parts need not arrive in any particular order, but each part
94    can only participate in one begin_part ... append_text ... end_part
95    sequence, and the sequences for different parts cannot be interleaved.
96 */
97 typedef struct search_text_receiver search_text_receiver_t;
98 struct search_text_receiver {
99     int (*begin_mailbox)(search_text_receiver_t *,
100                          struct mailbox *, int incremental);
101     uint32_t (*first_unindexed_uid)(search_text_receiver_t *);
102     int (*is_indexed)(search_text_receiver_t *, message_t *msg);
103     int (*begin_message)(search_text_receiver_t *, message_t *msg);
104     void (*begin_part)(search_text_receiver_t *, int part);
105     void (*append_text)(search_text_receiver_t *, const struct buf *);
106     void (*end_part)(search_text_receiver_t *, int part);
107     int (*end_message)(search_text_receiver_t *);
108     int (*end_mailbox)(search_text_receiver_t *,
109                        struct mailbox *);
110     int (*flush)(search_text_receiver_t *);
111 };
112 
113 #define SEARCH_FLAG_CAN_BATCH   (1<<0)
114 struct search_engine {
115     const char *name;
116     unsigned int flags;
117 #define _SEARCH_VERBOSE_MASK    (0x7)
118 #define SEARCH_VERBOSE(v)       ((v)&_SEARCH_VERBOSE_MASK)
119 #define SEARCH_MULTIPLE         (1<<3)  /* return results from
120                                          * multiple folders */
121 #define SEARCH_UNINDEXED        (1<<4)  /* return unindexed messages
122                                          * as hits (doesn't work
123                                          * with MULTIPLE) */
124 #define SEARCH_COMPACT_COPYONE  (1<<5)  /* if only one source, just copy */
125 #define SEARCH_COMPACT_FILTER   (1<<6)  /* filter resulting DB for
126                                          * expunged records */
127 #define SEARCH_COMPACT_REINDEX  (1<<7)  /* re-index all matching messages */
128     search_builder_t *(*begin_search)(struct mailbox *, int opts);
129     void (*end_search)(search_builder_t *);
130     search_text_receiver_t *(*begin_update)(int verbose);
131     int (*end_update)(search_text_receiver_t *);
132     search_text_receiver_t *(*begin_snippets)(void *internalised,
133                                               int verbose,
134                                               search_snippet_markup_t *markup,
135                                               search_snippet_cb_t,
136                                               void *rock);
137     int (*end_snippets)(search_text_receiver_t *);
138     char *(*describe_internalised)(void *);
139     void (*free_internalised)(void *);
140     int (*start_daemon)(int verbose);
141     int (*stop_daemon)(int verbose);
142     int (*list_files)(const char *userid, strarray_t *);
143     int (*compact)(const char *userid, const char *tempdir,
144                    const strarray_t *srctiers, const char *desttier,
145                    int flags);
146     int (*deluser)(const char *userid);
147 };
148 
149 /*
150  * Search for messages which could match the query built with the
151  * search_builder_t.  Calls 'proc' once for each hit found.  If 'single'
152  * is true, only hits in 'mailbox' are reported; otherwise hits in any
153  * folder in the same conversation scope (i.e. the same user) as
154  * reported.
155  */
156 extern search_builder_t *search_begin_search(struct mailbox *, int opts);
157 extern void search_end_search(search_builder_t *);
158 
159 #define SEARCH_UPDATE_INCREMENTAL (1<<0)
160 #define SEARCH_UPDATE_NONBLOCKING (1<<1)
161 #define SEARCH_UPDATE_BATCH (1<<2)
162 search_text_receiver_t *search_begin_update(int verbose);
163 int search_update_mailbox(search_text_receiver_t *rx,
164                           struct mailbox *mailbox,
165                           int flags);
166 int search_end_update(search_text_receiver_t *rx);
167 search_text_receiver_t *search_begin_snippets(void *internalised,
168                                               int verbose,
169                                               search_snippet_markup_t *markup,
170                                               search_snippet_cb_t proc,
171                                               void *rock);
172 int search_end_snippets(search_text_receiver_t *rx);
173 /* Returns a new string which describes the internalised query, and must
174  * be free()d by the caller.  Only useful for whitebox testing.  */
175 char *search_describe_internalised(void *internalised);
176 void search_free_internalised(void *internalised);
177 int search_start_daemon(int verbose);
178 int search_stop_daemon(int verbose);
179 int search_list_files(const char *userid, strarray_t *);
180 int search_compact(const char *userid, const char *tempdir,
181                    const strarray_t *srctiers, const char *desttier, int verbose);
182 int search_deluser(const char *userid);
183 
184 
185 /* for debugging */
186 extern const char *search_op_as_string(int op);
187 
188 #endif
189